summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/Android.bp4
-rw-r--r--apct-tests/perftests/core/AndroidManifest.xml22
-rw-r--r--apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml21
-rw-r--r--apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java75
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java52
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java43
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java103
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java292
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java164
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java112
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java510
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java182
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java313
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java73
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java43
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java78
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java111
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java129
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java85
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java114
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java70
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java49
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java86
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java111
-rw-r--r--apct-tests/perftests/core/src/android/view/HandwritingImeService.java32
-rw-r--r--apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java21
-rw-r--r--apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java21
-rw-r--r--apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js113
-rw-r--r--apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java142
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java28
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java408
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java4
-rw-r--r--config/boot-image-profile-extra.txt21
-rw-r--r--core/api/current.txt26
-rw-r--r--core/api/system-current.txt4
-rw-r--r--core/api/test-current.txt4
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java3
-rw-r--r--core/java/android/app/Activity.java17
-rw-r--r--core/java/android/app/ActivityOptions.java1
-rw-r--r--core/java/android/app/ActivityTransitionState.java10
-rw-r--r--core/java/android/app/AppOpsManager.java3
-rw-r--r--core/java/android/app/ApplicationPackageManager.java9
-rw-r--r--core/java/android/app/INotificationManager.aidl1
-rw-r--r--core/java/android/app/NotificationChannel.java6
-rw-r--r--core/java/android/app/SystemServiceRegistry.java1
-rw-r--r--core/java/android/app/TaskInfo.java9
-rw-r--r--core/java/android/app/UiAutomation.java3
-rw-r--r--core/java/android/app/UiAutomationConnection.java1
-rw-r--r--core/java/android/app/search/SearchAction.java4
-rw-r--r--core/java/android/app/search/SearchTarget.java2
-rw-r--r--core/java/android/app/timedetector/ITimeDetectorService.aidl4
-rw-r--r--core/java/android/app/timedetector/NetworkTimeSuggestion.java124
-rw-r--r--core/java/android/app/timedetector/TimeDetector.java16
-rw-r--r--core/java/android/app/timedetector/TimeDetectorImpl.java24
-rw-r--r--core/java/android/app/timedetector/TimeSuggestionHelper.java3
-rw-r--r--core/java/android/app/trust/ITrustManager.aidl1
-rw-r--r--core/java/android/app/usage/IUsageStatsManager.aidl4
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java4
-rw-r--r--core/java/android/content/integrity/AppInstallMetadata.java15
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageManager.java12
-rw-r--r--core/java/android/hardware/biometrics/IAuthService.aidl3
-rw-r--r--core/java/android/hardware/biometrics/IBiometricService.aidl15
-rw-r--r--core/java/android/hardware/biometrics/ITestSession.aidl8
-rw-r--r--core/java/android/hardware/display/IColorDisplayManager.aidl3
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl29
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl32
-rw-r--r--core/java/android/hardware/iris/IIrisService.aidl1
-rw-r--r--core/java/android/hardware/location/IContextHubService.aidl16
-rw-r--r--core/java/android/hardware/radio/ProgramList.java15
-rw-r--r--core/java/android/net/SntpClient.java22
-rw-r--r--core/java/android/os/PowerManager.java20
-rw-r--r--core/java/android/os/storage/IStorageManager.aidl26
-rw-r--r--core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS3
-rw-r--r--core/java/android/permission/IPermissionManager.aidl1
-rw-r--r--core/java/android/permission/OWNERS2
-rw-r--r--core/java/android/provider/Settings.java22
-rw-r--r--core/java/android/text/TextLine.java200
-rw-r--r--core/java/android/util/NtpTrustedTime.java479
-rw-r--r--core/java/android/view/InsetsFrameProvider.java139
-rw-r--r--core/java/android/view/View.java36
-rw-r--r--core/java/android/view/ViewRootImpl.java15
-rw-r--r--core/java/android/view/ViewTreeObserver.java6
-rw-r--r--core/java/android/view/WindowLayout.java4
-rw-r--r--core/java/android/view/WindowManager.java27
-rw-r--r--core/java/android/view/WindowManagerGlobal.java5
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java26
-rw-r--r--core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl (renamed from core/java/android/app/timedetector/GnssTimeSuggestion.aidl)10
-rw-r--r--core/java/android/view/accessibility/AccessibilityWindowAttributes.java110
-rw-r--r--core/java/android/view/accessibility/IAccessibilityManager.aidl3
-rw-r--r--core/java/android/view/inputmethod/IInputMethodManagerInvoker.java63
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java145
-rw-r--r--core/java/android/widget/TextView.java15
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl13
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java5
-rw-r--r--core/java/com/android/internal/app/ResolverListController.java5
-rw-r--r--core/java/com/android/internal/graphics/fonts/IFontManager.aidl1
-rw-r--r--core/java/com/android/internal/jank/FrameTracker.java303
-rw-r--r--core/java/com/android/internal/jank/InteractionJankMonitor.java236
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl33
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java15
-rw-r--r--core/jni/com_android_internal_net_NetworkUtilsInternal.cpp8
-rw-r--r--core/proto/android/server/powermanagerservice.proto1
-rw-r--r--core/proto/android/server/windowmanagerservice.proto2
-rw-r--r--core/res/AndroidManifest.xml5
-rw-r--r--core/res/res/values-af/strings.xml4
-rw-r--r--core/res/res/values-am/strings.xml6
-rw-r--r--core/res/res/values-ar/strings.xml10
-rw-r--r--core/res/res/values-as/strings.xml10
-rw-r--r--core/res/res/values-az/strings.xml10
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml4
-rw-r--r--core/res/res/values-be/strings.xml10
-rw-r--r--core/res/res/values-bg/strings.xml10
-rw-r--r--core/res/res/values-bn/strings.xml4
-rw-r--r--core/res/res/values-bs/strings.xml8
-rw-r--r--core/res/res/values-ca/strings.xml4
-rw-r--r--core/res/res/values-cs/strings.xml4
-rw-r--r--core/res/res/values-da/strings.xml4
-rw-r--r--core/res/res/values-de/strings.xml12
-rw-r--r--core/res/res/values-el/strings.xml4
-rw-r--r--core/res/res/values-en-rAU/strings.xml4
-rw-r--r--core/res/res/values-en-rCA/strings.xml4
-rw-r--r--core/res/res/values-en-rGB/strings.xml4
-rw-r--r--core/res/res/values-en-rIN/strings.xml4
-rw-r--r--core/res/res/values-en-rXC/strings.xml3
-rw-r--r--core/res/res/values-es-rUS/strings.xml4
-rw-r--r--core/res/res/values-es/strings.xml10
-rw-r--r--core/res/res/values-et/strings.xml10
-rw-r--r--core/res/res/values-eu/strings.xml4
-rw-r--r--core/res/res/values-fa/strings.xml16
-rw-r--r--core/res/res/values-fi/strings.xml10
-rw-r--r--core/res/res/values-fr-rCA/strings.xml10
-rw-r--r--core/res/res/values-fr/strings.xml12
-rw-r--r--core/res/res/values-gl/strings.xml10
-rw-r--r--core/res/res/values-gu/strings.xml4
-rw-r--r--core/res/res/values-hi/strings.xml16
-rw-r--r--core/res/res/values-hr/strings.xml4
-rw-r--r--core/res/res/values-hu/strings.xml4
-rw-r--r--core/res/res/values-hy/strings.xml10
-rw-r--r--core/res/res/values-in/strings.xml12
-rw-r--r--core/res/res/values-is/strings.xml10
-rw-r--r--core/res/res/values-it/strings.xml10
-rw-r--r--core/res/res/values-iw/strings.xml4
-rw-r--r--core/res/res/values-ja/strings.xml6
-rw-r--r--core/res/res/values-ka/strings.xml4
-rw-r--r--core/res/res/values-kk/strings.xml18
-rw-r--r--core/res/res/values-km/strings.xml4
-rw-r--r--core/res/res/values-kn/strings.xml4
-rw-r--r--core/res/res/values-ko/strings.xml10
-rw-r--r--core/res/res/values-ky/strings.xml6
-rw-r--r--core/res/res/values-lo/strings.xml10
-rw-r--r--core/res/res/values-lt/strings.xml4
-rw-r--r--core/res/res/values-lv/strings.xml10
-rw-r--r--core/res/res/values-mk/strings.xml4
-rw-r--r--core/res/res/values-ml/strings.xml8
-rw-r--r--core/res/res/values-mn/strings.xml10
-rw-r--r--core/res/res/values-mr/strings.xml10
-rw-r--r--core/res/res/values-ms/strings.xml4
-rw-r--r--core/res/res/values-my/strings.xml4
-rw-r--r--core/res/res/values-nb/strings.xml34
-rw-r--r--core/res/res/values-ne/strings.xml10
-rw-r--r--core/res/res/values-nl/strings.xml4
-rw-r--r--core/res/res/values-or/strings.xml26
-rw-r--r--core/res/res/values-pa/strings.xml6
-rw-r--r--core/res/res/values-pl/strings.xml4
-rw-r--r--core/res/res/values-pt-rBR/strings.xml4
-rw-r--r--core/res/res/values-pt-rPT/strings.xml4
-rw-r--r--core/res/res/values-pt/strings.xml4
-rw-r--r--core/res/res/values-ro/strings.xml4
-rw-r--r--core/res/res/values-ru/strings.xml10
-rw-r--r--core/res/res/values-si/strings.xml4
-rw-r--r--core/res/res/values-sk/strings.xml6
-rw-r--r--core/res/res/values-sl/strings.xml10
-rw-r--r--core/res/res/values-sq/strings.xml4
-rw-r--r--core/res/res/values-sr/strings.xml4
-rw-r--r--core/res/res/values-sv/strings.xml12
-rw-r--r--core/res/res/values-sw/strings.xml10
-rw-r--r--core/res/res/values-ta/strings.xml10
-rw-r--r--core/res/res/values-te/strings.xml18
-rw-r--r--core/res/res/values-th/strings.xml10
-rw-r--r--core/res/res/values-tl/strings.xml10
-rw-r--r--core/res/res/values-tr/strings.xml10
-rw-r--r--core/res/res/values-uk/strings.xml10
-rw-r--r--core/res/res/values-ur/strings.xml10
-rw-r--r--core/res/res/values-uz/strings.xml4
-rw-r--r--core/res/res/values-vi/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml4
-rw-r--r--core/res/res/values-zh-rHK/strings.xml4
-rw-r--r--core/res/res/values-zh-rTW/strings.xml4
-rw-r--r--core/res/res/values-zu/strings.xml4
-rw-r--r--core/res/res/values/config.xml6
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/text/TextLineTest.java268
-rw-r--r--core/tests/coretests/src/android/util/NtpTrustedTimeTest.java307
-rw-r--r--core/tests/coretests/src/android/util/OWNERS2
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java69
-rw-r--r--core/tests/coretests/src/android/widget/TextViewTest.java17
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java39
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java15
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--graphics/java/android/graphics/Paint.java125
-rw-r--r--graphics/java/android/graphics/Typeface.java29
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rXC/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml3
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java59
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md73
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md50
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md69
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md58
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md55
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md49
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md83
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java138
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java20
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt181
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt22
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt24
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt33
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt61
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt86
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt16
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt69
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt37
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt28
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt74
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt42
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt82
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt7
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt13
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt28
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt5
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt18
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt5
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt17
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt37
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt54
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt87
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt)35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt85
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt84
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt88
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt23
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java129
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java11
-rw-r--r--libs/hwui/jni/Paint.cpp248
-rw-r--r--location/java/android/location/ILocationManager.aidl5
-rw-r--r--location/java/android/location/SatellitePvt.java6
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl50
-rw-r--r--media/java/android/media/MediaCodec.java8
-rw-r--r--media/java/android/media/MediaRouter2.java21
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java41
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java4
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java4
-rw-r--r--packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java19
-rw-r--r--packages/CompanionDeviceManager/res/values-af/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ar/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-as/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-az/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-bs/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-da/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-de/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-el/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rAU/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rCA/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rGB/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rIN/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rXC/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-eu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-gu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hi/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hr/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-iw/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml8
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml8
-rw-r--r--packages/CompanionDeviceManager/res/values-kn/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ml/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-mn/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ms/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-my/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-nl/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-pt/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-ro/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-si/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-sk/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sr/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ta/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-te/strings.xml8
-rw-r--r--packages/CompanionDeviceManager/res/values-th/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-tl/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-ur/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-vi/strings.xml4
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/CompanionDeviceManager/res/values-zu/strings.xml6
-rw-r--r--packages/DynamicSystemInstallationService/res/values-or/strings.xml2
-rw-r--r--packages/InputDevices/res/values-zu/strings.xml64
-rw-r--r--packages/PackageInstaller/res/values-eu/strings.xml4
-rw-r--r--packages/PackageInstaller/res/values-or/strings.xml2
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java2
-rw-r--r--packages/PrintSpooler/res/values-or/strings.xml2
-rw-r--r--packages/SettingsLib/Android.bp23
-rw-r--r--packages/SettingsLib/common.mk14
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-te/arrays.xml4
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java46
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java8
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java2
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java16
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java23
-rw-r--r--packages/Shell/AndroidManifest.xml3
-rw-r--r--packages/Shell/res/values-pa/strings.xml2
-rw-r--r--packages/SimAppDialog/res/values-fa/strings.xml2
-rw-r--r--packages/SystemUI/TEST_MAPPING4
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt16
-rw-r--r--packages/SystemUI/checks/Android.bp1
-rw-r--r--packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt31
-rw-r--r--packages/SystemUI/docs/user-file-manager.md13
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt14
-rw-r--r--packages/SystemUI/proguard.flags6
-rw-r--r--packages/SystemUI/res/drawable/dream_overlay_camera_off.xml29
-rw-r--r--packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml33
-rw-r--r--packages/SystemUI/res/drawable/dream_overlay_mic_off.xml29
-rw-r--r--packages/SystemUI/res/drawable/qs_airplane_icon_off.xml53
-rw-r--r--packages/SystemUI/res/drawable/qs_airplane_icon_on.xml98
-rw-r--r--packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml67
-rw-r--r--packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml636
-rw-r--r--packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml110
-rw-r--r--packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml93
-rw-r--r--packages/SystemUI/res/drawable/qs_dnd_icon_off.xml56
-rw-r--r--packages/SystemUI/res/drawable/qs_dnd_icon_on.xml73
-rw-r--r--packages/SystemUI/res/drawable/qs_location_icon_off.xml166
-rw-r--r--packages/SystemUI/res/drawable/qs_location_icon_on.xml155
-rw-r--r--packages/SystemUI/res/drawable/qs_mic_access_off.xml212
-rw-r--r--packages/SystemUI/res/drawable/qs_mic_access_on.xml212
-rw-r--r--packages/SystemUI/res/drawable/screenshot_edit_background.xml2
-rw-r--r--packages/SystemUI/res/layout/auth_container_view.xml1
-rw-r--r--packages/SystemUI/res/layout/brightness_mirror_container.xml1
-rw-r--r--packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml29
-rw-r--r--packages/SystemUI/res/layout/media_output_dialog.xml36
-rw-r--r--packages/SystemUI/res/layout/media_session_view.xml3
-rw-r--r--packages/SystemUI/res/layout/user_switcher_fullscreen.xml4
-rw-r--r--packages/SystemUI/res/values-af/strings.xml8
-rw-r--r--packages/SystemUI/res/values-am/strings.xml10
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml8
-rw-r--r--packages/SystemUI/res/values-as/strings.xml8
-rw-r--r--packages/SystemUI/res/values-az/strings.xml8
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-be/strings.xml10
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml12
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml8
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml10
-rw-r--r--packages/SystemUI/res/values-da/strings.xml10
-rw-r--r--packages/SystemUI/res/values-de/strings.xml8
-rw-r--r--packages/SystemUI/res/values-el/strings.xml10
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml7
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml7
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml8
-rw-r--r--packages/SystemUI/res/values-es/strings.xml10
-rw-r--r--packages/SystemUI/res/values-es/tiles_states_strings.xml4
-rw-r--r--packages/SystemUI/res/values-et/strings.xml8
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml10
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml8
-rw-r--r--packages/SystemUI/res/values-is/strings.xml8
-rw-r--r--packages/SystemUI/res/values-it/strings.xml11
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml10
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-km/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml10
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml16
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml8
-rw-r--r--packages/SystemUI/res/values-my/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml18
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml10
-rw-r--r--packages/SystemUI/res/values-or/strings.xml24
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml10
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml10
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml10
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml10
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml10
-rw-r--r--packages/SystemUI/res/values-si/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml10
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml8
-rw-r--r--packages/SystemUI/res/values-te/strings.xml20
-rw-r--r--packages/SystemUI/res/values-television/config.xml2
-rw-r--r--packages/SystemUI/res/values-th/strings.xml14
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml8
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml8
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml10
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml8
-rw-r--r--packages/SystemUI/res/values/colors.xml1
-rw-r--r--packages/SystemUI/res/values/config.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml1
-rw-r--r--packages/SystemUI/res/values/strings.xml14
-rw-r--r--packages/SystemUI/res/xml/media_session_collapsed.xml17
-rw-r--r--packages/SystemUI/screenshot/Android.bp4
-rw-r--r--packages/SystemUI/screenshot/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt64
-rw-r--r--packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java193
-rw-r--r--packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt223
-rw-r--r--packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt78
-rw-r--r--packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt42
-rw-r--r--packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt58
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt38
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt105
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java40
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java22
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java23
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java44
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java63
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ClockEventController.kt146
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java69
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java129
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java22
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/Gefingerpoken.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java158
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt183
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java (renamed from packages/SystemUI/src/com/android/systemui/SystemUIFactory.java)101
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt72
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt (renamed from core/java/android/app/timedetector/NetworkTimeSuggestion.aidl)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt114
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt144
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java (renamed from packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java128
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java94
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java136
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java99
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java90
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java (renamed from packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java)12
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt41
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java145
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt59
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java70
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java41
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt150
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt112
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt112
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt112
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt110
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt120
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java153
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt192
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconListTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java)137
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java3
-rw-r--r--packages/VpnDialogs/res/values-te/strings.xml2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java21
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java63
-rw-r--r--services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java13
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java21
-rw-r--r--services/art-profile98
-rw-r--r--services/companion/java/com/android/server/companion/PackageUtils.java22
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java6
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java62
-rw-r--r--services/core/java/com/android/server/Watchdog.java1
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java23
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java41
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java85
-rw-r--r--services/core/java/com/android/server/am/AppRestrictionController.java35
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java7
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java4
-rw-r--r--services/core/java/com/android/server/am/UserController.java31
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java100
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java6
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java30
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java58
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java64
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java2
-rw-r--r--services/core/java/com/android/server/content/ContentService.java105
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java6
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java2
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayService.java12
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerService.java3
-rw-r--r--services/core/java/com/android/server/input/GestureMonitorSpyWindow.java6
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java22
-rw-r--r--services/core/java/com/android/server/input/NativeInputManagerService.java24
-rw-r--r--services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java14
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java5
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java15
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java372
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodUtils.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/SubtypeUtils.java19
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java13
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java216
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java32
-rw-r--r--services/core/java/com/android/server/location/gnss/NtpTimeHelper.java20
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java9
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java18
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsStorage.java193
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java2
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java21
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java8
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java5
-rw-r--r--services/core/java/com/android/server/notification/PermissionHelper.java6
-rw-r--r--services/core/java/com/android/server/notification/SnoozeHelper.java390
-rw-r--r--services/core/java/com/android/server/pm/AppDataHelper.java2
-rw-r--r--services/core/java/com/android/server/pm/AppsFilterBase.java40
-rw-r--r--services/core/java/com/android/server/pm/AppsFilterImpl.java105
-rw-r--r--services/core/java/com/android/server/pm/AppsFilterLocked.java10
-rw-r--r--services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java4
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java2
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java27
-rw-r--r--services/core/java/com/android/server/pm/FileInstallArgs.java268
-rw-r--r--services/core/java/com/android/server/pm/IPackageManagerBase.java8
-rw-r--r--services/core/java/com/android/server/pm/InstallArgs.java40
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java395
-rw-r--r--services/core/java/com/android/server/pm/InstallingSession.java318
-rw-r--r--services/core/java/com/android/server/pm/MoveInstallArgs.java133
-rw-r--r--services/core/java/com/android/server/pm/MultiPackageInstallingSession.java107
-rw-r--r--services/core/java/com/android/server/pm/PackageHandler.java10
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java21
-rw-r--r--services/core/java/com/android/server/pm/PackageSessionVerifier.java9
-rw-r--r--services/core/java/com/android/server/pm/ReconciledPackage.java3
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java112
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java3
-rw-r--r--services/core/java/com/android/server/pm/SettingBase.java11
-rw-r--r--services/core/java/com/android/server/pm/Settings.java25
-rw-r--r--services/core/java/com/android/server/pm/SharedLibrariesImpl.java137
-rw-r--r--services/core/java/com/android/server/pm/StorageEventHelper.java4
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java19
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java7
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java4
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java46
-rw-r--r--services/core/java/com/android/server/timedetector/GnssTimeSuggestion.java (renamed from core/java/android/app/timedetector/GnssTimeSuggestion.java)32
-rw-r--r--services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java35
-rw-r--r--services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java182
-rw-r--r--services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java22
-rw-r--r--services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java63
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorInternal.java9
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java14
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorService.java8
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java2
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java2
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java2
-rw-r--r--services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java4
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java15
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java38
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java42
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartController.java40
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java59
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java24
-rw-r--r--services/core/java/com/android/server/wm/AsyncRotationController.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java38
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java116
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java11
-rw-r--r--services/core/java/com/android/server/wm/InputManagerCallback.java2
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java32
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java64
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java18
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java6
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java2
-rw-r--r--services/core/java/com/android/server/wm/SafeActivityOptions.java9
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java14
-rw-r--r--services/core/java/com/android/server/wm/Transition.java11
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java65
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java34
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java4
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp48
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java7
-rw-r--r--services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java16
-rw-r--r--services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java13
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java32
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt18
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java16
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java46
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java31
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java369
-rw-r--r--services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java24
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/GnssTimeSuggestionTest.java (renamed from core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java)17
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeSuggestionTest.java (renamed from core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java)48
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java65
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java13
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java91
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java11
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java14
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java14
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java28
-rw-r--r--telecomm/java/android/telecom/CallScreeningService.java3
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java14
-rw-r--r--telecomm/java/com/android/internal/telecom/ITelecomService.aidl15
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java56
-rw-r--r--telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl22
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt179
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt108
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt97
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt28
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt16
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt128
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt99
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt107
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt146
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt123
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt130
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt26
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt128
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt117
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt96
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt95
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt93
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt227
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt162
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt48
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt211
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt27
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt75
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt79
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt40
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt50
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt42
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt58
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt84
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt96
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt79
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt134
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt69
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt107
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt192
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt33
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt168
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt240
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt32
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt170
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt22
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt186
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt52
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt91
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt48
-rw-r--r--tests/StagedInstallTest/Android.bp1
-rw-r--r--tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java23
-rw-r--r--tools/lint/Android.bp1
974 files changed, 21137 insertions, 10596 deletions
diff --git a/apct-tests/perftests/core/Android.bp b/apct-tests/perftests/core/Android.bp
index 2182f0bc2501..ab20fdbde1e5 100644
--- a/apct-tests/perftests/core/Android.bp
+++ b/apct-tests/perftests/core/Android.bp
@@ -43,12 +43,14 @@ android_test {
"apct-perftests-resources-manager-apps",
"apct-perftests-utils",
"collector-device-lib",
+ "compatibility-device-util-axt",
+ "core-tests-support",
"guava",
],
libs: ["android.test.base"],
- java_resources: [ ":GoogleFontDancingScript", ],
+ java_resources: [":GoogleFontDancingScript"],
data: [":perfetto_artifacts"],
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index 56fa70cfc220..c153201cd475 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.perftests.core">
<permission android:name="com.android.perftests.core.TestPermission" />
@@ -33,6 +34,17 @@
android:exported="false"
android:process=":some_provider" />
+ <!-- We remove EmojiCompat initializer here because it may crash the test process
+ if the initializer runs while TypefaceSerializationPerfTest is running. -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ android:exported="false"
+ tools:node="merge">
+ <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
+ tools:node="remove" />
+ </provider>
+
<service
android:name="android.view.autofill.MyAutofillService"
android:label="PERF AutofillService"
@@ -43,6 +55,16 @@
</intent-filter>
</service>
+ <service android:name="android.view.HandwritingImeService"
+ android:label="Handwriting IME"
+ android:permission="android.permission.BIND_INPUT_METHOD"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.view.InputMethod"/>
+ </intent-filter>
+ <meta-data android:name="android.view.im"
+ android:resource="@xml/ime_meta_handwriting"/>
+ </service>
</application>
<instrumentation android:name="androidx.benchmark.junit4.AndroidBenchmarkRunner"
diff --git a/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml b/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml
new file mode 100644
index 000000000000..24c0c255c2f3
--- /dev/null
+++ b/apct-tests/perftests/core/res/xml/ime_meta_handwriting.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<input-method
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
+ android:supportsStylusHandwriting="true"/>
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
index d27250719c6d..675ff0107081 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
@@ -17,10 +17,13 @@
package android.graphics.perftests;
import android.graphics.Typeface;
+import android.os.Debug;
import android.os.SharedMemory;
-import android.perftests.utils.BenchmarkState;
-import android.perftests.utils.PerfStatusReporter;
+import android.os.SystemClock;
+import android.perftests.utils.ManualBenchmarkState;
+import android.perftests.utils.PerfManualStatusReporter;
import android.util.ArrayMap;
+import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -37,16 +40,33 @@ import java.util.Map;
@RunWith(AndroidJUnit4.class)
public class TypefaceSerializationPerfTest {
+ private static final String TAG = "TypefaceSerializationPerfTest";
+
@Rule
- public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+ public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter();
@Test
public void testSerializeFontMap() throws Exception {
Map<String, Typeface> systemFontMap = Typeface.getSystemFontMap();
- BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
- while (state.keepRunning()) {
+ long elapsedTime = 0;
+ while (state.keepRunning(elapsedTime)) {
+ long startTime = System.nanoTime();
Typeface.serializeFontMap(systemFontMap);
+ elapsedTime = System.nanoTime() - startTime;
+ }
+ }
+
+ @Test
+ public void testSerializeFontMap_memory() throws Exception {
+ Map<String, Typeface> systemFontMap = Typeface.getSystemFontMap();
+ SharedMemory memory = Typeface.serializeFontMap(systemFontMap);
+ ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
+
+ while (state.keepRunning(memory.getSize())) {
+ // Rate-limiting
+ SystemClock.sleep(100);
}
}
@@ -54,22 +74,54 @@ public class TypefaceSerializationPerfTest {
public void testDeserializeFontMap() throws Exception {
SharedMemory memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
ByteBuffer buffer = memory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
- BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
+
+ ArrayMap<String, Typeface> out = new ArrayMap<>();
+ long elapsedTime = 0;
+ while (state.keepRunning(elapsedTime)) {
+ long startTime = System.nanoTime();
+ buffer.position(0);
+ Typeface.deserializeFontMap(buffer, out);
+ elapsedTime = System.nanoTime() - startTime;
+ }
+ }
+
+ @Test
+ public void testDeserializeFontMap_memory() throws Exception {
+ SharedMemory memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
+ ByteBuffer buffer = memory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
+ ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
ArrayMap<String, Typeface> out = new ArrayMap<>();
- while (state.keepRunning()) {
+ // Diff of native heap allocation size (in bytes) before and after deserializeFontMap.
+ // Note: we don't measure memory usage of setSystemFontMap because setSystemFontMap sets
+ // some global variables, and it's hard to clear them.
+ long heapDiff = 0;
+ // Sometimes heapDiff may become negative due to GC.
+ // Use 0 in that case to avoid crashing in keepRunning.
+ while (state.keepRunning(Math.max(0, heapDiff))) {
buffer.position(0);
+ long baselineSize = Debug.getNativeHeapAllocatedSize();
Typeface.deserializeFontMap(buffer, out);
+ long currentSize = Debug.getNativeHeapAllocatedSize();
+ heapDiff = currentSize - baselineSize;
+ Log.i(TAG, String.format("native heap alloc: current = %d, baseline = %d, diff = %d",
+ currentSize, baselineSize, heapDiff));
+ // Release native objects here to minimize the impact of GC.
+ for (Typeface typeface : out.values()) {
+ typeface.releaseNativeObjectForTest();
+ }
+ out.clear();
}
}
@Test
public void testSetSystemFontMap() throws Exception {
SharedMemory memory = null;
- BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ ManualBenchmarkState state = mPerfManualStatusReporter.getBenchmarkState();
- while (state.keepRunning()) {
- state.pauseTiming();
+ long elapsedTime = 0;
+ while (state.keepRunning(elapsedTime)) {
// Explicitly destroy lazy-loaded typefaces, so that we don't hit the mmap limit
// (max_map_count).
Typeface.destroySystemFontMap();
@@ -78,8 +130,9 @@ public class TypefaceSerializationPerfTest {
memory.close();
}
memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
- state.resumeTiming();
+ long startTime = System.nanoTime();
Typeface.setSystemFontMap(memory);
+ elapsedTime = System.nanoTime() - startTime;
}
}
}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
new file mode 100644
index 000000000000..694d609cd950
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import libcore.java.security.TestKeyStore;
+import libcore.javax.net.ssl.TestSSLContext;
+import libcore.javax.net.ssl.TestSSLSocketPair;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.net.ssl.SSLSocket;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SSLLoopbackPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void time() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TestSSLContext context =
+ TestSSLContext.create(TestKeyStore.getClient(), TestKeyStore.getServer());
+ SSLSocket[] sockets = TestSSLSocketPair.connect(context, null, null);
+ context.close();
+ sockets[0].close();
+ sockets[1].close();
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
new file mode 100644
index 000000000000..bdbbcb0da006
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.net.ssl.SSLSocketFactory;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SSLSocketFactoryPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void time() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ SSLSocketFactory.getDefault();
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
new file mode 100644
index 000000000000..42dc5811e6db
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public final class SchemePrefixPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ enum Strategy {
+ JAVA() {
+ @Override
+ String execute(String spec) {
+ int colon = spec.indexOf(':');
+
+ if (colon < 1) {
+ return null;
+ }
+
+ for (int i = 0; i < colon; i++) {
+ char c = spec.charAt(i);
+ if (!isValidSchemeChar(i, c)) {
+ return null;
+ }
+ }
+
+ return spec.substring(0, colon).toLowerCase(Locale.US);
+ }
+
+ private boolean isValidSchemeChar(int index, char c) {
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ return true;
+ }
+ if (index > 0 && ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.')) {
+ return true;
+ }
+ return false;
+ }
+ },
+
+ REGEX() {
+ private final Pattern mPattern = Pattern.compile("^([a-zA-Z][a-zA-Z0-9+\\-.]*):");
+
+ @Override
+ String execute(String spec) {
+ Matcher matcher = mPattern.matcher(spec);
+ if (matcher.find()) {
+ return matcher.group(1).toLowerCase(Locale.US);
+ } else {
+ return null;
+ }
+ }
+ };
+
+ abstract String execute(String spec);
+ }
+
+ @Parameters(name = "mStrategy={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {{Strategy.REGEX}, {Strategy.JAVA}});
+ }
+
+ @Parameterized.Parameter(0)
+ public Strategy mStrategy;
+
+ @Test
+ public void timeSchemePrefix() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStrategy.execute("http://android.com");
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
new file mode 100644
index 000000000000..1ec22d217109
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SerializationPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private static byte[] bytes(Object o) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ out.writeObject(o);
+ out.close();
+ return baos.toByteArray();
+ }
+
+ @Test
+ public void timeReadIntArray() throws Exception {
+ int[] intArray = new int[256];
+ readSingleObject(intArray);
+ }
+
+ @Test
+ public void timeWriteIntArray() throws Exception {
+ int[] intArray = new int[256];
+ writeSingleObject(intArray);
+ }
+
+ @Test
+ public void timeReadArrayListInteger() throws Exception {
+ ArrayList<Integer> object = new ArrayList<Integer>();
+ for (int i = 0; i < 256; ++i) {
+ object.add(i);
+ }
+ readSingleObject(object);
+ }
+
+ @Test
+ public void timeWriteArrayListInteger() throws Exception {
+ ArrayList<Integer> object = new ArrayList<Integer>();
+ for (int i = 0; i < 256; ++i) {
+ object.add(i);
+ }
+ writeSingleObject(object);
+ }
+
+ @Test
+ public void timeReadString() throws Exception {
+ readSingleObject("hello");
+ }
+
+ @Test
+ public void timeReadObjectStreamClass() throws Exception {
+ // A special case because serialization itself requires this class.
+ // (This should really be a unit test.)
+ ObjectStreamClass osc = ObjectStreamClass.lookup(String.class);
+ readSingleObject(osc);
+ }
+
+ @Test
+ public void timeWriteString() throws Exception {
+ // String is a special case that avoids JNI.
+ writeSingleObject("hello");
+ }
+
+ @Test
+ public void timeWriteObjectStreamClass() throws Exception {
+ // A special case because serialization itself requires this class.
+ // (This should really be a unit test.)
+ ObjectStreamClass osc = ObjectStreamClass.lookup(String.class);
+ writeSingleObject(osc);
+ }
+
+ // This is
+ //
+ // @Testa baseline for the others.
+ public void timeWriteNoObjects() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ out.reset();
+ baos.reset();
+ }
+ out.close();
+ }
+
+ private void readSingleObject(Object object) throws Exception {
+ byte[] bytes = bytes(object);
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ ObjectInputStream in = new ObjectInputStream(bais);
+ in.readObject();
+ in.close();
+ bais.reset();
+ }
+ }
+
+ private void writeSingleObject(Object o) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ out.writeObject(o);
+ out.reset();
+ baos.reset();
+ }
+ out.close();
+ }
+
+ @Test
+ public void timeWriteEveryKindOfField() throws Exception {
+ writeSingleObject(new LittleBitOfEverything());
+ }
+
+ @Test
+ public void timeWriteSerializableBoolean() throws Exception {
+ writeSingleObject(new SerializableBoolean());
+ }
+
+ @Test
+ public void timeWriteSerializableByte() throws Exception {
+ writeSingleObject(new SerializableByte());
+ }
+
+ @Test
+ public void timeWriteSerializableChar() throws Exception {
+ writeSingleObject(new SerializableChar());
+ }
+
+ @Test
+ public void timeWriteSerializableDouble() throws Exception {
+ writeSingleObject(new SerializableDouble());
+ }
+
+ @Test
+ public void timeWriteSerializableFloat() throws Exception {
+ writeSingleObject(new SerializableFloat());
+ }
+
+ @Test
+ public void timeWriteSerializableInt() throws Exception {
+ writeSingleObject(new SerializableInt());
+ }
+
+ @Test
+ public void timeWriteSerializableLong() throws Exception {
+ writeSingleObject(new SerializableLong());
+ }
+
+ @Test
+ public void timeWriteSerializableShort() throws Exception {
+ writeSingleObject(new SerializableShort());
+ }
+
+ @Test
+ public void timeWriteSerializableReference() throws Exception {
+ writeSingleObject(new SerializableReference());
+ }
+
+ @Test
+ public void timeReadEveryKindOfField() throws Exception {
+ readSingleObject(new LittleBitOfEverything());
+ }
+
+ @Test
+ public void timeReadSerializableBoolean() throws Exception {
+ readSingleObject(new SerializableBoolean());
+ }
+
+ @Test
+ public void timeReadSerializableByte() throws Exception {
+ readSingleObject(new SerializableByte());
+ }
+
+ @Test
+ public void timeReadSerializableChar() throws Exception {
+ readSingleObject(new SerializableChar());
+ }
+
+ @Test
+ public void timeReadSerializableDouble() throws Exception {
+ readSingleObject(new SerializableDouble());
+ }
+
+ @Test
+ public void timeReadSerializableFloat() throws Exception {
+ readSingleObject(new SerializableFloat());
+ }
+
+ @Test
+ public void timeReadSerializableInt() throws Exception {
+ readSingleObject(new SerializableInt());
+ }
+
+ @Test
+ public void timeReadSerializableLong() throws Exception {
+ readSingleObject(new SerializableLong());
+ }
+
+ @Test
+ public void timeReadSerializableShort() throws Exception {
+ readSingleObject(new SerializableShort());
+ }
+
+ @Test
+ public void timeReadSerializableReference() throws Exception {
+ readSingleObject(new SerializableReference());
+ }
+
+ public static class SerializableBoolean implements Serializable {
+ boolean mZ;
+ }
+
+ public static class SerializableByte implements Serializable {
+ byte mB;
+ }
+
+ public static class SerializableChar implements Serializable {
+ char mC;
+ }
+
+ public static class SerializableDouble implements Serializable {
+ double mD;
+ }
+
+ public static class SerializableFloat implements Serializable {
+ float mF;
+ }
+
+ public static class SerializableInt implements Serializable {
+ int mI;
+ }
+
+ public static class SerializableLong implements Serializable {
+ long mJ;
+ }
+
+ public static class SerializableShort implements Serializable {
+ short mS;
+ }
+
+ public static class SerializableReference implements Serializable {
+ Object mL;
+ }
+
+ public static class LittleBitOfEverything implements Serializable {
+ boolean mZ;
+ byte mB;
+ char mC;
+ double mD;
+ float mF;
+ int mI;
+ long mJ;
+ short mS;
+ Object mL;
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
new file mode 100644
index 000000000000..96e7cb27afef
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Tests RSA and DSA mSignature creation and verification. */
+@RunWith(Parameterized.class)
+@LargeTest
+public class SignaturePerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Parameters(name = "mAlgorithm={0}, mImplementation={1}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {Algorithm.MD5WithRSA, Implementation.OpenSSL},
+ {Algorithm.SHA1WithRSA, Implementation.OpenSSL},
+ {Algorithm.SHA256WithRSA, Implementation.OpenSSL},
+ {Algorithm.SHA384WithRSA, Implementation.OpenSSL},
+ {Algorithm.SHA512WithRSA, Implementation.OpenSSL},
+ {Algorithm.SHA1withDSA, Implementation.BouncyCastle}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public Algorithm mAlgorithm;
+
+ @Parameterized.Parameter(1)
+ public Implementation mImplementation;
+
+ private static final int DATA_SIZE = 8192;
+ private static final byte[] DATA = new byte[DATA_SIZE];
+
+ static {
+ for (int i = 0; i < DATA_SIZE; i++) {
+ DATA[i] = (byte) i;
+ }
+ }
+
+ public enum Algorithm {
+ MD5WithRSA,
+ SHA1WithRSA,
+ SHA256WithRSA,
+ SHA384WithRSA,
+ SHA512WithRSA,
+ SHA1withDSA
+ };
+
+ public enum Implementation {
+ OpenSSL,
+ BouncyCastle
+ };
+
+ // Key generation and signing aren't part of the benchmark for verification
+ // so cache the results
+ private static Map<String, KeyPair> sKeyPairs = new HashMap<String, KeyPair>();
+ private static Map<String, byte[]> sSignatures = new HashMap<String, byte[]>();
+
+ private String mSignatureAlgorithm;
+ private byte[] mSignature;
+ private PrivateKey mPrivateKey;
+ private PublicKey mPublicKey;
+
+ @Before
+ public void setUp() throws Exception {
+ this.mSignatureAlgorithm = mAlgorithm.toString();
+
+ String keyAlgorithm =
+ mSignatureAlgorithm.substring(
+ mSignatureAlgorithm.length() - 3, mSignatureAlgorithm.length());
+ KeyPair keyPair = sKeyPairs.get(keyAlgorithm);
+ if (keyPair == null) {
+ KeyPairGenerator generator = KeyPairGenerator.getInstance(keyAlgorithm);
+ keyPair = generator.generateKeyPair();
+ sKeyPairs.put(keyAlgorithm, keyPair);
+ }
+ this.mPrivateKey = keyPair.getPrivate();
+ this.mPublicKey = keyPair.getPublic();
+
+ this.mSignature = sSignatures.get(mSignatureAlgorithm);
+ if (this.mSignature == null) {
+ Signature signer = Signature.getInstance(mSignatureAlgorithm);
+ signer.initSign(keyPair.getPrivate());
+ signer.update(DATA);
+ this.mSignature = signer.sign();
+ sSignatures.put(mSignatureAlgorithm, mSignature);
+ }
+ }
+
+ @Test
+ public void timeSign() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Signature signer;
+ switch (mImplementation) {
+ case OpenSSL:
+ signer = Signature.getInstance(mSignatureAlgorithm, "AndroidOpenSSL");
+ break;
+ case BouncyCastle:
+ signer = Signature.getInstance(mSignatureAlgorithm, "BC");
+ break;
+ default:
+ throw new RuntimeException(mImplementation.toString());
+ }
+ signer.initSign(mPrivateKey);
+ signer.update(DATA);
+ signer.sign();
+ }
+ }
+
+ @Test
+ public void timeVerify() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Signature verifier;
+ switch (mImplementation) {
+ case OpenSSL:
+ verifier = Signature.getInstance(mSignatureAlgorithm, "AndroidOpenSSL");
+ break;
+ case BouncyCastle:
+ verifier = Signature.getInstance(mSignatureAlgorithm, "BC");
+ break;
+ default:
+ throw new RuntimeException(mImplementation.toString());
+ }
+ verifier.initVerify(mPublicKey);
+ verifier.update(DATA);
+ verifier.verify(mSignature);
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
new file mode 100644
index 000000000000..c25b0ce6d7d9
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Benchmark for java.text.SimpleDateFormat. This tests common formatting, parsing and creation
+ * operations with a specific focus on TimeZone handling.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SimpleDateFormatPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void time_createFormatWithTimeZone() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+ }
+ }
+
+ @Test
+ public void time_parseWithTimeZoneShort() throws ParseException {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sdf.parse("2000.01.01 PST");
+ }
+ }
+
+ @Test
+ public void time_parseWithTimeZoneLong() throws ParseException {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sdf.parse("2000.01.01 Pacific Standard Time");
+ }
+ }
+
+ @Test
+ public void time_parseWithoutTimeZone() throws ParseException {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sdf.parse("2000.01.01");
+ }
+ }
+
+ @Test
+ public void time_createAndParseWithTimeZoneShort() throws ParseException {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+ sdf.parse("2000.01.01 PST");
+ }
+ }
+
+ @Test
+ public void time_createAndParseWithTimeZoneLong() throws ParseException {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
+ sdf.parse("2000.01.01 Pacific Standard Time");
+ }
+ }
+
+ @Test
+ public void time_formatWithTimeZoneShort() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd z");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sdf.format(new Date());
+ }
+ }
+
+ @Test
+ public void time_formatWithTimeZoneLong() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd zzzz");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sdf.format(new Date());
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
new file mode 100644
index 000000000000..eeccb5bd64f4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Many of these tests are bogus in that the cost will vary wildly depending on inputs. For _my_
+ * current purposes, that's okay. But beware!
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StrictMathPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private final double mDouble = 1.2;
+ private final float mFloat = 1.2f;
+ private final int mInt = 1;
+ private final long mLong = 1L;
+
+ /* Values for full line coverage of ceiling function */
+ private static final double[] CEIL_DOUBLES =
+ new double[] {
+ 3245817.2018463886,
+ 1418139.083668501,
+ 3.572936802189103E15,
+ -4.7828929737254625E249,
+ 213596.58636369856,
+ 6.891928421440976E-96,
+ -7.9318566885477E-36,
+ -1.9610339084804148E15,
+ -4.696725715628246E10,
+ 3742491.296880909,
+ 7.140274745333553E11
+ };
+
+ /* Values for full line coverage of floor function */
+ private static final double[] FLOOR_DOUBLES =
+ new double[] {
+ 7.140274745333553E11,
+ 3742491.296880909,
+ -4.696725715628246E10,
+ -1.9610339084804148E15,
+ 7.049948629370372E-56,
+ -7.702933170334643E-16,
+ -1.99657681810579,
+ -1.1659287182288336E236,
+ 4.085518816513057E15,
+ -1500948.440658056,
+ -2.2316479921415575E7
+ };
+
+ @Test
+ public void timeAbsD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.abs(mDouble);
+ }
+ }
+
+ @Test
+ public void timeAbsF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.abs(mFloat);
+ }
+ }
+
+ @Test
+ public void timeAbsI() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.abs(mInt);
+ }
+ }
+
+ @Test
+ public void timeAbsL() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.abs(mLong);
+ }
+ }
+
+ @Test
+ public void timeAcos() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.acos(mDouble);
+ }
+ }
+
+ @Test
+ public void timeAsin() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.asin(mDouble);
+ }
+ }
+
+ @Test
+ public void timeAtan() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.atan(mDouble);
+ }
+ }
+
+ @Test
+ public void timeAtan2() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.atan2(3, 4);
+ }
+ }
+
+ @Test
+ public void timeCbrt() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.cbrt(mDouble);
+ }
+ }
+
+ @Test
+ public void timeCeilOverInterestingValues() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < CEIL_DOUBLES.length; ++i) {
+ StrictMath.ceil(CEIL_DOUBLES[i]);
+ }
+ }
+ }
+
+ @Test
+ public void timeCopySignD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.copySign(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeCopySignF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.copySign(mFloat, mFloat);
+ }
+ }
+
+ @Test
+ public void timeCos() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.cos(mDouble);
+ }
+ }
+
+ @Test
+ public void timeCosh() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.cosh(mDouble);
+ }
+ }
+
+ @Test
+ public void timeExp() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.exp(mDouble);
+ }
+ }
+
+ @Test
+ public void timeExpm1() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.expm1(mDouble);
+ }
+ }
+
+ @Test
+ public void timeFloorOverInterestingValues() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < FLOOR_DOUBLES.length; ++i) {
+ StrictMath.floor(FLOOR_DOUBLES[i]);
+ }
+ }
+ }
+
+ @Test
+ public void timeGetExponentD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.getExponent(mDouble);
+ }
+ }
+
+ @Test
+ public void timeGetExponentF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.getExponent(mFloat);
+ }
+ }
+
+ @Test
+ public void timeHypot() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.hypot(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeIEEEremainder() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.IEEEremainder(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeLog() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.log(mDouble);
+ }
+ }
+
+ @Test
+ public void timeLog10() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.log10(mDouble);
+ }
+ }
+
+ @Test
+ public void timeLog1p() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.log1p(mDouble);
+ }
+ }
+
+ @Test
+ public void timeMaxD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.max(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeMaxF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.max(mFloat, mFloat);
+ }
+ }
+
+ @Test
+ public void timeMaxI() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.max(mInt, mInt);
+ }
+ }
+
+ @Test
+ public void timeMaxL() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.max(mLong, mLong);
+ }
+ }
+
+ @Test
+ public void timeMinD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.min(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeMinF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.min(mFloat, mFloat);
+ }
+ }
+
+ @Test
+ public void timeMinI() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.min(mInt, mInt);
+ }
+ }
+
+ @Test
+ public void timeMinL() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.min(mLong, mLong);
+ }
+ }
+
+ @Test
+ public void timeNextAfterD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.nextAfter(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeNextAfterF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.nextAfter(mFloat, mFloat);
+ }
+ }
+
+ @Test
+ public void timeNextUpD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.nextUp(mDouble);
+ }
+ }
+
+ @Test
+ public void timeNextUpF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.nextUp(mFloat);
+ }
+ }
+
+ @Test
+ public void timePow() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.pow(mDouble, mDouble);
+ }
+ }
+
+ @Test
+ public void timeRandom() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.random();
+ }
+ }
+
+ @Test
+ public void timeRint() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.rint(mDouble);
+ }
+ }
+
+ @Test
+ public void timeRoundD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.round(mDouble);
+ }
+ }
+
+ @Test
+ public void timeRoundF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.round(mFloat);
+ }
+ }
+
+ @Test
+ public void timeScalbD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.scalb(mDouble, 5);
+ }
+ }
+
+ @Test
+ public void timeScalbF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.scalb(mFloat, 5);
+ }
+ }
+
+ @Test
+ public void timeSignumD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.signum(mDouble);
+ }
+ }
+
+ @Test
+ public void timeSignumF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.signum(mFloat);
+ }
+ }
+
+ @Test
+ public void timeSin() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.sin(mDouble);
+ }
+ }
+
+ @Test
+ public void timeSinh() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.sinh(mDouble);
+ }
+ }
+
+ @Test
+ public void timeSqrt() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.sqrt(mDouble);
+ }
+ }
+
+ @Test
+ public void timeTan() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.tan(mDouble);
+ }
+ }
+
+ @Test
+ public void timeTanh() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.tanh(mDouble);
+ }
+ }
+
+ @Test
+ public void timeToDegrees() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.toDegrees(mDouble);
+ }
+ }
+
+ @Test
+ public void timeToRadians() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.toRadians(mDouble);
+ }
+ }
+
+ @Test
+ public void timeUlpD() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.ulp(mDouble);
+ }
+ }
+
+ @Test
+ public void timeUlpF() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StrictMath.ulp(mFloat);
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
new file mode 100644
index 000000000000..34fb88bf8627
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/** Tests the performance of various StringBuilder methods. */
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringBuilderPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Parameters(name = "mLength={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {{1}, {10}, {100}});
+ }
+
+ @Parameterized.Parameter(0)
+ public int mLength;
+
+ @Test
+ public void timeAppendBoolean() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(true);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendChar() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append('c');
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendCharArray() {
+ char[] chars = "chars".toCharArray();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(chars);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendCharSequence() {
+ CharSequence cs = "chars";
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(cs);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendSubCharSequence() {
+ CharSequence cs = "chars";
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(cs);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendDouble() {
+ double d = 1.2;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(d);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendFloat() {
+ float f = 1.2f;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(f);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendInt() {
+ int n = 123;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(n);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendLong() {
+ long l = 123;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(l);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendObject() {
+ // We don't want to time the toString, so ensure we're calling a trivial one...
+ Object o =
+ new Object() {
+ @Override
+ public String toString() {
+ return "constant";
+ }
+ };
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(o);
+ }
+ }
+ }
+
+ @Test
+ public void timeAppendString() {
+ String s = "chars";
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < mLength; ++j) {
+ sb.append(s);
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
new file mode 100644
index 000000000000..6854c0de9387
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Benchmarks to measure the performance of String.equals for Strings of varying lengths. Each
+ * benchmarks makes 5 measurements, aiming at covering cases like strings of equal length that are
+ * not equal, identical strings with different references, strings with different endings, interned
+ * strings, and strings of different lengths.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringEqualsPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private final String mLong1 =
+ "Ahead-of-time compilation is possible as the compiler may just convert an instruction"
+ + " thus: dex code: add-int v1000, v2000, v3000 C code: setIntRegter(1000,"
+ + " call_dex_add_int(getIntRegister(2000), getIntRegister(3000)) This means even"
+ + " lidinstructions may have code generated, however, it is not expected that code"
+ + " generate inthis way will perform well. The job of AOT verification is to tell"
+ + " the compiler thatinstructions are sound and provide tests to detect unsound"
+ + " sequences so slow path codemay be generated. Other than for totally invalid"
+ + " code, the verification may fail at AOrrun-time. At AOT time it can be because"
+ + " of incomplete information, at run-time it can ethat code in a different apk"
+ + " that the application depends upon has changed. The Dalvikverifier would return"
+ + " a bool to state whether a Class were good or bad. In ART the fail case becomes"
+ + " either a soft or hard failure. Classes have new states to represent that a soft"
+ + " failure occurred at compile time and should be re-verified at run-time.";
+
+ private final String mVeryLong =
+ "Garbage collection has two phases. The first distinguishes live objects from garbage"
+ + " objects. The second is reclaiming the rage of garbage objectIn the mark-sweep"
+ + " algorithm used by Dalvik, the first phase is achievd by computing the closure"
+ + " of all reachable objects in a process known as tracing from theoots. After"
+ + " thetrace has completed, garbage objects are reclaimed. Each of these"
+ + " operations can beparallelized and can be interleaved with the operation of the"
+ + " applicationTraditionally,the tracing phase dominates the time spent in garbage"
+ + " collection. The greatreduction ipause time can be achieved by interleaving as"
+ + " much of this phase as possible with theapplication. If we simply ran the GC in"
+ + " a separate thread with no other changes, normaloperation of an application"
+ + " would confound the trace. Abstractly, the GC walks the h oall reachable"
+ + " objects. When the application is paused, the object graph cannot change.The GC"
+ + " can therefore walk this structure and assume that all reachable objects"
+ + " live.When the application is running, this graph may be altered. New nodes may"
+ + " be addnd edgemay be changed. These changes may cause live objects to be hidden"
+ + " and falsely recla bythe GC. To avoid this problem a write barrier is used to"
+ + " intercept and record modifionto objects in a separate structure. After"
+ + " performing its walk, the GC will revisit theupdated objects and re-validate its"
+ + " assumptions. Without a card table, the garbagecollector would have to visit"
+ + " all objects reached during the trace looking for dirtied objects. The cost of"
+ + " this operation would be proportional to the amount of live data.With a card"
+ + " table, the cost of this operation is proportional to the amount of updateatThe"
+ + " write barrier in Dalvik is a card marking write barrier. Card marking is the"
+ + " proceof noting the location of object connectivity changes on a sub-page"
+ + " granularity. A caris merely a colorful term for a contiguous extent of memory"
+ + " smaller than a page, commonsomewhere between 128- and 512-bytes. Card marking"
+ + " is implemented by instrumenting alllocations in the virtual machine which can"
+ + " assign a pointer to an object. After themalpointer assignment has occurred, a"
+ + " byte is written to a byte-map spanning the heap whiccorresponds to the location"
+ + " of the updated object. This byte map is known as a card taThe garbage"
+ + " collector visits this card table and looks for written bytes to reckon"
+ + " thelocation of updated objects. It then rescans all objects located on the"
+ + " dirty card,correcting liveness assumptions that were invalidated by the"
+ + " application. While cardmarking imposes a small burden on the application"
+ + " outside of a garbage collection, theoverhead of maintaining the card table is"
+ + " paid for by the reduced time spent insidegarbage collection. With the"
+ + " concurrent garbage collection thread and a write barriersupported by the"
+ + " interpreter, JIT, and Runtime we modify garbage collection";
+
+ private final String[][] mShortStrings =
+ new String[][] {
+ // Equal, constant comparison
+ {"a", "a"},
+ // Different constants, first character different
+ {":", " :"},
+ // Different constants, last character different, same length
+ {"ja M", "ja N"},
+ // Different constants, different lengths
+ {"$$$", "$$"},
+ // Force execution of code beyond reference equality check
+ {"hi", new String("hi")}
+ };
+
+ private final String[][] mMediumStrings =
+ new String[][] {
+ // Equal, constant comparison
+ {"Hello my name is ", "Hello my name is "},
+ // Different constants, different lengths
+ {"What's your name?", "Whats your name?"},
+ // Force execution of code beyond reference equality check
+ {"Android Runtime", new String("Android Runtime")},
+ // Different constants, last character different, same length
+ {"v3ry Cre@tiVe?****", "v3ry Cre@tiVe?***."},
+ // Different constants, first character different, same length
+ {"!@#$%^&*()_++*^$#@", "0@#$%^&*()_++*^$#@"}
+ };
+
+ private final String[][] mLongStrings =
+ new String[][] {
+ // Force execution of code beyond reference equality check
+ {mLong1, new String(mLong1)},
+ // Different constants, last character different, same length
+ {mLong1 + "fun!", mLong1 + "----"},
+ // Equal, constant comparison
+ {mLong1 + mLong1, mLong1 + mLong1},
+ // Different constants, different lengths
+ {mLong1 + "123456789", mLong1 + "12345678"},
+ // Different constants, first character different, same length
+ {"Android Runtime" + mLong1, "android Runtime" + mLong1}
+ };
+
+ private final String[][] mVeryLongStrings =
+ new String[][] {
+ // Force execution of code beyond reference equality check
+ {mVeryLong, new String(mVeryLong)},
+ // Different constants, different lengths
+ {mVeryLong + mVeryLong, mVeryLong + " " + mVeryLong},
+ // Equal, constant comparison
+ {mVeryLong + mVeryLong + mVeryLong, mVeryLong + mVeryLong + mVeryLong},
+ // Different constants, last character different, same length
+ {mVeryLong + "77777", mVeryLong + "99999"},
+ // Different constants, first character different
+ {"Android Runtime" + mVeryLong, "android Runtime" + mVeryLong}
+ };
+
+ private final String[][] mEndStrings =
+ new String[][] {
+ // Different constants, medium but different lengths
+ {"Hello", "Hello "},
+ // Different constants, long but different lengths
+ {mLong1, mLong1 + "x"},
+ // Different constants, very long but different lengths
+ {mVeryLong, mVeryLong + "?"},
+ // Different constants, same medium lengths
+ {"How are you doing today?", "How are you doing today "},
+ // Different constants, short but different lengths
+ {"1", "1."}
+ };
+
+ private final String mTmpStr1 =
+ "012345678901234567890"
+ + "0123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789";
+
+ private final String mTmpStr2 =
+ "z012345678901234567890"
+ + "0123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789"
+ + "012345678901234567890123456789012345678x";
+
+ private final String[][] mNonalignedStrings =
+ new String[][] {
+ // Different non-word aligned medium length strings
+ {mTmpStr1, mTmpStr1.substring(1)},
+ // Different differently non-word aligned medium length strings
+ {mTmpStr2, mTmpStr2.substring(2)},
+ // Different non-word aligned long length strings
+ {mLong1, mLong1.substring(3)},
+ // Different non-word aligned very long length strings
+ {mVeryLong, mVeryLong.substring(1)},
+ // Equal non-word aligned constant strings
+ {"hello", "hello".substring(1)}
+ };
+
+ private final Object[] mObjects =
+ new Object[] {
+ // Compare to Double object
+ new Double(1.5),
+ // Compare to Integer object
+ new Integer(9999999),
+ // Compare to String array
+ new String[] {"h", "i"},
+ // Compare to int array
+ new int[] {1, 2, 3},
+ // Compare to Character object
+ new Character('a')
+ };
+
+ // Check assumptions about how the compiler, new String(String), and String.intern() work.
+ // Any failures here would invalidate these benchmarks.
+ @Before
+ public void setUp() throws Exception {
+ // String constants are the same object
+ Assert.assertSame("abc", "abc");
+ // new String(String) makes a copy
+ Assert.assertNotSame("abc", new String("abc"));
+ // Interned strings are treated like constants, so it is not necessary to
+ // separately benchmark interned strings.
+ Assert.assertSame("abc", "abc".intern());
+ Assert.assertSame("abc", new String("abc").intern());
+ // Compiler folds constant strings into new constants
+ Assert.assertSame(mLong1 + mLong1, mLong1 + mLong1);
+ }
+
+ // Benchmark cases of String.equals(null)
+ @Test
+ public void timeEqualsNull() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mMediumStrings.length; i++) {
+ mMediumStrings[i][0].equals(null);
+ }
+ }
+ }
+
+ // Benchmark cases with very short (<5 character) Strings
+ @Test
+ public void timeEqualsShort() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mShortStrings.length; i++) {
+ mShortStrings[i][0].equals(mShortStrings[i][1]);
+ }
+ }
+ }
+
+ // Benchmark cases with medium length (10-15 character) Strings
+ @Test
+ public void timeEqualsMedium() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mMediumStrings.length; i++) {
+ mMediumStrings[i][0].equals(mMediumStrings[i][1]);
+ }
+ }
+ }
+
+ // Benchmark cases with long (>100 character) Strings
+ @Test
+ public void timeEqualsLong() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mLongStrings.length; i++) {
+ mLongStrings[i][0].equals(mLongStrings[i][1]);
+ }
+ }
+ }
+
+ // Benchmark cases with very long (>1000 character) Strings
+ @Test
+ public void timeEqualsVeryLong() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mVeryLongStrings.length; i++) {
+ mVeryLongStrings[i][0].equals(mVeryLongStrings[i][1]);
+ }
+ }
+ }
+
+ // Benchmark cases with non-word aligned Strings
+ @Test
+ public void timeEqualsNonWordAligned() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mNonalignedStrings.length; i++) {
+ mNonalignedStrings[i][0].equals(mNonalignedStrings[i][1]);
+ }
+ }
+ }
+
+ // Benchmark cases with slight differences in the endings
+ @Test
+ public void timeEqualsEnd() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mEndStrings.length; i++) {
+ mEndStrings[i][0].equals(mEndStrings[i][1]);
+ }
+ }
+ }
+
+ // Benchmark cases of comparing a string to a non-string object
+ @Test
+ public void timeEqualsNonString() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < mMediumStrings.length; i++) {
+ mMediumStrings[i][0].equals(mObjects[i]);
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
new file mode 100644
index 000000000000..79ff646bbfff
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringIsEmptyPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void timeIsEmpty_NonEmpty() {
+ boolean result = true;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ result &= !("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".isEmpty());
+ }
+ if (!result) throw new RuntimeException();
+ }
+
+ @Test
+ public void timeIsEmpty_Empty() {
+ boolean result = true;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ result &= ("".isEmpty());
+ }
+ if (!result) throw new RuntimeException();
+ }
+
+ @Test
+ public void timeLengthEqualsZero() {
+ boolean result = true;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ result &= !("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length() == 0);
+ }
+ if (!result) throw new RuntimeException();
+ }
+
+ @Test
+ public void timeEqualsEmpty() {
+ boolean result = true;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ result &= !"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".equals("");
+ }
+ if (!result) throw new RuntimeException();
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
new file mode 100644
index 000000000000..8dbf9f58fbf8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringLengthPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void timeLength() {
+ int length = 0;
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ length = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
+ }
+ if (length != 51) throw new RuntimeException();
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
new file mode 100644
index 000000000000..02194b1b9745
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ enum StringLengths {
+ EMPTY(""),
+ SHORT("short"),
+ EIGHTY(makeString(80)),
+ EIGHT_KI(makeString(8192));
+ final String mValue;
+
+ StringLengths(String value) {
+ this.mValue = value;
+ }
+ }
+
+ @Parameters(name = "mStringLengths={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {StringLengths.EIGHT_KI},
+ {StringLengths.EIGHTY},
+ {StringLengths.SHORT},
+ {StringLengths.EMPTY}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public StringLengths mStringLengths;
+
+ private static String makeString(int length) {
+ StringBuilder result = new StringBuilder(length);
+ for (int i = 0; i < length; ++i) {
+ result.append((char) i);
+ }
+ return result.toString();
+ }
+
+ @Test
+ public void timeHashCode() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.hashCode();
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
new file mode 100644
index 000000000000..b0d1ee4132fa
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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 android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringReplaceAllPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ // NOTE: These estimates of MOVEABLE / NON_MOVEABLE are based on a knowledge of
+ // ART implementation details. They make a difference here because JNI calls related
+ // to strings took different paths depending on whether the String in question was
+ // moveable or not.
+ enum StringLengths {
+ EMPTY(""),
+ MOVEABLE_16(makeString(16)),
+ MOVEABLE_256(makeString(256)),
+ MOVEABLE_1024(makeString(1024)),
+ NON_MOVEABLE(makeString(64 * 1024)),
+ BOOT_IMAGE(java.util.jar.JarFile.MANIFEST_NAME);
+
+ private final String mValue;
+
+ StringLengths(String s) {
+ this.mValue = s;
+ }
+ }
+
+ private static String makeString(int length) {
+ final String sequence8 = "abcdefghijklmnop";
+ final int numAppends = (length / 16) - 1;
+ StringBuilder stringBuilder = new StringBuilder(length);
+
+ // (n-1) occurrences of "abcdefghijklmnop"
+ for (int i = 0; i < numAppends; ++i) {
+ stringBuilder.append(sequence8);
+ }
+
+ // and one final occurrence of qrstuvwx.
+ stringBuilder.append("qrstuvwx");
+
+ return stringBuilder.toString();
+ }
+
+ @Parameters(name = "mStringLengths={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {StringLengths.BOOT_IMAGE},
+ {StringLengths.EMPTY},
+ {StringLengths.MOVEABLE_16},
+ {StringLengths.MOVEABLE_256},
+ {StringLengths.MOVEABLE_1024},
+ {StringLengths.NON_MOVEABLE}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public StringLengths mStringLengths;
+
+ @Test
+ public void timeReplaceAllTrivialPatternNonExistent() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replaceAll("fish", "0");
+ }
+ }
+
+ @Test
+ public void timeReplaceTrivialPatternAllRepeated() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replaceAll("jklm", "0");
+ }
+ }
+
+ @Test
+ public void timeReplaceAllTrivialPatternSingleOccurrence() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replaceAll("qrst", "0");
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
new file mode 100644
index 000000000000..d2e657a78608
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringReplacePerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ enum StringLengths {
+ EMPTY(""),
+ L_16(makeString(16)),
+ L_64(makeString(64)),
+ L_256(makeString(256)),
+ L_512(makeString(512));
+
+ private final String mValue;
+
+ StringLengths(String s) {
+ this.mValue = s;
+ }
+ }
+
+ private static String makeString(int length) {
+ final String sequence8 = "abcdefghijklmnop";
+ final int numAppends = (length / 16) - 1;
+ StringBuilder stringBuilder = new StringBuilder(length);
+
+ // (n-1) occurrences of "abcdefghijklmnop"
+ for (int i = 0; i < numAppends; ++i) {
+ stringBuilder.append(sequence8);
+ }
+
+ // and one final occurrence of qrstuvwx.
+ stringBuilder.append("qrstuvwx");
+
+ return stringBuilder.toString();
+ }
+
+ @Parameters(name = "mStringLengths={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {StringLengths.EMPTY},
+ {StringLengths.L_16},
+ {StringLengths.L_64},
+ {StringLengths.L_256},
+ {StringLengths.L_512}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public StringLengths mStringLengths;
+
+ @Test
+ public void timeReplaceCharNonExistent() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replace('z', '0');
+ }
+ }
+
+ @Test
+ public void timeReplaceCharRepeated() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replace('a', '0');
+ }
+ }
+
+ @Test
+ public void timeReplaceSingleChar() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replace('q', '0');
+ }
+ }
+
+ @Test
+ public void timeReplaceSequenceNonExistent() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replace("fish", "0");
+ }
+ }
+
+ @Test
+ public void timeReplaceSequenceRepeated() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replace("jklm", "0");
+ }
+ }
+
+ @Test
+ public void timeReplaceSingleSequence() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.replace("qrst", "0");
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
new file mode 100644
index 000000000000..2bb25ac56694
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class StringSplitPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void timeStringSplitComma() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ "this,is,a,simple,example".split(",");
+ }
+ }
+
+ @Test
+ public void timeStringSplitLiteralDot() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ "this.is.a.simple.example".split("\\.");
+ }
+ }
+
+ @Test
+ public void timeStringSplitNewline() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ "this\nis\na\nsimple\nexample\n".split("\n");
+ }
+ }
+
+ @Test
+ public void timePatternSplitComma() {
+ Pattern p = Pattern.compile(",");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ p.split("this,is,a,simple,example");
+ }
+ }
+
+ @Test
+ public void timePatternSplitLiteralDot() {
+ Pattern p = Pattern.compile("\\.");
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ p.split("this.is.a.simple.example");
+ }
+ }
+
+ @Test
+ public void timeStringSplitHard() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ "this,is,a,harder,example".split("[,]");
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
new file mode 100644
index 000000000000..1efc188f4e4d
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringToBytesPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ enum StringLengths {
+ EMPTY(""),
+ L_16(makeString(16)),
+ L_64(makeString(64)),
+ L_256(makeString(256)),
+ L_512(makeString(512)),
+ A_16(makeAsciiString(16)),
+ A_64(makeAsciiString(64)),
+ A_256(makeAsciiString(256)),
+ A_512(makeAsciiString(512));
+
+ private final String mValue;
+
+ StringLengths(String s) {
+ this.mValue = s;
+ }
+ }
+
+ @Parameters(name = "mStringLengths={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {StringLengths.EMPTY},
+ {StringLengths.L_16},
+ {StringLengths.L_64},
+ {StringLengths.L_256},
+ {StringLengths.L_512},
+ {StringLengths.A_16},
+ {StringLengths.A_64},
+ {StringLengths.A_256},
+ {StringLengths.A_512}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public StringLengths mStringLengths;
+
+ private static String makeString(int length) {
+ char[] chars = new char[length];
+ for (int i = 0; i < length; ++i) {
+ chars[i] = (char) i;
+ }
+ return new String(chars);
+ }
+
+ private static String makeAsciiString(int length) {
+ char[] chars = new char[length];
+ for (int i = 0; i < length; ++i) {
+ chars[i] = ((i & 0x7f) != 0) ? (char) (i & 0x7f) : '?';
+ }
+ return new String(chars);
+ }
+
+ @Test
+ public void timeGetBytesUtf8() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.getBytes(StandardCharsets.UTF_8);
+ }
+ }
+
+ @Test
+ public void timeGetBytesIso88591() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.getBytes(StandardCharsets.ISO_8859_1);
+ }
+ }
+
+ @Test
+ public void timeGetBytesAscii() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mStringLengths.mValue.getBytes(StandardCharsets.US_ASCII);
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
new file mode 100644
index 000000000000..b01948aa2255
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class StringToRealPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Parameters(name = "mString={0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {"NaN"},
+ {"-1"},
+ {"0"},
+ {"1"},
+ {"1.2"},
+ {"-123.45"},
+ {"-123.45e8"},
+ {"-123.45e36"}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public String mString;
+
+ @Test
+ public void timeFloat_parseFloat() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Float.parseFloat(mString);
+ }
+ }
+
+ @Test
+ public void timeDouble_parseDouble() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ Double.parseDouble(mString);
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
new file mode 100644
index 000000000000..f2565550c6c5
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ThreadLocalPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private static final ThreadLocal<char[]> BUFFER =
+ new ThreadLocal<char[]>() {
+ @Override
+ protected char[] initialValue() {
+ return new char[20];
+ }
+ };
+
+ @Test
+ public void timeThreadLocal_get() {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ BUFFER.get();
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
new file mode 100644
index 000000000000..8274512e1501
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.TimeZone;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class TimeZonePerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void timeTimeZone_getDefault() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TimeZone.getDefault();
+ }
+ }
+
+ @Test
+ public void timeTimeZone_getTimeZoneUTC() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TimeZone.getTimeZone("UTC");
+ }
+ }
+
+ @Test
+ public void timeTimeZone_getTimeZone_default() throws Exception {
+ String defaultId = TimeZone.getDefault().getID();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TimeZone.getTimeZone(defaultId);
+ }
+ }
+
+ // A time zone with relatively few transitions.
+ @Test
+ public void timeTimeZone_getTimeZone_America_Caracas() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TimeZone.getTimeZone("America/Caracas");
+ }
+ }
+
+ // A time zone with a lot of transitions.
+ @Test
+ public void timeTimeZone_getTimeZone_America_Santiago() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TimeZone.getTimeZone("America/Santiago");
+ }
+ }
+
+ @Test
+ public void timeTimeZone_getTimeZone_GMT_plus_10() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ TimeZone.getTimeZone("GMT+10");
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
new file mode 100644
index 000000000000..2ea834d0b71c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.libcore.regression;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.xml.sax.InputSource;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+// http://code.google.com/p/android/issues/detail?id=18102
+@RunWith(Parameterized.class)
+@LargeTest
+public final class XMLEntitiesPerfTest {
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Parameters(name = "mLength={0}, mEntityFraction={1}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(
+ new Object[][] {
+ {10, 0},
+ {10, 0.5f},
+ {10, 1.0f},
+ {100, 0},
+ {100, 0.5f},
+ {100, 1.0f},
+ {1000, 0},
+ {1000, 0.5f},
+ {1000, 1.0f}
+ });
+ }
+
+ @Parameterized.Parameter(0)
+ public int mLength;
+
+ @Parameterized.Parameter(1)
+ public float mEntityFraction;
+
+ private XmlPullParserFactory mXmlPullParserFactory;
+ private DocumentBuilderFactory mDocumentBuilderFactory;
+
+ /** a string like {@code <doc>&amp;&amp;++</doc>}. */
+ private String mXml;
+
+ @Before
+ public void setUp() throws Exception {
+ mXmlPullParserFactory = XmlPullParserFactory.newInstance();
+ mDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+ StringBuilder xmlBuilder = new StringBuilder();
+ xmlBuilder.append("<doc>");
+ for (int i = 0; i < (mLength * mEntityFraction); i++) {
+ xmlBuilder.append("&amp;");
+ }
+ while (xmlBuilder.length() < mLength) {
+ xmlBuilder.append("+");
+ }
+ xmlBuilder.append("</doc>");
+ mXml = xmlBuilder.toString();
+ }
+
+ @Test
+ public void timeXmlParser() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ XmlPullParser parser = mXmlPullParserFactory.newPullParser();
+ parser.setInput(new StringReader(mXml));
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ // Keep running
+ }
+ }
+ }
+
+ @Test
+ public void timeDocumentBuilder() throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ DocumentBuilder documentBuilder = mDocumentBuilderFactory.newDocumentBuilder();
+ documentBuilder.parse(new InputSource(new StringReader(mXml)));
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingImeService.java b/apct-tests/perftests/core/src/android/view/HandwritingImeService.java
new file mode 100644
index 000000000000..27cb16e9a19f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/view/HandwritingImeService.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.content.ComponentName;
+import android.inputmethodservice.InputMethodService;
+
+public class HandwritingImeService extends InputMethodService {
+ private static final String PACKAGE_NAME = "com.android.perftests.core";
+
+ private static ComponentName getComponentName() {
+ return new ComponentName(PACKAGE_NAME, HandwritingImeService.class.getName());
+ }
+
+ static String getImeId() {
+ return getComponentName().flattenToShortString();
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
index 123b2eeba5dd..cf76334ceb10 100644
--- a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
@@ -22,7 +22,6 @@ import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.TOOL_TYPE_FINGER;
import static android.view.MotionEvent.TOOL_TYPE_STYLUS;
-
import android.app.Instrumentation;
import android.content.Context;
import android.perftests.utils.BenchmarkState;
@@ -34,11 +33,15 @@ import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.PollingCheck;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.TimeUnit;
+
/**
* Benchmark tests for {@link HandwritingInitiator}
*
@@ -56,11 +59,21 @@ public class HandwritingInitiatorPerfTest {
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Before
- public void setup() {
- final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
- mContext = mInstrumentation.getTargetContext();
+ public void setup() throws Exception {
+ final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ mContext = instrumentation.getTargetContext();
+
+ String imeId = HandwritingImeService.getImeId();
+ instrumentation.getUiAutomation().executeShellCommand("ime enable " + imeId);
+ instrumentation.getUiAutomation().executeShellCommand("ime set " + imeId);
+ PollingCheck.check("Check that stylus handwriting is available",
+ TimeUnit.SECONDS.toMillis(10),
+ () -> mContext.getSystemService(InputMethodManager.class)
+ .isStylusHandwritingAvailable());
+
final ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext);
mTouchSlop = viewConfiguration.getScaledTouchSlop();
+
final InputMethodManager inputMethodManager =
mContext.getSystemService(InputMethodManager.class);
mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager);
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 734545376279..448ee6160ce0 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -15,6 +15,7 @@
*/
package android.multiuser;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import android.annotation.NonNull;
@@ -42,6 +43,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.perftests.utils.ShellHelper;
+import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManagerGlobal;
@@ -116,13 +118,14 @@ public class UserLifecycleTests {
private boolean mHasManagedUserFeature;
private BroadcastWaiter mBroadcastWaiter;
private UserSwitchWaiter mUserSwitchWaiter;
+ private String mUserSwitchTimeoutMs;
private final BenchmarkRunner mRunner = new BenchmarkRunner();
@Rule
public BenchmarkResultsReporter mReporter = new BenchmarkResultsReporter(mRunner);
@Before
- public void setUp() {
+ public void setUp() throws Exception {
final Context context = InstrumentationRegistry.getContext();
mUm = UserManager.get(context);
mAm = context.getSystemService(ActivityManager.class);
@@ -141,10 +144,16 @@ public class UserLifecycleTests {
Log.w(TAG, "WARNING: Tests are being run from user " + mAm.getCurrentUser()
+ " rather than the system user");
}
+ mUserSwitchTimeoutMs = setSystemProperty("debug.usercontroller.user_switch_timeout_ms",
+ "100000");
+ if (TextUtils.isEmpty(mUserSwitchTimeoutMs)) {
+ mUserSwitchTimeoutMs = "invalid";
+ }
}
@After
- public void tearDown() {
+ public void tearDown() throws Exception {
+ setSystemProperty("debug.usercontroller.user_switch_timeout_ms", mUserSwitchTimeoutMs);
mBroadcastWaiter.close();
for (int userId : mUsersToRemove) {
try {
@@ -236,7 +245,7 @@ public class UserLifecycleTests {
/** Tests switching to an uninitialized user. */
@Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
- public void switchUser() throws RemoteException {
+ public void switchUser() throws Exception {
while (mRunner.keepRunning()) {
mRunner.pauseTiming();
final int startUser = mAm.getCurrentUser();
@@ -867,4 +876,10 @@ public class UserLifecycleTests {
private void attestFalse(@NonNull String message, boolean assertion) {
attestTrue(message, !assertion);
}
+
+ private String setSystemProperty(String name, String value) throws Exception {
+ final String oldValue = ShellHelper.runShellCommand("getprop " + name);
+ assertEquals("", ShellHelper.runShellCommand("setprop " + name + " " + value));
+ return oldValue;
+ }
}
diff --git a/apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js b/apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js
new file mode 100644
index 000000000000..d8e0f8e47163
--- /dev/null
+++ b/apct-tests/perftests/rubidium/assets/turtledove_parametrized_generateBid.js
@@ -0,0 +1,113 @@
+/*
+
+ Copyright The Closure Library Authors.
+ SPDX-License-Identifier: Apache-2.0
+*/
+var n,aa=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a},ca=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");
+},ea=ca(this),q=function(a,b){if(b)a:{var c=ea;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}};
+q("Symbol",function(a){if(a)return a;var b=function(g,f){this.ra=g;ba(this,"description",{configurable:!0,writable:!0,value:f})};b.prototype.toString=function(){return this.ra};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(g){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(g||"")+"_"+d++,g)};return e});
+q("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c<b.length;c++){var d=ea[b[c]];"function"===typeof d&&"function"!=typeof d.prototype[a]&&ba(d.prototype,a,{configurable:!0,writable:!0,value:function(){return fa(aa(this))}})}return a});
+var fa=function(a){a={next:a};a[Symbol.iterator]=function(){return this};return a},r=function(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:aa(a)}},ha="function"==typeof Object.create?Object.create:function(a){var b=function(){};b.prototype=a;return new b},ia;
+if("function"==typeof Object.setPrototypeOf)ia=Object.setPrototypeOf;else{var ja;a:{var ka={a:!0},la={};try{la.__proto__=ka;ja=la.a;break a}catch(a){}ja=!1}ia=ja?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}
+var ma=ia,t=function(a,b){a.prototype=ha(b.prototype);a.prototype.constructor=a;if(ma)ma(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.za=b.prototype},u=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};
+q("WeakMap",function(a){function b(){}function c(k){var l=typeof k;return"object"===l&&null!==k||"function"===l}function d(k){if(!u(k,g)){var l=new b;ba(k,g,{value:l})}}function e(k){var l=Object[k];l&&(Object[k]=function(m){if(m instanceof b)return m;Object.isExtensible(m)&&d(m);return l(m)})}if(function(){if(!a||!Object.seal)return!1;try{var k=Object.seal({}),l=Object.seal({}),m=new a([[k,2],[l,3]]);if(2!=m.get(k)||3!=m.get(l))return!1;m.delete(k);m.set(l,4);return!m.has(k)&&4==m.get(l)}catch(p){return!1}}())return a;
+var g="$jscomp_hidden_"+Math.random();e("freeze");e("preventExtensions");e("seal");var f=0,h=function(k){this.M=(f+=Math.random()+1).toString();if(k){k=r(k);for(var l;!(l=k.next()).done;)l=l.value,this.set(l[0],l[1])}};h.prototype.set=function(k,l){if(!c(k))throw Error("Invalid WeakMap key");d(k);if(!u(k,g))throw Error("WeakMap key fail: "+k);k[g][this.M]=l;return this};h.prototype.get=function(k){return c(k)&&u(k,g)?k[g][this.M]:void 0};h.prototype.has=function(k){return c(k)&&u(k,g)&&u(k[g],this.M)};
+h.prototype.delete=function(k){return c(k)&&u(k,g)&&u(k[g],this.M)?delete k[g][this.M]:!1};return h});
+q("Map",function(a){if(function(){if(!a||"function"!=typeof a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var h=Object.seal({x:4}),k=new a(r([[h,"s"]]));if("s"!=k.get(h)||1!=k.size||k.get({x:4})||k.set({x:4},"t")!=k||2!=k.size)return!1;var l=k.entries(),m=l.next();if(m.done||m.value[0]!=h||"s"!=m.value[1])return!1;m=l.next();return m.done||4!=m.value[0].x||"t"!=m.value[1]||!l.next().done?!1:!0}catch(p){return!1}}())return a;var b=new WeakMap,c=function(h){this.L={};this.A=g();
+this.size=0;if(h){h=r(h);for(var k;!(k=h.next()).done;)k=k.value,this.set(k[0],k[1])}};c.prototype.set=function(h,k){h=0===h?0:h;var l=d(this,h);l.list||(l.list=this.L[l.id]=[]);l.j?l.j.value=k:(l.j={next:this.A,B:this.A.B,head:this.A,key:h,value:k},l.list.push(l.j),this.A.B.next=l.j,this.A.B=l.j,this.size++);return this};c.prototype.delete=function(h){h=d(this,h);return h.j&&h.list?(h.list.splice(h.index,1),h.list.length||delete this.L[h.id],h.j.B.next=h.j.next,h.j.next.B=h.j.B,h.j.head=null,this.size--,
+!0):!1};c.prototype.clear=function(){this.L={};this.A=this.A.B=g();this.size=0};c.prototype.has=function(h){return!!d(this,h).j};c.prototype.get=function(h){return(h=d(this,h).j)&&h.value};c.prototype.entries=function(){return e(this,function(h){return[h.key,h.value]})};c.prototype.keys=function(){return e(this,function(h){return h.key})};c.prototype.values=function(){return e(this,function(h){return h.value})};c.prototype.forEach=function(h,k){for(var l=this.entries(),m;!(m=l.next()).done;)m=m.value,
+h.call(k,m[1],m[0],this)};c.prototype[Symbol.iterator]=c.prototype.entries;var d=function(h,k){var l=k&&typeof k;"object"==l||"function"==l?b.has(k)?l=b.get(k):(l=""+ ++f,b.set(k,l)):l="p_"+k;var m=h.L[l];if(m&&u(h.L,l))for(h=0;h<m.length;h++){var p=m[h];if(k!==k&&p.key!==p.key||k===p.key)return{id:l,list:m,index:h,j:p}}return{id:l,list:m,index:-1,j:void 0}},e=function(h,k){var l=h.A;return fa(function(){if(l){for(;l.head!=h.A;)l=l.B;for(;l.next!=l.head;)return l=l.next,{done:!1,value:k(l)};l=null}return{done:!0,
+value:void 0}})},g=function(){var h={};return h.B=h.next=h.head=h},f=0;return c});q("Number.isFinite",function(a){return a?a:function(b){return"number"!==typeof b?!1:!isNaN(b)&&Infinity!==b&&-Infinity!==b}});var oa=function(a,b){a instanceof String&&(a+="");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var g=c++;return{value:b(g,a[g]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[Symbol.iterator]=function(){return e};return e};
+q("Array.prototype.entries",function(a){return a?a:function(){return oa(this,function(b,c){return[b,c]})}});q("Number.isNaN",function(a){return a?a:function(b){return"number"===typeof b&&isNaN(b)}});
+q("Set",function(a){if(function(){if(!a||"function"!=typeof a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var c=Object.seal({x:4}),d=new a(r([c]));if(!d.has(c)||1!=d.size||d.add(c)!=d||1!=d.size||d.add({x:4})!=d||2!=d.size)return!1;var e=d.entries(),g=e.next();if(g.done||g.value[0]!=c||g.value[1]!=c)return!1;g=e.next();return g.done||g.value[0]==c||4!=g.value[0].x||g.value[1]!=g.value[0]?!1:e.next().done}catch(f){return!1}}())return a;var b=function(c){this.m=new Map;if(c){c=
+r(c);for(var d;!(d=c.next()).done;)this.add(d.value)}this.size=this.m.size};b.prototype.add=function(c){c=0===c?0:c;this.m.set(c,c);this.size=this.m.size;return this};b.prototype.delete=function(c){c=this.m.delete(c);this.size=this.m.size;return c};b.prototype.clear=function(){this.m.clear();this.size=0};b.prototype.has=function(c){return this.m.has(c)};b.prototype.entries=function(){return this.m.entries()};b.prototype.values=function(){return this.m.values()};b.prototype.keys=b.prototype.values;
+b.prototype[Symbol.iterator]=b.prototype.values;b.prototype.forEach=function(c,d){var e=this;this.m.forEach(function(g){return c.call(d,g,g,e)})};return b});q("Array.from",function(a){return a?a:function(b,c,d){c=null!=c?c:function(h){return h};var e=[],g="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];if("function"==typeof g){b=g.call(b);for(var f=0;!(g=b.next()).done;)e.push(c.call(d,g.value,f++))}else for(g=b.length,f=0;f<g;f++)e.push(c.call(d,b[f],f));return e}});
+q("Object.entries",function(a){return a?a:function(b){var c=[],d;for(d in b)u(b,d)&&c.push([d,b[d]]);return c}});q("Object.is",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});q("Array.prototype.includes",function(a){return a?a:function(b,c){var d=this;d instanceof String&&(d=String(d));var e=d.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var g=d[c];if(g===b||Object.is(g,b))return!0}return!1}});
+q("String.prototype.includes",function(a){return a?a:function(b,c){if(null==this)throw new TypeError("The 'this' value for String.prototype.includes must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype.includes must not be a regular expression");return-1!==(this+"").indexOf(b,c||0)}});q("Array.prototype.values",function(a){return a?a:function(){return oa(this,function(b,c){return c})}});
+var pa=function(a){var b=typeof a;return"object"!=b?b:a?Array.isArray(a)?"array":b:"null"},qa=function(a,b){function c(){}c.prototype=b.prototype;a.za=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.Ca=function(d,e,g){for(var f=Array(arguments.length-2),h=2;h<arguments.length;h++)f[h-2]=arguments[h];return b.prototype[e].apply(d,f)}};function ra(a,b){if(Error.captureStackTrace)Error.captureStackTrace(this,ra);else{var c=Error().stack;c&&(this.stack=c)}a&&(this.message=String(a));void 0!==b&&(this.cause=b)}qa(ra,Error);ra.prototype.name="CustomError";function sa(a,b){a=a.split("%s");for(var c="",d=a.length-1,e=0;e<d;e++)c+=a[e]+(e<b.length?b[e]:"%s");ra.call(this,c+a[d])}qa(sa,ra);sa.prototype.name="AssertionError";function ta(a,b,c,d){var e="Assertion failed";if(c){e+=": "+c;var g=d}else a&&(e+=": "+a,g=b);throw new sa(""+e,g||[]);}
+var v=function(a,b,c){a||ta("",null,b,Array.prototype.slice.call(arguments,2));return a},ua=function(a,b,c){null==a&&ta("Expected to exist: %s.",[a],b,Array.prototype.slice.call(arguments,2));return a},va=function(a,b){throw new sa("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));},w=function(a,b,c){Array.isArray(a)||ta("Expected array but got %s: %s.",[pa(a),a],b,Array.prototype.slice.call(arguments,2))},x=function(a,b,c,d){a instanceof b||ta("Expected instanceof %s but got %s.",
+[wa(b),wa(a)],c,Array.prototype.slice.call(arguments,3));return a};function wa(a){return a instanceof Function?a.displayName||a.name||"unknown type name":a instanceof Object?a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a):null===a?"null":typeof a};var xa={},ya=null,za=function(a){var b,c=pa(a);v("array"==c||"object"==c&&"number"==typeof a.length,"encodeByteArray takes an array as a parameter");void 0===b&&(b=0);if(!ya){ya={};c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split("");for(var d=["+/=","+/","-_=","-_.","-_"],e=0;5>e;e++){var g=c.concat(d[e].split(""));xa[e]=g;for(var f=0;f<g.length;f++){var h=g[f],k=ya[h];void 0===k?ya[h]=f:v(k===f)}}}b=xa[b];c=Array(Math.floor(a.length/3));d=b[64]||"";for(e=g=0;g<a.length-2;g+=
+3){k=a[g];var l=a[g+1];h=a[g+2];f=b[k>>2];k=b[(k&3)<<4|l>>4];l=b[(l&15)<<2|h>>6];h=b[h&63];c[e++]=""+f+k+l+h}f=0;h=d;switch(a.length-g){case 2:f=a[g+1],h=b[(f&15)<<2]||d;case 1:a=a[g],c[e]=""+b[a>>2]+b[(a&3)<<4|f>>4]+h+d}return c.join("")};var Aa="undefined"!==typeof Uint8Array,Ba={};var Ca,Da=function(a){if(Ba!==Ba)throw Error("illegal external caller");this.qa=a;if(null!=a&&0===a.length)throw Error("ByteString should be constructed with non-empty values");};v(!0);var Ea={};var z="function"===typeof Symbol&&"symbol"===typeof Symbol()?Symbol("INTERNAL_ARRAY_STATE"):void 0;function Fa(a,b){Object.isFrozen(a)||(z?a[z]|=b:void 0!==a.F?a.F|=b:Object.defineProperties(a,{F:{value:b,configurable:!0,writable:!0,enumerable:!1}}))}var Ga=Object.getOwnPropertyDescriptor(Array.prototype,"wa");
+Object.defineProperties(Array.prototype,{wa:{get:function(){var a=A(this),b=[];1&a&&b.push("IS_REPEATED_FIELD");2&a&&b.push("IS_IMMUTABLE_ARRAY");4&a&&b.push("IS_API_FORMATTED");8&a&&b.push("ONLY_MUTABLE_VALUES");a=b.join(",");return Ga?Ga.get.call(this)+"|"+a:a},configurable:!0,enumerable:!1}});function A(a){w(a,"state is only maintained on arrays.");a=z?a[z]:a.F;return null==a?0:a}function B(a){w(a,"state is only maintained on arrays.");Fa(a,1);return a}
+function C(a){return Array.isArray(a)?!!(A(a)&2):!1}function Ha(a){if(!Array.isArray(a))throw Error("cannot mark non-array as immutable");Fa(a,2)}function Ia(a,b){if(!Array.isArray(a))throw Error("cannot mark non-array as mutable");b?Fa(a,8):Object.isFrozen(a)||(z?a[z]&=-9:void 0!==a.F&&(a.F&=-9))};function Ja(a){return null!==a&&"object"===typeof a&&!Array.isArray(a)&&a.constructor===Object}var Ka=Symbol("exempted jspb subclass"),La=Symbol("generated by jspb"),Ma=Object.freeze(B([])),Na=function(a){if(C(a.g))throw Error("Cannot mutate an immutable Message");},Oa="undefined"!=typeof Symbol&&"undefined"!=typeof Symbol.hasInstance;function Pa(a){return{value:a,configurable:!1,writable:!1,enumerable:!1}};function Qa(a){return a.displayName||a.name||"unknown type name"}function Ra(a,b){if(!(a instanceof b))throw Error("Expected instanceof "+Qa(b)+" but got "+(a&&Qa(a.constructor)));return a}function Sa(a,b,c){c=void 0===c?!1:c;if(Array.isArray(a))return new b(a);if(c)return new b};var Ta=function(){throw Error("please construct maps as mutable then call toImmutable");};if(Oa){var Ua=function(){throw Error("Cannot perform instanceof checks on ImmutableMap");},Va={};Object.defineProperties(Ta,(Va[Symbol.hasInstance]=Pa(Ua),Va));v(Ta[Symbol.hasInstance]===Ua,"defineProperties did not work: was it monkey-patched?")};function Wa(a){switch(typeof a){case "number":return isFinite(a)?a:String(a);case "object":if(a&&!Array.isArray(a)){if(Aa&&null!=a&&a instanceof Uint8Array)return za(a);if(a instanceof Da){var b=a.qa;null!=b&&"string"!==typeof b&&(Aa&&b instanceof Uint8Array?b=za(b):(va("Cannot coerce to b64 string: "+pa(b)),b=null));return null==b?"":a.qa=b}}}return a};function Xa(a,b){b=void 0===b?Ya:b;w(a);return Za(a,b)}function $a(a,b){if(null!=a){if(Array.isArray(a))a=Za(a,b);else if(Ja(a)){var c={},d;for(d in a)c[d]=$a(a[d],b);a=c}else a=b(a);return a}}function Za(a,b){w(a);for(var c=a.slice(),d=0;d<c.length;d++)c[d]=$a(c[d],b);Array.isArray(a)&&A(a)&1&&B(c);return c}function ab(a){if(a&&"object"==typeof a&&a.toJSON)return a.toJSON();a=Wa(a);return Array.isArray(a)?Xa(a,ab):a}function Ya(a){return Aa&&null!=a&&a instanceof Uint8Array?new Uint8Array(a):a};var bb=function(a){return a.C||(a.C=a.g[a.G+a.D]={})},D=function(a,b,c){return-1===b?null:b>=a.G?a.C?a.C[b]:void 0:(void 0===c?0:c)&&a.C&&(c=a.C[b],null!=c)?c:a.g[b+a.D]},E=function(a,b,c,d,e){d=void 0===d?!1:d;(void 0===e?0:e)||Na(a);b<a.G&&!d?a.g[b+a.D]=c:bb(a)[b]=c},F=function(a,b,c,d){c=void 0===c?!0:c;var e=D(a,b,d);Array.isArray(e)||(e=Ma);if(C(a.g))c&&(Ha(e),Object.freeze(e));else if(e===Ma||C(e))e=B(e.slice()),E(a,b,e,d);return e},G=function(a,b){var c=Number,d=F(a,b,!1),e;if(e=d.length)e=
+d,w(e,"state is only maintained on arrays."),e=!(A(e)&4);if(e){Object.isFrozen(d)&&(d=B(d.slice()),E(a,b,d,void 0,!0));for(b=0;b<d.length;b++)d[b]=c(d[b]);c=d;w(c,"state is only maintained on arrays.");Fa(c,5)}C(a.g)&&Object.freeze(d);return d},I=function(a,b,c){a=D(a,b);return null==a?c:a},J=function(a,b){a=D(a,b);a=null==a?a:!!a;return null==a?!1:a},L=function(a,b){a=D(a,b);a=null==a?a:+a;return null==a?0:a};function M(a,b,c){Na(a);0!==c?E(a,b,c):E(a,b,void 0,!1);return a}
+var N=function(a,b,c,d,e){e=void 0===e?!1:e;var g=e;if(-1===c)d=null;else{a.h||(a.h={});var f=a.h[c];if(f)d=f;else{var h=D(a,c,g);b=Sa(h,b,d);void 0==b?d=f:(d&&b.g!==h&&E(a,c,b.g,g,!0),a.h[c]=b,C(a.g)&&Ha(b.g),d=b)}}if(null==d)return d;C(d.g)&&!C(a.g)&&(d=d.fa(Ea),E(a,c,d.g,e),a.h[c]=d);return d},O=function(a,b,c,d){d=void 0===d?!1:d;var e=C(a.g),g=d,f=e;f=void 0===f?!0:f;a.h||(a.h={});var h=C(a.g);var k=a.h[c];g=F(a,c,!0,g);var l=h||C(g);if(!k){k=[];h=h||l;for(var m=0;m<g.length;m++){var p=g[m];
+h=h||C(p);p=Sa(p,b);void 0!==p&&(k.push(p),l&&Ha(p.g))}a.h[c]=k;Ia(g,!h)}b=l||f;f=C(k);b&&!f&&(Object.isFrozen(k)&&(a.h[c]=k=k.slice()),Ha(k),Object.freeze(k));!b&&f&&(a.h[c]=k=k.slice());a=F(a,c,d);if(!(c=e)&&(c=a)){if(!Array.isArray(a))throw Error("cannot check mutability state of non-array");c=!(A(a)&8)}if(c){for(c=0;c<k.length;c++)(d=k[c])&&C(d.g)&&!e&&(k[c]=k[c].fa(Ea),a[c]=k[c].g);Ia(a,!0)}return k},cb=function(a,b,c,d){Na(a);a.h||(a.h={});b=null!=d?Ra(d,ua(b)).g:d;a.h[c]=d;E(a,c,b)},P=function(a,
+b){return I(a,b,"0")};var Q=function(a,b,c){x(this,Q,"The message constructor should only be used by subclasses");v(this.constructor!==Q,"Message is an abstract class and cannot be directly constructed");if(!0!==this[Ka]){v(!0===this[La],"Message can only be subclassed by proto gencode.");var d=Object.getPrototypeOf(v(Object.getPrototypeOf(this)));v(d.hasOwnProperty(La),"Generated jspb classes should not be extended")}a||(a=db);db=null;d=this.constructor.Ia;a||(a=d?[d]:[]);this.D=(d?0:-1)-(this.constructor.Ga||0);this.h=
+void 0;this.g=a;a:{d=this.g.length;a=d-1;if(d&&(d=this.g[a],Ja(d))){this.G=a-this.D;this.C=d;break a}void 0!==b&&-1<b?(this.G=Math.max(b,a+1-this.D),this.C=void 0):this.G=Number.MAX_VALUE}if(c)for(b=0;b<c.length;b++)if(a=c[b],a<this.G)a+=this.D,(d=this.g[a])?Array.isArray(d)&&B(d):this.g[a]=Ma;else{d=bb(this);var e=d[a];e?Array.isArray(e)&&B(e):d[a]=Ma}};n=Q.prototype;n.toJSON=function(){return Xa(this.g,ab)};n.getExtension=function(a){x(this,a.va);return a.Ea(x(this,Q))};
+n.hasExtension=function(a){x(this,a.va);v(!a.Ha,"repeated extensions don't support hasExtension");var b=x(this,Q);return null!=D(b,a.Da)};n.clone=function(){var a=x(this,Q),b=Xa(a.g);x(a,Q);w(b);db=b;b=new a.constructor(b);x(b,Q);db=null;eb(b,a);return b};n.toString=function(){return this.g.toString()};
+function eb(a,b){v(a,"expected `to` to be non-null");v(b,"expected `from` to be non-null");b.N&&(a.N=b.N.slice());var c=b.h;if(c){b=b.C;for(var d in c){var e=c[d];if(e){var g=!(!b||!b[d]),f=+d;if(Array.isArray(e)){if(e.length)for(g=O(a,e[0].constructor,f,g),f=0;f<Math.min(g.length,e.length);f++)eb(g[f],x(e[f],Q))}else x(e,Q),(g=N(a,e.constructor,f,void 0,g))&&eb(g,e)}}}}var db;var fb=function(){Q.call(this,void 0);throw Error("ImmutableMessage is not instantiable");};t(fb,Q);fb.prototype.clone=function(){return Q.prototype.clone.call(this)};if(Oa){var gb=function(){throw Error("Cannot perform instanceof checks for MutableMessage");},hb={};Object.defineProperties(fb,(hb[Symbol.hasInstance]=Pa(gb),hb));v(fb[Symbol.hasInstance]===gb,"broken defineProperties implementation")};var R=function(){Q.apply(this,arguments)};t(R,Q);R.prototype.fa=function(){return this};if(Oa){var ib=function(){throw Error("Cannot perform instanceof checks for MutableMessage");},jb={};Object.defineProperties(R,(jb[Symbol.hasInstance]=Pa(ib),jb));v(R[Symbol.hasInstance]===ib,"defineProperties did not work: was it monkey-patched?")};function kb(a,b,c,d,e,g){if(a=a.h&&a.h[c])if(Array.isArray(a)){e=g.ba?B(a.slice()):a;g=0<e.length?e[0].constructor:void 0;Na(b);if(null!=e){w(e);d=B([]);a=!1;for(var f=0;f<e.length;f++)d[f]=Ra(e[f],ua(g)).g,a=a||C(d[f]);b.h||(b.h={});b.h[c]=e;Ia(d,!a)}else b.h&&(b.h[c]=void 0),d=Ma;E(b,c,d)}else cb(b,a.constructor,c,x(a,Q));else Aa&&d instanceof Uint8Array?(e=d,x(e,Uint8Array),e=e.length?new Da(new Uint8Array(e)):Ca||(Ca=new Da(null))):(Array.isArray(d)&&(e?Ha(d):Array.isArray(d)&&A(d)&1&&g.ba&&(d=
+d.slice())),e=d),E(b,c,e)};var S=function(){R.apply(this,arguments)};t(S,R);
+S.prototype.fa=function(a){if(a!==Ea)throw Error("requires a valid immutable API token");if(C(this.g)){x(this,Q);a={ba:!0};var b=C(this.g);if(b&&!a.ba)throw Error("copyRepeatedFields must be true for frozen messages");var c=new this.constructor;this.N&&(c.N=this.N.slice());for(var d=this.g,e=0;e<d.length;e++){var g=d[e];if(e===d.length-1&&Ja(g))for(h in g){var f=+h;Number.isNaN(f)?bb(c)[h]=g[h]:kb(this,c,f,g[h],b,a)}else kb(this,c,e-this.D,g,b,a)}var h=c}else h=this;return h};S.prototype[La]=!0;
+if(Oa){var lb={};Object.defineProperties(S,(lb[Symbol.hasInstance]=Pa(Object[Symbol.hasInstance]),lb));v(S[Symbol.hasInstance]===Object[Symbol.hasInstance],"broken defineProperties implementation")};var mb=void 0;function nb(a){var b=mb;mb=void 0;var c=[],d=ob(a,c);if(!d&&c){var e="Expected Array<unknown>, got "+pb(a);c.push(e)}if(!d)throw a="",b&&(a=b()+"\n"),Error(a+"Guard Array<unknown> failed:\n"+c.reverse().join("\n"));return a}
+function pb(a,b){b=void 0===b?new Set:b;if(b.has(a))return"(Recursive reference)";switch(typeof a){case "object":if(a){var c=Object.getPrototypeOf(a);switch(c){case Map.prototype:case Set.prototype:case Array.prototype:b.add(a);var d="["+Array.from(a,function(e){return pb(e,b)}).join(", ")+"]";b.delete(a);c!==Array.prototype&&(d=qb(c.constructor)+"("+d+")");return d;case Object.prototype:return b.add(a),c="{"+Object.entries(a).map(function(e){var g=r(e);e=g.next().value;g=g.next().value;return e+
+": "+pb(g,b)}).join(", ")+"}",b.delete(a),c;default:return d="Object",c&&c.constructor&&(d=qb(c.constructor)),"function"===typeof a.toString&&a.toString!==Object.prototype.toString?d+"("+String(a)+")":"(object "+d+")"}}break;case "function":return"function "+qb(a);case "number":if(!Number.isFinite(a))return String(a);break;case "bigint":return a.toString(10)+"n"}return JSON.stringify(a)}function qb(a){var b=a.name;b||(b=(a=/function\s+([^\(]+)/m.exec(String(a)))?a[1]:"(Anonymous)");return b};var ob=function(a){a.Fa=function(){return"Array<unknown>"};return a}(function(a){return Array.isArray(a)});var rb=[[[["1646440773",[-.21289063,-.014526367,-.0046081543,-.013671875,-.012451172,.056152344,-.05029297,-.15234375,-.044677734,-.29101563,-.099121094,.0014190674,.08496094,.078125,-.009765625,-.09765625,-.045166016,.09765625,-.022583008,.23242188,-.04321289,.0126953125,.032226563,.064941406,.36132813,-.09716797,.28515625,.0074768066,-.11279297,-.0625,.012329102,-.076171875]]],[["1646451678",[-.18652344,.15917969,-.005340576,.055664063,.041015625,-.010253906,.06591797,-.071777344,.024536133,1.828125,
+-.19140625,-.35351563,.13671875,.45117188,.12792969,-.03466797,.18261719,.19628906,.14160156,.17480469,-.04638672,-.06689453,-.30273438,.35351563,-.33789063,-.7578125,-.17675781,.05810547,-.002029419,.005279541,-.025756836,.15234375]]]],null,[1],"CMb9tKfcrvYCFawfBgAdboELOQ",null,[null,null,null,1,[]],[null,null,null,null,[]]];var sb={"1j115753478":[[["52836427830","310927197294","4",[[["1643849995",[3.09375,.8203125,1.4765625,-.55078125,1.9140625,-.78125,-1.1640625,-3.15625,1.25,3.421875,1.6484375,1.0625,4.96875,-.66796875,-1.4375,.87109375,1.6171875,-4.125,-2.375,3.421875,-2.359375,1.6015625,.625,-4.65625,-5.03125,.416015625,-4.03125,-.24609375,3.296875,-.052001953125,-3.75,3.765625]],["1643804092",[3.09375,.796875,1.46875,-.56640625,1.890625,-.76953125,-1.1484375,-3.140625,1.2109375,3.421875,1.625,1.046875,4.9375,-.65234375,
+-1.421875,.84765625,1.6015625,-4.125,-2.359375,3.453125,-2.34375,1.5859375,.63671875,-4.65625,-5,.396484375,-4.03125,-.26171875,3.296875,-.068359375,-3.734375,3.75]]],null,[["1643822293",[-.039794921875,.035400390625,.357421875,.041748046875,.0054931640625,-.060791015625,.138671875,-.318359375,.2255859375,.10546875,.2099609375,-.240234375,-.07373046875,-.279296875,-.44140625,.015380859375,-.298828125,.119140625,-.09716796875,.1796875,.04248046875,.09033203125,.38671875,.412109375,-.357421875,.259765625,
+-.24609375,-.3828125,.33984375,.07861328125,-.1259765625,.3046875]],["1643799063",[.0079345703125,.0546875,.353515625,.00958251953125,-.01318359375,-.10888671875,.13671875,-.373046875,.208984375,.09228515625,.1962890625,-.248046875,-.031494140625,-.2734375,-.42578125,.0035400390625,-.345703125,.1083984375,-.068359375,.173828125,.0810546875,.1162109375,.361328125,.451171875,-.3671875,.162109375,-.212890625,-.46484375,.337890625,.1083984375,-.177734375,.318359375]]],null,null,null,null,[[null,[318.3513488769531,
+1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197297","4",[[["1643849995",[3.125,.953125,1.484375,-.46875,2.109375,-.89453125,-1.265625,-3.15625,1.265625,3.421875,1.7578125,1.1796875,4.9375,-.6796875,-1.5234375,.953125,1.7734375,-4.125,-2.453125,3.4375,-2.375,1.6328125,.3984375,-4.375,-4.96875,.59375,-4.03125,-.08935546875,3.34375,.1806640625,-3.8125,3.796875]],["1643804092",[3.125,.90625,1.4609375,-.5,2.046875,-.8671875,
+-1.234375,-3.140625,1.2265625,3.421875,1.71875,1.1328125,4.90625,-.65625,-1.4921875,.921875,1.734375,-4.125,-2.421875,3.46875,-2.34375,1.6015625,.4296875,-4.375,-4.9375,.55078125,-4.03125,-.123046875,3.328125,.1416015625,-3.78125,3.765625]]],null,[["1643822293",[-.060546875,.0185546875,.353515625,.02587890625,.00311279296875,-.07421875,.1533203125,-.3203125,.2470703125,.06689453125,.193359375,-.234375,.029296875,-.255859375,-.44921875,.0146484375,-.306640625,.11962890625,-.10498046875,.1865234375,
+.049072265625,.1162109375,.365234375,.42578125,-.359375,.26953125,-.2490234375,-.392578125,.306640625,.1103515625,-.1376953125,.310546875]],["1643799063",[-.015869140625,.02978515625,.337890625,-.00628662109375,-.0169677734375,-.12353515625,.1494140625,-.373046875,.232421875,.056640625,.1806640625,-.2353515625,.0966796875,-.2451171875,-.43359375,.004180908203125,-.353515625,.107421875,-.087890625,.1865234375,.087890625,.138671875,.345703125,.455078125,-.36328125,.181640625,-.224609375,-.486328125,
+.294921875,.13671875,-.19921875,.3203125]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197300","4",[[["1643849995",[3.109375,.99609375,1.59375,-.4609375,2.171875,-.91015625,-1.296875,-3.3125,1.3984375,3.4375,1.8046875,1.2578125,5.09375,-.7421875,-1.59375,1.0078125,1.8125,-4.1875,-2.578125,3.390625,-2.53125,1.765625,.54296875,-4.71875,-5.09375,.55859375,-4.09375,-.1318359375,
+3.328125,.0654296875,-3.890625,3.859375]],["1643804092",[3.109375,.953125,1.5703125,-.48828125,2.109375,-.88671875,-1.2734375,-3.296875,1.359375,3.4375,1.7734375,1.21875,5.0625,-.71875,-1.5625,.9765625,1.7734375,-4.1875,-2.53125,3.4375,-2.5,1.734375,.5703125,-4.71875,-5.0625,.5234375,-4.0625,-.1591796875,3.328125,.03515625,-3.84375,3.828125]]],null,[["1643822293",[-.048095703125,.0179443359375,.36328125,.033203125,.030029296875,-.07568359375,.15625,-.326171875,.224609375,.07568359375,.1787109375,
+-.234375,-.0277099609375,-.265625,-.412109375,.00909423828125,-.3046875,.11865234375,-.103515625,.1767578125,.048095703125,.12158203125,.36328125,.421875,-.359375,.255859375,-.25,-.396484375,.29296875,.10205078125,-.1279296875,.318359375]],["1643799063",[-.0045166015625,.03173828125,.353515625,.003631591796875,.00927734375,-.126953125,.154296875,-.37890625,.208984375,.06689453125,.1708984375,-.234375,.03173828125,-.255859375,-.396484375,-.00384521484375,-.353515625,.10693359375,-.0830078125,.1708984375,
+.08935546875,.1474609375,.341796875,.44921875,-.3671875,.1669921875,-.224609375,-.482421875,.28125,.130859375,-.1796875,.326171875]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j380357233":[[["52836427830","310927197294","4",[[["1643849995",[4.53125,1.8671875,.13671875,3.3125,-7.5625,.546875,2.953125,-7.90625,4.71875,7.375,.0047607421875,-3.25,.74609375,.298828125,-1.34375,-2.4375,-6.34375,
+-9.1875,-1.3359375,9.875,1.1796875,-3.15625,3.796875,-6.90625,-3.203125,-.09375,-7.65625,-.71875,4.65625,-.75390625,-6.28125,3.6875]],["1643804092",[4.53125,1.9453125,.19140625,3.40625,-7.53125,.52734375,2.9375,-7.9375,4.625,7.375,.01416015625,-3.25,.74609375,.28125,-1.34375,-2.484375,-6.34375,-9.25,-1.328125,9.9375,1.2421875,-3.171875,3.71875,-6.71875,-3.21875,-.0311279296875,-7.71875,-.69140625,4.65625,-.70703125,-6.40625,3.71875]]],null,[["1643822293",[-.09033203125,.037109375,.423828125,.0439453125,
+.0390625,-.04345703125,.162109375,-.3125,.2197265625,.06884765625,.25,-.240234375,-.07763671875,-.267578125,-.416015625,.0150146484375,-.2890625,.126953125,-.08740234375,.158203125,.035888671875,.130859375,.3515625,.412109375,-.38671875,.27734375,-.234375,-.408203125,.337890625,.0458984375,-.1328125,.36328125]],["1643799063",[-.044921875,.056640625,.3984375,.0162353515625,.01373291015625,-.08544921875,.1611328125,-.359375,.1982421875,.06298828125,.2421875,-.2421875,-.05078125,-.263671875,-.39453125,
+.001953125,-.33203125,.11767578125,-.060546875,.1513671875,.07080078125,.14453125,.3359375,.4453125,-.388671875,.1865234375,-.1904296875,-.48046875,.3359375,.0693359375,-.177734375,.37109375]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197297","4",[[["1643849995",[4.4375,1.90625,.20703125,3.125,-7.03125,.44140625,2.703125,-7.46875,4.5,7.1875,.080078125,-3.03125,.94140625,
+.25390625,-1.3203125,-2.25,-5.875,-8.875,-1.375,9.4375,1.0234375,-2.984375,3.453125,-6.46875,-3.171875,.007781982421875,-7.4375,-.62890625,4.5625,-.58984375,-6.125,3.609375]],["1643804092",[4.46875,1.9765625,.26171875,3.1875,-6.9375,.41015625,2.671875,-7.53125,4.375,7.21875,.09716796875,-3.015625,1.0078125,.232421875,-1.3203125,-2.28125,-5.84375,-8.875,-1.3828125,9.5625,1.0859375,-2.96875,3.359375,-6.3125,-3.234375,.06494140625,-7.5,-.6171875,4.5625,-.53125,-6.28125,3.703125]]],null,[["1643822293",
+[-.107421875,.017822265625,.427734375,.0274658203125,.0289306640625,-.05908203125,.17578125,-.31640625,.2373046875,.033447265625,.2470703125,-.23046875,.00579833984375,-.25,-.421875,.01385498046875,-.298828125,.1240234375,-.09912109375,.16796875,.036865234375,.1435546875,.33984375,.4296875,-.380859375,.28515625,-.232421875,-.427734375,.3125,.0654296875,-.1513671875,.373046875]],["1643799063",[-.07177734375,.024658203125,.396484375,-.0016937255859375,.01434326171875,-.11328125,.1748046875,-.3671875,
+.2255859375,.026611328125,.224609375,-.2197265625,.07470703125,-.232421875,-.396484375,.01507568359375,-.341796875,.11376953125,-.087890625,.16015625,.072265625,.173828125,.3203125,.44921875,-.3828125,.19921875,-.2080078125,-.5078125,.28125,.1044921875,-.21484375,.380859375]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["52836427830","310927197300","4",[[["1643849995",[4.5,1.96875,.2099609375,
+3.328125,-7.28125,.458984375,2.8125,-7.84375,4.84375,7.3125,.09814453125,-3.078125,.859375,.224609375,-1.4296875,-2.3125,-6.09375,-9.125,-1.4453125,9.75,1.0078125,-3,3.71875,-6.90625,-3.203125,-.04931640625,-7.5625,-.6328125,4.625,-.69140625,-6.25,3.671875]],["1643804092",[4.5,2.09375,.298828125,3.453125,-7.1875,.416015625,2.765625,-7.90625,4.75,7.3125,.1318359375,-3.046875,.9140625,.17578125,-1.4453125,-2.328125,-6.0625,-9.125,-1.46875,9.75,1.046875,-2.984375,3.59375,-6.6875,-3.25,.041015625,-7.625,
+-.5859375,4.625,-.6171875,-6.40625,3.75]]],null,[["1643822293",[-.09765625,.0216064453125,.421875,.03955078125,.056396484375,-.0546875,.1767578125,-.31640625,.208984375,.04248046875,.2265625,-.2314453125,-.0419921875,-.2578125,-.3828125,.0084228515625,-.29296875,.123046875,-.09423828125,.1533203125,.0380859375,.1474609375,.333984375,.4140625,-.384765625,.275390625,-.232421875,-.4140625,.291015625,.06591796875,-.1337890625,.376953125]],["1643799063",[-.0673828125,.03271484375,.41796875,.01336669921875,
+.041748046875,-.10595703125,.1767578125,-.37109375,.1982421875,.0294189453125,.212890625,-.2275390625,.02880859375,-.248046875,-.361328125,.00909423828125,-.337890625,.115234375,-.0732421875,.14453125,.07080078125,.1875,.310546875,.4453125,-.39453125,.1875,-.203125,-.5078125,.26953125,.095703125,-.1962890625,.40625]]],null,null,null,null,[[null,[318.3513488769531,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149038",
+null,[[["1643849995",[7.875,2.375,-3.078125,9.8125,-20.875,2.46875,9.1875,-18.25,10,13.0625,-1.1171875,-8.875,-6.9375,2.078125,-2.1875,-7.34375,-17.375,-19.375,.640625,21.375,7.0625,-9.875,7.875,-9.5625,-2.09375,.034423828125,-13.4375,-.3359375,8.5625,-.75390625,-11.375,6.15625]],["1643804092",[7.875,2.4375,-3.015625,10,-20.75,2.453125,9.1875,-18.25,9.6875,13,-1.1484375,-8.9375,-6.875,2.078125,-2.125,-7.4375,-17.5,-19.25,.71875,21.25,7.3125,-9.9375,7.65625,-9.125,-2.171875,.1513671875,-13.5625,-.34765625,
+8.5625,-.69921875,-11.6875,6.28125]]],null,[["1643822293",[-.337890625,-.1884765625,.1923828125,-.0213623046875,-.1953125,.5234375,.326171875,.0908203125,-.09033203125,.019775390625,.40234375,.462890625,-.19921875,-.08642578125,-.29296875,-.1943359375,.248046875,-.2470703125,-.2099609375,.2353515625,.0400390625,.1767578125,.828125,-.059326171875,-.0218505859375,.5703125,-.431640625,-.30859375,.19921875,.1455078125,-.486328125,-.2578125]],["1643799063",[-.37109375,-.1455078125,.361328125,-.0595703125,
+-.1611328125,.5234375,.3203125,.07568359375,-.0791015625,.03173828125,.423828125,.4609375,-.2412109375,-.09130859375,-.310546875,-.193359375,.232421875,-.2353515625,-.19140625,.2177734375,.0205078125,.232421875,.8359375,-.04150390625,-.045166015625,.55078125,-.451171875,-.412109375,.298828125,.1220703125,-.56640625,-.11767578125]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038",
+"113383149158",null,[[["1643849995",[8.1875,2.0625,-3.328125,9.5,-21.125,2.609375,9.3125,-17.875,9.5,13.375,-1.2578125,-9.1875,-7,2.265625,-1.9140625,-7.5,-17.625,-19.5,.953125,21.375,7.46875,-10.3125,7.65625,-9.125,-2.265625,.02490234375,-13.75,-.4375,8.8125,-.59765625,-11.4375,6.40625]],["1643804092",[8.125,2.140625,-3.25,9.6875,-21.125,2.59375,9.3125,-17.875,9.25,13.25,-1.25,-9.1875,-6.90625,2.234375,-1.8671875,-7.5625,-17.625,-19.5,1.0078125,21.25,7.625,-10.375,7.5,-8.8125,-2.359375,.1494140625,
+-13.75,-.458984375,8.75,-.5625,-11.6875,6.5]]],null,[["1643822293",[-.349609375,-.19140625,.1767578125,-.0213623046875,-.197265625,.5234375,.330078125,.0927734375,-.0908203125,.027587890625,.3984375,.462890625,-.2001953125,-.0810546875,-.296875,-.19140625,.2490234375,-.244140625,-.2119140625,.2392578125,.0400390625,.181640625,.828125,-.05859375,-.0181884765625,.5703125,-.4296875,-.302734375,.1982421875,.1494140625,-.490234375,-.263671875]],["1643799063",[-.369140625,-.1435546875,.353515625,-.05908203125,
+-.1552734375,.515625,.322265625,.0703125,-.07177734375,.04345703125,.421875,.45703125,-.248046875,-.08935546875,-.30859375,-.1953125,.2255859375,-.2333984375,-.1943359375,.220703125,.021484375,.2431640625,.83984375,-.0419921875,-.04052734375,.54296875,-.443359375,-.41015625,.30078125,.11767578125,-.5703125,-.12158203125]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149518",
+null,[[["1643849995",[7.71875,2.21875,-2.984375,9.3125,-20.25,2.40625,8.875,-17.375,9.5,12.75,-1.1015625,-8.6875,-6.53125,2.03125,-2.03125,-7.09375,-16.875,-18.625,.61328125,20.625,6.84375,-9.625,7.625,-9.3125,-2.140625,-.0341796875,-13.125,-.435546875,8.375,-.8046875,-11.0625,6]],["1643804092",[7.65625,2.328125,-2.875,9.5,-20.125,2.375,8.8125,-17.375,9.3125,12.625,-1.09375,-8.625,-6.46875,1.9921875,-2.015625,-7.125,-16.875,-18.625,.671875,20.5,7,-9.625,7.4375,-8.9375,-2.15625,.1357421875,-13.125,
+-.4140625,8.25,-.73046875,-11.25,6.0625]]],null,[["1643822293",[-.34765625,-.193359375,.208984375,-.025390625,-.201171875,.5234375,.330078125,.09326171875,-.09423828125,.0084228515625,.41015625,.46484375,-.1767578125,-.08251953125,-.310546875,-.19140625,.25,-.24609375,-.212890625,.2392578125,.0380859375,.17578125,.828125,-.0576171875,-.01904296875,.578125,-.43359375,-.31640625,.2060546875,.14453125,-.4921875,-.255859375]],["1643799063",[-.369140625,-.150390625,.37890625,-.0546875,-.1630859375,.53125,
+.3203125,.08251953125,-.08447265625,.01318359375,.43359375,.462890625,-.2392578125,-.09619140625,-.310546875,-.189453125,.2421875,-.2333984375,-.1953125,.2119140625,.0142822265625,.23046875,.83203125,-.0284423828125,-.047119140625,.55078125,-.447265625,-.427734375,.306640625,.115234375,-.57421875,-.107421875]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j395640136":[[["31279674038","113383149038",
+null,[[["1643849995",[3.34375,.197265625,.66015625,-.796875,1.1015625,-.5546875,-.78515625,-2.21875,.84765625,3.390625,1.28125,.482421875,3.9375,-.1865234375,-1.09375,.609375,1.1484375,-4.0625,-1.7890625,4.5625,-1.859375,.83203125,.64453125,-4,-4.09375,.02587890625,-3.734375,-.31640625,3.65625,-.025146484375,-2.5625,3.03125]],["1643804092",[3.34375,.177734375,.6484375,-.8125,1.078125,-.54296875,-.76953125,-2.203125,.81640625,3.40625,1.265625,.462890625,3.9375,-.171875,-1.078125,.59375,1.125,-4.09375,
+-1.7734375,4.59375,-1.8359375,.8203125,.65625,-3.984375,-4.09375,.0101318359375,-3.75,-.33203125,3.671875,-.039794921875,-2.546875,3.015625]]],null,[["1643822293",[-.345703125,-.1962890625,.2109375,-.034912109375,-.2158203125,.5234375,.3359375,.09619140625,-.09326171875,.01385498046875,.427734375,.474609375,-.1806640625,-.0771484375,-.3203125,-.2060546875,.2451171875,-.2578125,-.2177734375,.2490234375,.035888671875,.1513671875,.84375,-.04638671875,-.01220703125,.5703125,-.439453125,-.32421875,.2138671875,
+.1513671875,-.50390625,-.263671875]],["1643799063",[-.3828125,-.1494140625,.384765625,-.058837890625,-.1826171875,.53125,.322265625,.0859375,-.08837890625,.0159912109375,.458984375,.462890625,-.2275390625,-.08984375,-.328125,-.1962890625,.23828125,-.23828125,-.189453125,.22265625,.01556396484375,.2109375,.83203125,-.0238037109375,-.044677734375,.55859375,-.453125,-.43359375,.31640625,.12158203125,-.57421875,-.11328125]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,
+[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149158",null,[[["1643849995",[3.34375,.130859375,.62109375,-.84765625,.98046875,-.453125,-.68359375,-2.03125,.51953125,3.453125,1.140625,.291015625,3.96875,-.15625,-.8828125,.435546875,1.0078125,-4,-1.515625,4.15625,-1.5234375,.62890625,.37890625,-3.421875,-4.21875,.1220703125,-3.84375,-.345703125,3.5625,.10791015625,-2.828125,3.25]],["1643804092",[3.34375,.130859375,.62109375,-.8515625,.98046875,-.451171875,
+-.68359375,-2.03125,.50390625,3.453125,1.1328125,.287109375,3.96875,-.1533203125,-.875,.427734375,1.0078125,-4,-1.5078125,4.15625,-1.515625,.625,.369140625,-3.390625,-4.21875,.1259765625,-3.84375,-.34765625,3.5625,.11181640625,-2.828125,3.25]]],null,[["1643822293",[-.3515625,-.1982421875,.185546875,-.027099609375,-.21875,.5234375,.333984375,.099609375,-.09423828125,.0244140625,.42578125,.47265625,-.1845703125,-.0751953125,-.314453125,-.2001953125,.2470703125,-.25390625,-.216796875,.248046875,.036865234375,
+.1533203125,.83984375,-.044189453125,-.00933837890625,.5703125,-.43359375,-.31640625,.212890625,.15625,-.5,-.275390625]],["1643799063",[-.38671875,-.138671875,.375,-.061767578125,-.177734375,.5234375,.3203125,.07666015625,-.080078125,.033447265625,.4453125,.447265625,-.2333984375,-.09130859375,-.333984375,-.19921875,.2265625,-.2275390625,-.18359375,.2255859375,.02197265625,.2197265625,.828125,-.0189208984375,-.047119140625,.55078125,-.44140625,-.4296875,.328125,.11962890625,-.5703125,-.11572265625]]],
+null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149518",null,[[["1643849995",[3.21875,.1484375,.6796875,-.8203125,1,-.486328125,-.73046875,-2.21875,.77734375,3.3125,1.1875,.419921875,3.875,-.1904296875,-1.015625,.52734375,1.046875,-3.984375,-1.7265625,4.46875,-1.8046875,.828125,.7421875,-4.03125,-4.0625,-.07080078125,-3.671875,-.3984375,3.53125,-.1494140625,-2.515625,2.953125]],
+["1643804092",[3.21875,.1416015625,.671875,-.828125,1,-.486328125,-.73046875,-2.21875,.75390625,3.3125,1.1796875,.416015625,3.890625,-.1796875,-1.015625,.51953125,1.046875,-3.984375,-1.71875,4.5,-1.7890625,.8203125,.73046875,-4,-4.0625,-.06640625,-3.6875,-.3984375,3.53125,-.142578125,-2.53125,2.96875]]],null,[["1643822293",[-.349609375,-.19921875,.2109375,-.03173828125,-.2158203125,.53515625,.333984375,.10400390625,-.11181640625,.00836181640625,.431640625,.4765625,-.16796875,-.07568359375,-.32421875,
+-.201171875,.25390625,-.26171875,-.21875,.251953125,.032958984375,.142578125,.83984375,-.05126953125,-.00836181640625,.58203125,-.439453125,-.31640625,.21875,.1513671875,-.498046875,-.267578125]],["1643799063",[-.376953125,-.1513671875,.38671875,-.061279296875,-.1875,.53125,.322265625,.08642578125,-.08935546875,.01324462890625,.45703125,.462890625,-.224609375,-.08984375,-.333984375,-.19921875,.23828125,-.240234375,-.1962890625,.2197265625,.01519775390625,.2041015625,.8359375,-.0179443359375,-.041748046875,
+.5546875,-.451171875,-.43359375,.3203125,.123046875,-.578125,-.11962890625]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j396781473":[[["31279674038","113383149038",null,[[["1643849995",[3.28125,.37890625,.828125,-.734375,1.3359375,-.625,-.89453125,-2.390625,.7578125,3.40625,1.3515625,.58984375,4.125,-.2734375,-1.125,.6171875,1.2734375,-4.0625,-1.859375,4.3125,-1.84375,.953125,.427734375,
+-3.71875,-4.28125,.2119140625,-3.828125,-.244140625,3.5625,.134765625,-2.9375,3.25]],["1643804092",[3.28125,.345703125,.80859375,-.75390625,1.2890625,-.6015625,-.87109375,-2.375,.72265625,3.40625,1.3203125,.5546875,4.09375,-.255859375,-1.09375,.5859375,1.234375,-4.0625,-1.828125,4.34375,-1.8125,.92578125,.4453125,-3.71875,-4.28125,.185546875,-3.84375,-.267578125,3.5625,.111328125,-2.921875,3.234375]]],null,[["1643822293",[-.32421875,-.203125,.212890625,-.006622314453125,-.224609375,.5234375,.330078125,
+.099609375,-.08203125,-.01239013671875,.41015625,.484375,-.140625,-.0751953125,-.3046875,-.17578125,.251953125,-.25,-.2119140625,.2119140625,.030029296875,.1689453125,.8359375,-.041748046875,-.022216796875,.5546875,-.412109375,-.34375,.1748046875,.1806640625,-.5,-.2470703125]],["1643799063",[-.3359375,-.1572265625,.376953125,-.039306640625,-.1982421875,.515625,.314453125,.076171875,-.0595703125,-.0079345703125,.43359375,.4765625,-.208984375,-.091796875,-.3125,-.1708984375,.23046875,-.23828125,-.1962890625,
+.1787109375,.01556396484375,.220703125,.84375,-.0184326171875,-.052001953125,.51953125,-.4296875,-.458984375,.263671875,.1494140625,-.58203125,-.10498046875]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149158",null,[[["1643849995",[3.328125,.369140625,.8125,-.7578125,1.3125,-.56640625,-.84375,-2.25,.478515625,3.484375,1.2734375,.462890625,4.21875,-.265625,-.96875,.4921875,
+1.2109375,-4.03125,-1.640625,3.875,-1.5546875,.7890625,.10302734375,-3.125,-4.4375,.375,-3.96875,-.2236328125,3.5,.3359375,-3.265625,3.515625]],["1643804092",[3.3125,.349609375,.80078125,-.76953125,1.28125,-.5546875,-.828125,-2.234375,.4453125,3.46875,1.25,.44140625,4.1875,-.251953125,-.94921875,.47265625,1.1875,-4.03125,-1.6171875,3.890625,-1.53125,.76953125,.10888671875,-3.109375,-4.4375,.359375,-3.953125,-.236328125,3.5,.32421875,-3.234375,3.5]]],null,[["1643822293",[-.326171875,-.201171875,.1884765625,
+-.0014190673828125,-.2216796875,.53125,.330078125,.10107421875,-.0849609375,-.00994873046875,.404296875,.4765625,-.1513671875,-.07470703125,-.298828125,-.17578125,.25390625,-.2421875,-.2099609375,.2109375,.0322265625,.1728515625,.83203125,-.0380859375,-.0242919921875,.55859375,-.408203125,-.33984375,.177734375,.18359375,-.494140625,-.25390625]],["1643799063",[-.33984375,-.1474609375,.3515625,-.03466796875,-.1923828125,.5078125,.3125,.0712890625,-.057861328125,.01446533203125,.431640625,.46484375,
+-.2109375,-.0927734375,-.310546875,-.17578125,.220703125,-.2294921875,-.1923828125,.1796875,.023681640625,.2314453125,.83984375,-.0205078125,-.049072265625,.51953125,-.41796875,-.4453125,.2734375,.1513671875,-.57421875,-.115234375]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]],["31279674038","113383149518",null,[[["1643849995",[3.15625,.34765625,.8515625,-.74609375,1.2578125,-.56640625,-.85546875,
+-2.40625,.6953125,3.328125,1.265625,.546875,4.09375,-.283203125,-1.0625,.54296875,1.1953125,-3.984375,-1.8046875,4.1875,-1.796875,.95703125,.5,-3.75,-4.25,.1376953125,-3.78125,-.310546875,3.4375,.03173828125,-2.921875,3.1875]],["1643804092",[3.171875,.322265625,.8359375,-.765625,1.2265625,-.546875,-.8359375,-2.390625,.65625,3.328125,1.2421875,.515625,4.0625,-.265625,-1.0390625,.51953125,1.171875,-3.984375,-1.7734375,4.21875,-1.765625,.93359375,.5,-3.71875,-4.25,.12353515625,-3.78125,-.32421875,3.4375,
+.0242919921875,-2.921875,3.1875]]],null,[["1643822293",[-.32421875,-.21484375,.212890625,-.00543212890625,-.2333984375,.52734375,.333984375,.10498046875,-.08740234375,-.0296630859375,.416015625,.49609375,-.1357421875,-.072265625,-.302734375,-.1728515625,.2578125,-.259765625,-.2177734375,.208984375,.028564453125,.1640625,.83984375,-.042724609375,-.0184326171875,.55859375,-.41796875,-.345703125,.162109375,.185546875,-.5078125,-.25390625]],["1643799063",[-.345703125,-.1650390625,.375,-.041748046875,
+-.1962890625,.51953125,.318359375,.08056640625,-.06396484375,-.004486083984375,.447265625,.486328125,-.197265625,-.0888671875,-.3203125,-.166015625,.234375,-.2431640625,-.2041015625,.1826171875,.01495361328125,.2216796875,.84765625,-.029052734375,-.044921875,.53125,-.431640625,-.4609375,.2578125,.1494140625,-.5859375,-.115234375]]],null,null,null,null,[[null,[176.8618621826172,1],[1,2],[1,1],null,3]]],[null,[[2,0,null,["PubPolicy1"]]]],"608936333",null,null,null,[[2,1,7]],[[2,1,5]]]]],"1j475122041":[[["60795725037",
+"306664789872",null,[[["1643849995",[3.421875,1.78125,1.6796875,.048095703125,2.796875,-1.3984375,-1.703125,-3.5625,1.328125,3.796875,2.265625,1.5,5.125,-.80078125,-1.8515625,1.1796875,2.203125,-4.53125,-2.78125,3.5625,-2.265625,1.6796875,-.76171875,-2.8125,-5.09375,1.5078125,-4.5,.59375,3.609375,1.359375,-4.78125,4.375]],["1643804092",[3.40625,1.75,1.6640625,.0306396484375,2.75,-1.3828125,-1.6875,-3.53125,1.3125,3.78125,2.25,1.4765625,5.09375,-.79296875,-1.828125,1.171875,2.171875,-4.53125,-2.765625,
+3.5625,-2.25,1.6640625,-.73046875,-2.84375,-5.0625,1.4765625,-4.5,.56640625,3.609375,1.3203125,-4.75,4.34375]]],null,[["1643822293",[1.2734375,1.0859375,.298828125,.09619140625,.10107421875,-.09375,-.52734375,-.953125,-.1259765625,-.5078125,-.1611328125,-.498046875,-1.3515625,-.412109375,.94140625,-.33984375,-.578125,.2578125,.47265625,-.478515625,.255859375,-.1005859375,-.06396484375,.166015625,-.9765625,.029541015625,.314453125,.0106201171875,.74609375,-.38671875,.83984375,.75390625]],["1643799063",
+[1.3046875,1.0625,.3828125,.06201171875,.1142578125,-.046875,-.52734375,-.94921875,-.134765625,-.56640625,-.08740234375,-.439453125,-1.3671875,-.4296875,1.046875,-.33203125,-.5625,.2734375,.50390625,-.54296875,.1728515625,-.123046875,-.0233154296875,.1962890625,-1.0546875,.05859375,.318359375,-.0537109375,.8125,-.423828125,.79296875,.953125]]],null,null,null,null,[[null,[61170.82421875,1],[1,2],[1,1],null,3]]],[null,[[3,0,null,["AdvControlbrand-unsafe"]]]],"1614272341"]]]};function tb(a,b){return!b||0>=b?a:Math.min(a,b)}function T(a,b,c){return b?b:c?c:a?1:0}function ub(a){a=null==a?void 0:I(a,9,0);return void 0===a?!1:[61,51,52].includes(a)};var U=function(a){S.call(this,a,-1,vb)};t(U,S);var vb=[2];var wb=function(a){S.call(this,a)};t(wb,S);var yb=function(a){S.call(this,a,-1,xb)};t(yb,S);yb.prototype.ca=function(){return O(this,wb,3)};var xb=[2,3];var Ab=function(a){S.call(this,a,-1,zb)};t(Ab,S);var Cb=function(a){S.call(this,a,-1,Bb)};t(Cb,S);var Eb=function(a){S.call(this,a,-1,Db)};t(Eb,S);Eb.prototype.ca=function(){return O(this,wb,5)};var zb=[1,2],Bb=[3,4],Db=[3,4,5];var Gb=function(a){S.call(this,a,-1,Fb)};t(Gb,S);var W=function(a){return N(a,Hb,3)},Jb=function(a){S.call(this,a,-1,Ib)};t(Jb,S);Jb.prototype.Y=function(){return O(this,U,2)};Jb.prototype.ma=function(){return O(this,U,3)};var Kb=function(a){S.call(this,a)};t(Kb,S);Kb.prototype.u=function(){return P(this,1)};Kb.prototype.v=function(){return P(this,2)};Kb.prototype.da=function(){return L(this,3)};var Hb=function(a){S.call(this,a)};t(Hb,S);var X=function(a){S.call(this,a)};t(X,S);
+var Y=function(a){S.call(this,a)};t(Y,S);var Nb=function(a){var b=new Y;return M(b,1,a)},Z=function(a){S.call(this,a)};t(Z,S);Z.prototype.u=function(){return P(this,2)};Z.prototype.v=function(){return P(this,3)};Z.prototype.W=function(){return P(this,4)};Z.prototype.da=function(){return L(this,5)};var Fb=[2],Ib=[1,2,3];function Ob(a,b,c){if(!b||0>=b)return{l:0,P:1};var d=T(!0,null==a?void 0:L(a,1),null==c?void 0:L(c,1)),e=T(!1,null==a?void 0:L(a,2),null==c?void 0:L(c,2)),g=T(!1,null==a?void 0:L(a,3),null==c?void 0:L(c,3)),f,h;a=T(!1,null==a?void 0:null==(f=N(a,Y,5))?void 0:L(f,1),null==c?void 0:null==(h=N(c,Y,5))?void 0:L(h,1));c=new X;f=M(c,1,d);f=M(f,2,e);f=M(f,3,g);h=Nb(a);cb(f,Y,5,h);return{l:b*d*(1-1/(1+Math.exp(-e*(Math.log(b/1E6)-a-g)))),P:4,sa:c}};function Pb(a,b){var c=null==a?void 0:N(a,X,6),d,e=null==a?void 0:null==(d=W(a))?void 0:N(d,X,3);if(!b||0>=b)return{l:0,P:1};var g;if(!(null==a?0:null==(g=W(a))?0:J(g,2)))return{l:.85*b,P:2};d=T(!0,null==c?void 0:L(c,4),null==e?void 0:L(e,4));g=T(!0,null==c?void 0:L(c,1),null==e?void 0:L(e,1));var f=T(!1,null==c?void 0:L(c,2),null==e?void 0:L(e,2)),h=T(!1,null==c?void 0:L(c,3),null==e?void 0:L(e,3)),k,l;c=T(!1,null==c?void 0:null==(k=N(c,Y,5))?void 0:L(k,1),null==e?void 0:null==(l=N(e,Y,5))?void 0:
+L(l,1));k=new X;l=M(k,1,g);l=M(l,2,f);l=M(l,3,h);l=M(l,4,d);var m=Nb(c);cb(l,Y,5,m);d=d*b*g*(1-1/(1+Math.exp(-f*(Math.log(d*b/1E6)-c-h))));g=1E6*(null==a?NaN:L(a,8));var p;if((null==a?0:null==(p=W(a))?0:J(p,6))&&d<g&&g<b){var y;d=g+1E6*(null!=(y=null==e?void 0:L(e,7))?y:0)*Math.log(b/g)}return{l:d,P:3,sa:k}};function Qb(a,b){if(!(0<G(a,2).length&&G(a,2).length===F(a,3).length&&G(a,2).length===G(a,4).length))return 0;for(var c=0,d=0,e=1,g=r(F(a,3)),f=g.next();!f.done;f=g.next()){var h=0;switch(f.value){case 1:h=G(a,2)[d]*(b.ea?Math.pow(b.ea,G(a,4)[d]):0);break;case 2:c=h=G(a,2)[d]*(b.oa?Math.pow(b.oa,G(a,4)[d]):0);break;case 3:h=G(a,2)[d]}if(0===h)return 0;e*=h;d+=1}0<L(a,7)&&(e=Math.min(e,L(a,7)*c*1E3));return 1E6*e}
+function Rb(a,b){var c=0;b&&(0<O(b,Sb,7).length?c=Qb(O(b,Sb,7)[0],a):0<O(b,Sb,8).length&&(c=Qb(O(b,Sb,8)[0],a)));return c};function Tb(a,b,c){if(I(a,2,0)!==I(b,2,0))return c;var d=!1;switch(I(a,2,0)){case 1:a:{var e,g=new Set(null!=(e=F(a,3))?e:[]);b=r(F(b,3));for(e=b.next();!e.done;e=b.next())if(g.has(e.value)){d=!0;break a}d=!1}break;case 0:a:{e=new Set(null!=(g=F(a,4))?g:[]);b=r(F(b,4));for(g=b.next();!g.done;g=b.next())if(e.has(g.value)){d=!0;break a}d=!1}break;case 2:b=new Ub(b),d=(e=N(a,yb,5))?Vb(b,e):!1}return J(a,6)?d?null:c:d?c:null}
+function Vb(a,b){var c=I(b,1,0),d=b.ca(),e=O(b,yb,2);switch(c){case 2:c=d.every(function(g){return Wb(a,g)})&&e.every(function(g){return Vb(a,g)});break;case 1:c=d.some(function(g){return Wb(a,g)})||e.some(function(g){return Vb(a,g)});break;default:throw Error("unexpected value "+c+"!");}return J(b,4)?!c:c}
+var Ub=function(a){this.ga=new Map;a=r(a.ca());for(var b=a.next();!b.done;b=a.next()){var c=b.value;b=I(c,1,0);c=I(c,2,0);var d=this.ga.get(b);d||(d=new Set,this.ga.set(b,d));d.add(c)}},Wb=function(a,b){var c=I(b,2,0);return(a=a.ga.get(I(b,1,0)))?a.has(c):!1};function Xb(a,b){a=r((null==b?void 0:b.get(a))||[]);for(b=a.next();!b.done;b=a.next())if(b=b.value,b.count+1>b.xa)return!1;return!0};function Yb(a,b){return null==a.na?!0:!a.na.some(function(c){var d;return null==(d=b.Ba)?void 0:d.includes(c,0)})};var Zb=function(a){S.call(this,a)};t(Zb,S);n=Zb.prototype;n.u=function(){return P(this,1)};n.v=function(){return P(this,2)};n.W=function(){return P(this,3)};n.V=function(){return P(this,4)};n.U=function(){return P(this,5)};n.X=function(){return P(this,6)};var ac=function(a){S.call(this,a,-1,$b)};t(ac,S);var $b=[1];function bc(a,b){var c=!0;c=void 0===c?!1:c;return cc(0,(null==a?void 0:O(a,U,1))||[],(null==b?void 0:O(b,U,1))||[],c)}function dc(a,b){var c=!0;c=void 0===c?!1:c;return cc(1,(null==a?void 0:a.Y())||[],(null==b?void 0:b.Y())||[],c)}function ec(a,b){var c=!0;c=void 0===c?!1:c;return cc(1,(null==a?void 0:a.ma())||[],(null==b?void 0:b.Y())||[],c)}
+function cc(a,b,c,d){var e=0,g=new Map;b=r(b);for(var f=b.next();!f.done;f=b.next())e=f.value,g.set(I(e,1,""),e),e=L(e,3);b=null;c=r(c);for(f=c.next();!f.done;f=c.next()){var h=f.value;e=L(h,3);if(f=d?g.values().next().value:g.get(I(h,1,""))){a:{b=a;f=G(f,2);h=G(h,2);if(f.length===h.length){for(var k=0,l=0;l<f.length;l++)k+=f[l]*h[l];f=k}else f=void 0;if(void 0!==f)switch(b){case 0:b=1/(1+Math.exp(-1*f));break a;case 1:b=Math.exp(f);break a}b=void 0}if(void 0!==b)return b;b=e}}var m;return null!=
+(m=b)?m:e};var fc=function(a){S.call(this,a)};t(fc,S);function gc(a,b,c){"0"===a||c.has(a)||c.set(a,b.filter(function(d){return 0<I(d,3,0)}).map(function(d){var e=I(d,3,0);switch(I(d,1,0)){case 6:d=60*I(d,2,0);break;case 1:d=3600*I(d,2,0);break;case 2:d=86400*I(d,2,0);break;case 3:d=604800*I(d,2,0);break;case 4:d=2592E3*I(d,2,0);break;case 5:d=null;break;default:e=d=0}return{pa:d,xa:e,count:0}}))}function hc(a,b,c){if(b=c.get(b))for(b=r(b),c=b.next();!c.done;c=b.next())c=c.value,(null===c.pa||a.Aa<=c.pa)&&c.count++};var Sb=function(a){S.call(this,a,-1,ic)};t(Sb,S);var ic=[2,3,4];var kc=function(a){S.call(this,a,-1,jc)};t(kc,S);kc.prototype.Y=function(){return O(this,U,3)};kc.prototype.ma=function(){return O(this,U,10)};var jc=[1,3,10,7,8];var mc=function(a){S.call(this,a,-1,lc)};t(mc,S);n=mc.prototype;n.u=function(){return P(this,1)};n.v=function(){return P(this,2)};n.W=function(){return P(this,3)};n.V=function(){return P(this,6)};n.U=function(){return P(this,7)};n.X=function(){return P(this,8)};var lc=[9,10,11,12,13,14];var oc=function(a){S.call(this,a,-1,nc)};t(oc,S);var nc=[1];var qc=function(a){S.call(this,a,-1,pc)};t(qc,S);var pc=[1];var rc={ad:{},bid:0,render:""};function sc(){new qc;return function(a,b,c,d,e){return tc(a,c,d,e)}}
+function tc(a,b,c,d){b=b?new Gb(nb(b)):void 0;var e,g;if(!b||!(O(b,Kb,2).length||(null==(e=W(b))?0:J(e,1))||(null==(g=W(b))?0:J(g,5))))return rc;e=new ac(nb(a.userBiddingSignals));g=a.ads.map(function(f){return{renderUrl:f.renderUrl,metadata:new Zb(nb(f.metadata))}});c=c[a.name]?new oc(nb(c[a.name])):void 0;d=d.prevWins.map(function(f){return{Aa:f[0],I:new Zb(nb(f[1].metadata))}});return uc(a.name,e,g,d,c,b)}
+function uc(a,b,c,d,e,g){var f,h={Ja:null!=(f=null==g?void 0:W(g))?f:void 0,T:new Map,O:new Map,R:new Map,S:new Map,Z:new Map,interestGroupName:null!=a?a:void 0};a=new Map;if(e){e=r(O(e,mc,1));for(f=e.next();!f.done;f=e.next())f=f.value,a.set(f.u().concat("+",f.v(),"+",f.W()),f),gc(f.v(),O(f,fc,9),h.T),gc(f.u(),O(f,fc,10),h.O),gc(f.V(),O(f,fc,11),h.R),gc(f.U(),O(f,fc,12),h.S),gc(f.X(),O(f,fc,13),h.Z);d=r(d);for(e=d.next();!e.done;e=d.next())e=e.value,h.T&&hc(e,e.I.v(),h.T),h.O&&hc(e,e.I.u(),h.O),
+h.R&&hc(e,e.I.V(),h.R),h.S&&hc(e,e.I.U(),h.S),h.Z&&hc(e,e.I.X(),h.Z)}e=new Map;if(g)for(d=r(O(g,Kb,2)),f=d.next();!f.done;f=d.next())f=f.value,e.set(f.u().concat("+",f.v(),"+",""),f.da());d=[];c=r(c);for(f=c.next();!f.done;f=c.next()){f=f.value;f={renderUrl:f.renderUrl,H:f.metadata.u(),K:f.metadata.v(),ka:f.metadata.W(),ja:f.metadata.V(),ia:f.metadata.U(),la:f.metadata.X(),i:0,J:0};var k=f.H.concat("+",f.K,"+",f.ka);f.aa=e.get(f.H.concat("+",f.K,"+",""));if(!f.aa){var l=void 0,m=void 0,p=void 0,y=
+void 0;if(!(null==(l=g)?0:null==(m=W(l))?0:J(m,1))&&!(null==(p=g)?0:null==(y=W(p))?0:J(y,5)))continue;else if(!a.get(k))continue;m=l=void 0;f.o=null!=(m=null==(l=a.get(k))?void 0:N(l,kc,4))?m:void 0}m=l=void 0;f.ha=null!=(m=null==(l=a.get(k))?void 0:N(l,Ab,5))?m:void 0;m=l=void 0;f.na=null!=(m=null==(l=a.get(k))?void 0:F(l,14))?m:void 0;d.push(f)}if(c=null==g?void 0:N(g,Ab,5)){a=new Map;e=new Map;f=r(O(c,Cb,1));for(k=f.next();!k.done;k=f.next())k=k.value,a.set(I(k,1,0),k);c=r(O(c,Eb,2));for(f=c.next();!f.done;f=
+c.next())f=f.value,e.set(I(f,1,0),f);h.ta=a;h.ua=e}var H;h.Ba=null!=(H=F(b,1))?H:void 0;b=[];H=new Map;a=r(d);for(d=a.next();!d.done;d=a.next())if(d=d.value,e=h,!(!Xb(d.K,e.T)||!Xb(d.H,e.O)||d.ja&&!Xb(d.ja,e.R)||d.ia&&!Xb(d.ia,e.S)||d.la&&!Xb(d.la,e.Z))){if(d.ha){c=h;e=c.ta;c=c.ua;f=d.ha;if(e&&c&&f)a:{k=r(O(f,Cb,1));for(l=k.next();!l.done;l=k.next()){p=l.value;y=I(p,1,0);var da=c.get(y);if(da){if(J(p,7)){l=H.get(y);m=I(p,8,0);if(void 0===l)l=new Map,H.set(y,l);else{var na=l.get(m);if(void 0!==na){e=
+na;break a}}p=Tb(p,da,y);l.set(m,p)}else p=Tb(p,da,y);if(p){e=p;break a}}}c=r(O(f,Eb,2));for(f=c.next();!f.done;f=c.next())if(f=f.value,k=I(f,1,0),l=e.get(k))if(f=Tb(l,f,k)){e=f;break a}e=null}else e=null;if(e)continue}Yb(d,h)&&b.push(d)}return vc({ads:b,ya:h},g).bidResponse}
+function vc(a,b){for(var c=[],d=[],e=r(a.ads),g=e.next();!g.done;g=e.next()){g=g.value;var f=void 0,h=void 0;if(null==(f=b)?0:null==(h=W(f))?0:J(h,7)){var k=h=f=void 0,l=void 0,m=void 0,p=void 0;g.H===(null==(f=b)?void 0:null==(h=N(f,Z,16))?void 0:h.u())&&g.K===(null==(k=b)?void 0:null==(l=N(k,Z,16))?void 0:l.v())&&a.ya.interestGroupName===(null==(m=b)?void 0:null==(p=N(m,Z,16))?void 0:I(p,1,""))?(k=h=f=void 0,l=null!=(k=null==(f=b)?void 0:null==(h=N(f,Z,16))?void 0:h.da())?k:0,g.i=0===l?1E9:l):g.i=
+0}else if(null!=g.aa){g.i=g.aa;c.push(g);continue}else if(h=f=void 0,null==(f=b)?0:null==(h=W(f))?0:J(h,1))ub(g.o)?(f=void 0,g.ea=ec(null==(f=b)?void 0:N(f,Jb,1),g.o)):(f=void 0,g.oa=bc(null==(f=b)?void 0:N(f,Jb,1),g.o),f=void 0,g.ea=dc(null==(f=b)?void 0:N(f,Jb,1),g.o)),g.i=Rb(g,g.o),g.i||(h=f=void 0,g.i=null!=(h=null==(f=g.o)?void 0:L(f,6))?h:0);else if(h=f=void 0,null==(f=b)?0:null==(h=W(f))?0:J(h,5))h=f=void 0,g.i=null!=(h=null==(f=g.o)?void 0:L(f,6))?h:0;d.push(g)}c={renderUrl:"",H:"",K:"",ka:"",
+i:0,J:0};var y;if(null==b?0:null==(y=W(b))?0:J(y,7))b=a.ads.reduce(function(V,K){return V.i<K.i?K:V},c),b.J=b.i;else{y=a.ads.reduce(function(V,K){return!ub(K.o)&&V.i<K.i?K:V},c);c=a.ads.reduce(function(V,K){return ub(K.o)&&V.i<K.i?K:V},c);a=Pb(b,null==y?void 0:y.i);var H,da;a.l=tb(a.l,null==b?void 0:null==(H=W(b))?void 0:null==(da=N(H,X,3))?void 0:L(da,6));var na;H=Ob(null==b?void 0:N(b,X,7),null==c?void 0:c.i,null==b?void 0:null==(na=W(b))?void 0:N(na,X,4));var Lb,Mb;H.l=tb(H.l,null==b?void 0:null==
+(Lb=W(b))?void 0:null==(Mb=N(Lb,X,4))?void 0:L(Mb,6));a.l>H.l?(b=y,b.J=a.l):(b=c,b.J=H.l)}return{bidResponse:{ad:{},bid:b.J,render:b.renderUrl},debugInfo:void 0}};var wc=function(a){var b={maxFloorCpmUsdMicros:"6250"},c={topWindowHostname:"www.cnn.com",seller:"https://pubads.g.doubleclick.net",joinCount:7,bidCount:0,prevWins:[]},d=sc();return function(){return d(a,b,rb,sb,c)}};
+
+function generateBid(interestGroups){for(var a=[],b=Date.now(),c=r(interestGroups),d=c.next();!d.done;d=c.next()){var e={generateBidTime:0,success:!1},g=wc(d.value);d=Date.now();g=g();e.generateBidTime=Date.now()-d;e.success=JSON.stringify(g)===JSON.stringify({ad:{},bid:2937687.988333709,render:"https://googleads.g.doubleclick.net/ads/simple-ad.html?adg_id=52836427830&cr_id=310927197294&cv_id=4"});e.bidResponse=g;a.push(e)}a.push({generateBidTime:Date.now()-b,success:!0});return a;}
diff --git a/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java b/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
index ac36ac2bcdcc..bf9ff3a47c40 100644
--- a/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
+++ b/apct-tests/perftests/rubidium/src/android/rubidium/js/JSScriptEnginePerfTests.java
@@ -16,49 +16,77 @@
package android.rubidium.js;
+import static com.android.adservices.service.js.JSScriptArgument.arrayArg;
import static com.android.adservices.service.js.JSScriptArgument.numericArg;
import static com.android.adservices.service.js.JSScriptArgument.recordArg;
import static com.android.adservices.service.js.JSScriptArgument.stringArg;
+import static com.android.adservices.service.js.JSScriptArgument.stringArrayArg;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.LargeTest;
+import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.adservices.service.js.JSScriptArgument;
+import com.android.adservices.service.js.JSScriptArrayArgument;
import com.android.adservices.service.js.JSScriptEngine;
+import com.android.adservices.service.js.JSScriptRecordArgument;
+import com.android.adservices.service.profiling.JSScriptEngineLogConstants;
+import com.android.adservices.service.profiling.Profiler;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
+import org.json.JSONArray;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-@LargeTest
+/** To run the unit tests for this class, run "atest RubidiumPerfTests:JSScriptEnginePerfTests" */
+@MediumTest
@RunWith(AndroidJUnit4.class)
public class JSScriptEnginePerfTests {
private static final String TAG = JSScriptEnginePerfTests.class.getSimpleName();
- protected static final Context sContext = ApplicationProvider.getApplicationContext();
- private final ExecutorService mExecutorService = Executors.newFixedThreadPool(10);
- private final JSScriptEngine mJSScriptEngine = new JSScriptEngine(sContext);
+ private static final Context sContext = ApplicationProvider.getApplicationContext();
+ private static final ExecutorService sExecutorService = Executors.newFixedThreadPool(10);
+
+ private static JSScriptEngine sJSScriptEngine;
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+ @Before
+ public void before() throws Exception {
+ Profiler profiler = Profiler.createInstance(JSScriptEngine.TAG);
+ sJSScriptEngine = JSScriptEngine.getInstanceForTesting(sContext, profiler);
+
+ // Warm up the sandbox env.
+ callJSEngine(
+ "function test() { return \"hello world\";" + " }", ImmutableList.of(), "test");
+ }
+
+ @After
+ public void after() {
+ sJSScriptEngine.shutdown();
+ }
+
@Test
public void evaluate_helloWorld() throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
@@ -88,8 +116,7 @@ public class JSScriptEnginePerfTests {
state.resumeTiming();
while (state.keepRunning()) {
- callJSEngine(
- jsTestFile, ImmutableList.of(adDataArgument), "generateBid");
+ callJSEngine(jsTestFile, ImmutableList.of(adDataArgument), "generateBid");
}
}
@@ -99,8 +126,7 @@ public class JSScriptEnginePerfTests {
state.pauseTiming();
InputStream testJsInputStream = sContext.getAssets().open("turtledove_generate_bid.js");
- String jsTestFile =
- new String(testJsInputStream.readAllBytes(), StandardCharsets.UTF_8);
+ String jsTestFile = new String(testJsInputStream.readAllBytes(), StandardCharsets.UTF_8);
// Initialize the environment with one call.
callJSEngine(jsTestFile, ImmutableList.of(), "generateBid");
@@ -110,15 +136,99 @@ public class JSScriptEnginePerfTests {
}
}
- private String callJSEngine(
+ @Test
+ public void evaluate_turtledoveSampleGenerateBid_parametrized_10Ads() throws Exception {
+ runParametrizedTurtledoveScript(10);
+ }
+
+ @Test
+ public void evaluate_turtledoveSampleGenerateBid_parametrized_25Ads() throws Exception {
+ runParametrizedTurtledoveScript(25);
+ }
+
+ @Test
+ public void evaluate_turtledoveSampleGenerateBid_parametrized_50Ads() throws Exception {
+ runParametrizedTurtledoveScript(50);
+ }
+
+ @Test
+ public void evaluate_turtledoveSampleGenerateBid_parametrized_75Ads() throws Exception {
+ runParametrizedTurtledoveScript(75);
+ }
+
+ private void runParametrizedTurtledoveScript(int numAds) throws Exception {
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ state.pauseTiming();
+ InputStream testJsInputStream =
+ sContext.getAssets().open("turtledove_parametrized_generateBid.js");
+ String jsTestFile = new String(testJsInputStream.readAllBytes(), StandardCharsets.UTF_8);
+
+ state.resumeTiming();
+ while (state.keepRunning()) {
+ int numInterestGroups = 1;
+ String res =
+ callJSEngine(
+ sJSScriptEngine,
+ jsTestFile,
+ ImmutableList.of(
+ buildSampleInterestGroupArg(numInterestGroups, numAds)),
+ "generateBid");
+
+ // I modified the Turtledove script to have the total execution time
+ // (across all IGs) as the last element in the response array.
+ JSONArray obj = new JSONArray(res);
+ long webviewExecTime = obj.getJSONObject(obj.length() - 1).getLong("generateBidTime");
+ String webviewExecTimeLog =
+ String.format(
+ "(%s: %d)",
+ JSScriptEngineLogConstants.WEBVIEW_EXECUTION_TIME, webviewExecTime);
+ // The listener picks up logs from JSScriptEngine, so simulate logging from there.
+ Log.d("JSScriptEngine", webviewExecTimeLog);
+ }
+ }
+
+ private JSScriptArrayArgument<JSScriptRecordArgument> buildSampleInterestGroupArg(
+ int numCustomAudiences, int numAds) {
+ JSScriptRecordArgument ad =
+ recordArg(
+ "foo",
+ ImmutableList.of(
+ stringArg(
+ "renderUrl",
+ "https://googleads.g.doubleclick.net/ads/simple-ad.html?adg_id=52836427830&cr_id=310927197297&cv_id=4"),
+ stringArrayArg(
+ "metadata",
+ ImmutableList.of(
+ "52836427830", "310927197297", "4", "608936333"))));
+
+ JSScriptRecordArgument interestGroupArg =
+ recordArg(
+ "foo",
+ stringArg("owner", "https://googleads.g.doubleclick.net/"),
+ stringArg("name", "1j115753478"),
+ stringArg("biddingLogicUrl", "https://googleads.g.doubleclick.net/td/bjs"),
+ stringArg(
+ "dailyUpdateUrl", "https://googleads.g.doubleclick.net/td/update"),
+ stringArg(
+ "trustedBiddingSignalsUrl",
+ "https://googleads.g.doubleclick.net/td/sjs"),
+ stringArrayArg(
+ "trustedBiddingSignalsKeys", ImmutableList.of("1j115753478")),
+ stringArrayArg("userBiddingSignals", ImmutableList.of()),
+ new JSScriptArrayArgument("ads", Collections.nCopies(numAds, ad)));
+
+ return arrayArg("foo", Collections.nCopies(numCustomAudiences, interestGroupArg));
+ }
+
+ private static String callJSEngine(
@NonNull String jsScript,
@NonNull List<JSScriptArgument> args,
@NonNull String functionName)
throws Exception {
- return callJSEngine(mJSScriptEngine, jsScript, args, functionName);
+ return callJSEngine(sJSScriptEngine, jsScript, args, functionName);
}
- private String callJSEngine(
+ private static String callJSEngine(
@NonNull JSScriptEngine jsScriptEngine,
@NonNull String jsScript,
@NonNull List<JSScriptArgument> args,
@@ -131,15 +241,15 @@ public class JSScriptEnginePerfTests {
return futureResult.get();
}
- private ListenableFuture<String> callJSEngineAsync(
+ private static ListenableFuture<String> callJSEngineAsync(
@NonNull String jsScript,
@NonNull List<JSScriptArgument> args,
@NonNull String functionName,
@NonNull CountDownLatch resultLatch) {
- return callJSEngineAsync(mJSScriptEngine, jsScript, args, functionName, resultLatch);
+ return callJSEngineAsync(sJSScriptEngine, jsScript, args, functionName, resultLatch);
}
- private ListenableFuture<String> callJSEngineAsync(
+ private static ListenableFuture<String> callJSEngineAsync(
@NonNull JSScriptEngine engine,
@NonNull String jsScript,
@NonNull List<JSScriptArgument> args,
@@ -148,7 +258,7 @@ public class JSScriptEnginePerfTests {
Objects.requireNonNull(engine);
Objects.requireNonNull(resultLatch);
ListenableFuture<String> result = engine.evaluate(jsScript, args, functionName);
- result.addListener(resultLatch::countDown, mExecutorService);
+ result.addListener(resultLatch::countDown, sExecutorService);
return result;
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index c053b2ed5adb..92068e516207 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -673,9 +673,6 @@ public class AlarmManagerService extends SystemService {
private static final String KEY_APP_STANDBY_RESTRICTED_WINDOW =
"app_standby_restricted_window";
- @VisibleForTesting
- static final String KEY_LAZY_BATCHING = "lazy_batching";
-
private static final String KEY_TIME_TICK_ALLOWED_WHILE_IDLE =
"time_tick_allowed_while_idle";
@@ -725,7 +722,6 @@ public class AlarmManagerService extends SystemService {
private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1;
private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = INTERVAL_DAY;
- private static final boolean DEFAULT_LAZY_BATCHING = true;
private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true;
/**
@@ -772,7 +768,6 @@ public class AlarmManagerService extends SystemService {
public int APP_STANDBY_RESTRICTED_QUOTA = DEFAULT_APP_STANDBY_RESTRICTED_QUOTA;
public long APP_STANDBY_RESTRICTED_WINDOW = DEFAULT_APP_STANDBY_RESTRICTED_WINDOW;
- public boolean LAZY_BATCHING = DEFAULT_LAZY_BATCHING;
public boolean TIME_TICK_ALLOWED_WHILE_IDLE = DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE;
public int ALLOW_WHILE_IDLE_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_QUOTA;
@@ -976,14 +971,6 @@ public class AlarmManagerService extends SystemService {
case KEY_APP_STANDBY_RESTRICTED_WINDOW:
updateStandbyWindowsLocked();
break;
- case KEY_LAZY_BATCHING:
- final boolean oldLazyBatching = LAZY_BATCHING;
- LAZY_BATCHING = properties.getBoolean(
- KEY_LAZY_BATCHING, DEFAULT_LAZY_BATCHING);
- if (oldLazyBatching != LAZY_BATCHING) {
- migrateAlarmsToNewStoreLocked();
- }
- break;
case KEY_TIME_TICK_ALLOWED_WHILE_IDLE:
TIME_TICK_ALLOWED_WHILE_IDLE = properties.getBoolean(
KEY_TIME_TICK_ALLOWED_WHILE_IDLE,
@@ -1094,15 +1081,6 @@ public class AlarmManagerService extends SystemService {
}
}
- private void migrateAlarmsToNewStoreLocked() {
- final AlarmStore newStore = LAZY_BATCHING ? new LazyAlarmStore()
- : new BatchingAlarmStore();
- final ArrayList<Alarm> allAlarms = mAlarmStore.remove((unused) -> true);
- newStore.addAll(allAlarms);
- mAlarmStore = newStore;
- mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
- }
-
private void updateDeviceIdleFuzzBoundaries() {
final DeviceConfig.Properties properties = DeviceConfig.getProperties(
DeviceConfig.NAMESPACE_ALARM_MANAGER,
@@ -1240,9 +1218,6 @@ public class AlarmManagerService extends SystemService {
TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw);
pw.println();
- pw.print(KEY_LAZY_BATCHING, LAZY_BATCHING);
- pw.println();
-
pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE);
pw.println();
@@ -1878,8 +1853,7 @@ public class AlarmManagerService extends SystemService {
mHandler = new AlarmHandler();
mConstants = new Constants(mHandler);
- mAlarmStore = mConstants.LAZY_BATCHING ? new LazyAlarmStore()
- : new BatchingAlarmStore();
+ mAlarmStore = new LazyAlarmStore();
mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
deleted file mode 100644
index 1a4efb8ffcd9..000000000000
--- a/apex/jobscheduler/service/java/com/android/server/alarm/BatchingAlarmStore.java
+++ /dev/null
@@ -1,408 +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.alarm;
-
-import static com.android.server.alarm.AlarmManagerService.DEBUG_BATCH;
-import static com.android.server.alarm.AlarmManagerService.clampPositive;
-import static com.android.server.alarm.AlarmManagerService.dumpAlarmList;
-import static com.android.server.alarm.AlarmManagerService.isTimeTickAlarm;
-
-import android.app.AlarmManager;
-import android.util.IndentingPrintWriter;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.StatLogger;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.function.Predicate;
-
-/**
- * Batching implementation of an Alarm Store.
- * This keeps the alarms in batches, which are sorted on the start time of their delivery window.
- */
-public class BatchingAlarmStore implements AlarmStore {
- @VisibleForTesting
- static final String TAG = BatchingAlarmStore.class.getSimpleName();
-
- private final ArrayList<Batch> mAlarmBatches = new ArrayList<>();
- private int mSize;
- private Runnable mOnAlarmClockRemoved;
-
- interface Stats {
- int REBATCH_ALL_ALARMS = 0;
- int GET_COUNT = 1;
- }
-
- final StatLogger mStatLogger = new StatLogger(TAG + " stats", new String[]{
- "REBATCH_ALL_ALARMS",
- "GET_COUNT",
- });
-
- private static final Comparator<Batch> sBatchOrder = Comparator.comparingLong(b -> b.mStart);
-
- private static final Comparator<Alarm> sIncreasingTimeOrder = Comparator.comparingLong(
- Alarm::getWhenElapsed);
-
- @Override
- public void add(Alarm a) {
- insertAndBatchAlarm(a);
- mSize++;
- }
-
- @Override
- public void addAll(ArrayList<Alarm> alarms) {
- if (alarms == null) {
- return;
- }
- for (final Alarm a : alarms) {
- add(a);
- }
- }
-
- @Override
- public ArrayList<Alarm> remove(Predicate<Alarm> whichAlarms) {
- final ArrayList<Alarm> removed = new ArrayList<>();
- for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
- final Batch b = mAlarmBatches.get(i);
- removed.addAll(b.remove(whichAlarms));
- if (b.size() == 0) {
- mAlarmBatches.remove(i);
- }
- }
- if (!removed.isEmpty()) {
- mSize -= removed.size();
- // Not needed if only whole batches were removed, but keeping existing behavior.
- rebatchAllAlarms();
- }
- return removed;
- }
-
- @Override
- public void setAlarmClockRemovalListener(Runnable listener) {
- mOnAlarmClockRemoved = listener;
- }
-
- @Override
- public Alarm getNextWakeFromIdleAlarm() {
- for (final Batch batch : mAlarmBatches) {
- if ((batch.mFlags & AlarmManager.FLAG_WAKE_FROM_IDLE) == 0) {
- continue;
- }
- for (int i = 0; i < batch.size(); i++) {
- final Alarm a = batch.get(i);
- if ((a.flags & AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
- return a;
- }
- }
- }
- return null;
- }
-
- private void rebatchAllAlarms() {
- final long start = mStatLogger.getTime();
- final ArrayList<Batch> oldBatches = (ArrayList<Batch>) mAlarmBatches.clone();
- mAlarmBatches.clear();
- for (final Batch batch : oldBatches) {
- for (int i = 0; i < batch.size(); i++) {
- insertAndBatchAlarm(batch.get(i));
- }
- }
- mStatLogger.logDurationStat(Stats.REBATCH_ALL_ALARMS, start);
- }
-
- @Override
- public int size() {
- return mSize;
- }
-
- @Override
- public long getNextWakeupDeliveryTime() {
- for (Batch b : mAlarmBatches) {
- if (b.hasWakeups()) {
- return b.mStart;
- }
- }
- return 0;
- }
-
- @Override
- public long getNextDeliveryTime() {
- if (mAlarmBatches.size() > 0) {
- return mAlarmBatches.get(0).mStart;
- }
- return 0;
- }
-
- @Override
- public ArrayList<Alarm> removePendingAlarms(long nowElapsed) {
- final ArrayList<Alarm> removedAlarms = new ArrayList<>();
- while (mAlarmBatches.size() > 0) {
- final Batch batch = mAlarmBatches.get(0);
- if (batch.mStart > nowElapsed) {
- break;
- }
- mAlarmBatches.remove(0);
- for (int i = 0; i < batch.size(); i++) {
- removedAlarms.add(batch.get(i));
- }
- }
- mSize -= removedAlarms.size();
- return removedAlarms;
- }
-
- @Override
- public boolean updateAlarmDeliveries(AlarmDeliveryCalculator deliveryCalculator) {
- boolean changed = false;
- for (final Batch b : mAlarmBatches) {
- for (int i = 0; i < b.size(); i++) {
- changed |= deliveryCalculator.updateAlarmDelivery(b.get(i));
- }
- }
- if (changed) {
- rebatchAllAlarms();
- }
- return changed;
- }
-
- @Override
- public ArrayList<Alarm> asList() {
- final ArrayList<Alarm> allAlarms = new ArrayList<>();
- for (final Batch batch : mAlarmBatches) {
- for (int i = 0; i < batch.size(); i++) {
- allAlarms.add(batch.get(i));
- }
- }
- return allAlarms;
- }
-
- @Override
- public void dump(IndentingPrintWriter ipw, long nowElapsed, SimpleDateFormat sdf) {
- ipw.print("Pending alarm batches: ");
- ipw.println(mAlarmBatches.size());
- for (Batch b : mAlarmBatches) {
- ipw.print(b);
- ipw.println(':');
- ipw.increaseIndent();
- dumpAlarmList(ipw, b.mAlarms, nowElapsed, sdf);
- ipw.decreaseIndent();
- }
- mStatLogger.dump(ipw);
- }
-
- @Override
- public void dumpProto(ProtoOutputStream pos, long nowElapsed) {
- for (Batch b : mAlarmBatches) {
- b.dumpDebug(pos, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES, nowElapsed);
- }
- }
-
- @Override
- public String getName() {
- return TAG;
- }
-
- @Override
- public int getCount(Predicate<Alarm> condition) {
- long start = mStatLogger.getTime();
-
- int count = 0;
- for (Batch b : mAlarmBatches) {
- for (int i = 0; i < b.size(); i++) {
- if (condition.test(b.get(i))) {
- count++;
- }
- }
- }
- mStatLogger.logDurationStat(Stats.GET_COUNT, start);
- return count;
- }
-
- private void insertAndBatchAlarm(Alarm alarm) {
- final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1
- : attemptCoalesce(alarm.getWhenElapsed(), alarm.getMaxWhenElapsed());
-
- if (whichBatch < 0) {
- addBatch(mAlarmBatches, new Batch(alarm));
- } else {
- final Batch batch = mAlarmBatches.get(whichBatch);
- if (batch.add(alarm)) {
- // The start time of this batch advanced, so batch ordering may
- // have just been broken. Move it to where it now belongs.
- mAlarmBatches.remove(whichBatch);
- addBatch(mAlarmBatches, batch);
- }
- }
- }
-
- static void addBatch(ArrayList<Batch> list, Batch newBatch) {
- int index = Collections.binarySearch(list, newBatch, sBatchOrder);
- if (index < 0) {
- index = 0 - index - 1;
- }
- list.add(index, newBatch);
- }
-
- // Return the index of the matching batch, or -1 if none found.
- private int attemptCoalesce(long whenElapsed, long maxWhen) {
- final int n = mAlarmBatches.size();
- for (int i = 0; i < n; i++) {
- Batch b = mAlarmBatches.get(i);
- if ((b.mFlags & AlarmManager.FLAG_STANDALONE) == 0 && b.canHold(whenElapsed, maxWhen)) {
- return i;
- }
- }
- return -1;
- }
-
- final class Batch {
- long mStart; // These endpoints are always in ELAPSED
- long mEnd;
- int mFlags; // Flags for alarms, such as FLAG_STANDALONE.
-
- final ArrayList<Alarm> mAlarms = new ArrayList<>();
-
- Batch(Alarm seed) {
- mStart = seed.getWhenElapsed();
- mEnd = clampPositive(seed.getMaxWhenElapsed());
- mFlags = seed.flags;
- mAlarms.add(seed);
- }
-
- int size() {
- return mAlarms.size();
- }
-
- Alarm get(int index) {
- return mAlarms.get(index);
- }
-
- boolean canHold(long whenElapsed, long maxWhen) {
- return (mEnd >= whenElapsed) && (mStart <= maxWhen);
- }
-
- boolean add(Alarm alarm) {
- boolean newStart = false;
- // narrows the batch if necessary; presumes that canHold(alarm) is true
- int index = Collections.binarySearch(mAlarms, alarm, sIncreasingTimeOrder);
- if (index < 0) {
- index = 0 - index - 1;
- }
- mAlarms.add(index, alarm);
- if (DEBUG_BATCH) {
- Slog.v(TAG, "Adding " + alarm + " to " + this);
- }
- if (alarm.getWhenElapsed() > mStart) {
- mStart = alarm.getWhenElapsed();
- newStart = true;
- }
- if (alarm.getMaxWhenElapsed() < mEnd) {
- mEnd = alarm.getMaxWhenElapsed();
- }
- mFlags |= alarm.flags;
-
- if (DEBUG_BATCH) {
- Slog.v(TAG, " => now " + this);
- }
- return newStart;
- }
-
- ArrayList<Alarm> remove(Predicate<Alarm> predicate) {
- final ArrayList<Alarm> removed = new ArrayList<>();
- long newStart = 0; // recalculate endpoints as we go
- long newEnd = Long.MAX_VALUE;
- int newFlags = 0;
- for (int i = 0; i < mAlarms.size(); ) {
- Alarm alarm = mAlarms.get(i);
- if (predicate.test(alarm)) {
- removed.add(mAlarms.remove(i));
- if (alarm.alarmClock != null && mOnAlarmClockRemoved != null) {
- mOnAlarmClockRemoved.run();
- }
- if (isTimeTickAlarm(alarm)) {
- // This code path is not invoked when delivering alarms, only when removing
- // alarms due to the caller cancelling it or getting uninstalled, etc.
- Slog.wtf(TAG, "Removed TIME_TICK alarm");
- }
- } else {
- if (alarm.getWhenElapsed() > newStart) {
- newStart = alarm.getWhenElapsed();
- }
- if (alarm.getMaxWhenElapsed() < newEnd) {
- newEnd = alarm.getMaxWhenElapsed();
- }
- newFlags |= alarm.flags;
- i++;
- }
- }
- if (!removed.isEmpty()) {
- // commit the new batch bounds
- mStart = newStart;
- mEnd = newEnd;
- mFlags = newFlags;
- }
- return removed;
- }
-
- boolean hasWakeups() {
- final int n = mAlarms.size();
- for (int i = 0; i < n; i++) {
- Alarm a = mAlarms.get(i);
- if (a.wakeup) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder(40);
- b.append("Batch{");
- b.append(Integer.toHexString(this.hashCode()));
- b.append(" num=");
- b.append(size());
- b.append(" start=");
- b.append(mStart);
- b.append(" end=");
- b.append(mEnd);
- if (mFlags != 0) {
- b.append(" flgs=0x");
- b.append(Integer.toHexString(mFlags));
- }
- b.append('}');
- return b.toString();
- }
-
- public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed) {
- final long token = proto.start(fieldId);
-
- proto.write(BatchProto.START_REALTIME, mStart);
- proto.write(BatchProto.END_REALTIME, mEnd);
- proto.write(BatchProto.FLAGS, mFlags);
- for (Alarm a : mAlarms) {
- a.dumpDebug(proto, BatchProto.ALARMS, nowElapsed);
- }
-
- proto.end(token);
- }
- }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 68801bcac4ba..dd80acb80de2 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -303,7 +303,9 @@ public final class JobServiceContext implements ServiceConnection {
getStartActionId(job), String.valueOf(job.getJobId()));
mVerb = VERB_BINDING;
scheduleOpTimeOutLocked();
- final Intent intent = new Intent().setComponent(job.getServiceComponent());
+ // Use FLAG_FROM_BACKGROUND to avoid resetting the bad-app tracking.
+ final Intent intent = new Intent().setComponent(job.getServiceComponent())
+ .setFlags(Intent.FLAG_FROM_BACKGROUND);
boolean binding = false;
try {
final int bindFlags;
diff --git a/config/boot-image-profile-extra.txt b/config/boot-image-profile-extra.txt
new file mode 100644
index 000000000000..e3b187e0a66d
--- /dev/null
+++ b/config/boot-image-profile-extra.txt
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# A list of methods that are found to be latency sensitive. We have this manual
+# due to current limitations of our boot image profiling, where knowing what
+# methods are latency sensitive is difficult. For example, this method is executed
+# in the system server, not on the UI thread of an app.
+HSPLandroid/graphics/Color;->luminance()F
diff --git a/core/api/current.txt b/core/api/current.txt
index bb3264701ca5..805435a757d1 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7051,6 +7051,7 @@ package android.app {
method public void setRunAsMonkey(boolean);
method public void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
method public android.graphics.Bitmap takeScreenshot();
+ method @Nullable public android.graphics.Bitmap takeScreenshot(@NonNull android.view.Window);
method public void waitForIdle(long, long) throws java.util.concurrent.TimeoutException;
field public static final int FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES = 1; // 0x1
field public static final int FLAG_DONT_USE_ACCESSIBILITY = 2; // 0x2
@@ -14928,6 +14929,8 @@ package android.graphics {
method public android.graphics.PathEffect getPathEffect();
method public float getRunAdvance(char[], int, int, int, int, boolean, int);
method public float getRunAdvance(CharSequence, int, int, int, int, boolean, int);
+ method public float getRunCharacterAdvance(@NonNull char[], int, int, int, int, boolean, int, @Nullable float[], int);
+ method public float getRunCharacterAdvance(@NonNull CharSequence, int, int, int, int, boolean, int, @Nullable float[], int);
method public android.graphics.Shader getShader();
method @ColorInt public int getShadowLayerColor();
method @ColorLong public long getShadowLayerColorLong();
@@ -51083,6 +51086,7 @@ package android.view {
method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
method public void addOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener);
method public void addOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener);
+ method public void addOnWindowVisibilityChangeListener(@NonNull android.view.ViewTreeObserver.OnWindowVisibilityChangeListener);
method public void dispatchOnDraw();
method public void dispatchOnGlobalLayout();
method public boolean dispatchOnPreDraw();
@@ -51098,6 +51102,7 @@ package android.view {
method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener);
method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener);
+ method public void removeOnWindowVisibilityChangeListener(@NonNull android.view.ViewTreeObserver.OnWindowVisibilityChangeListener);
method public boolean unregisterFrameCommitCallback(@NonNull Runnable);
}
@@ -51134,6 +51139,10 @@ package android.view {
method public void onWindowFocusChanged(boolean);
}
+ public static interface ViewTreeObserver.OnWindowVisibilityChangeListener {
+ method public void onWindowVisibilityChanged(int);
+ }
+
public abstract class Window {
ctor public Window(@UiContext android.content.Context);
method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
@@ -51530,6 +51539,7 @@ package android.view {
method public default boolean isCrossWindowBlurEnabled();
method public default void removeCrossWindowBlurEnabledListener(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void removeViewImmediate(android.view.View);
+ field public static final String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE = "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
}
public static class WindowManager.BadTokenException extends java.lang.RuntimeException {
@@ -53231,11 +53241,11 @@ package android.view.inputmethod {
public final class InputMethodManager {
method public void dispatchKeyEventFromInputMethod(@Nullable android.view.View, @NonNull android.view.KeyEvent);
method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]);
- method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
- method public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
- method public java.util.List<android.view.inputmethod.InputMethodSubtype> getEnabledInputMethodSubtypeList(android.view.inputmethod.InputMethodInfo, boolean);
- method public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodList();
- method public android.view.inputmethod.InputMethodSubtype getLastInputMethodSubtype();
+ method @Nullable public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype();
+ method @NonNull public java.util.List<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList();
+ method @NonNull public java.util.List<android.view.inputmethod.InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable android.view.inputmethod.InputMethodInfo, boolean);
+ method @NonNull public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodList();
+ method @Nullable public android.view.inputmethod.InputMethodSubtype getLastInputMethodSubtype();
method public java.util.Map<android.view.inputmethod.InputMethodInfo,java.util.List<android.view.inputmethod.InputMethodSubtype>> getShortcutInputMethodsAndSubtypes();
method @Deprecated public void hideSoftInputFromInputMethod(android.os.IBinder, int);
method public boolean hideSoftInputFromWindow(android.os.IBinder, int);
@@ -53251,12 +53261,12 @@ package android.view.inputmethod {
method @Deprecated public boolean isWatchingCursor(android.view.View);
method public void restartInput(android.view.View);
method public void sendAppPrivateCommand(android.view.View, String, android.os.Bundle);
- method @Deprecated public void setAdditionalInputMethodSubtypes(String, android.view.inputmethod.InputMethodSubtype[]);
+ method @Deprecated public void setAdditionalInputMethodSubtypes(@NonNull String, @NonNull android.view.inputmethod.InputMethodSubtype[]);
method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setCurrentInputMethodSubtype(android.view.inputmethod.InputMethodSubtype);
method @Deprecated public void setInputMethod(android.os.IBinder, String);
method @Deprecated public void setInputMethodAndSubtype(@NonNull android.os.IBinder, String, android.view.inputmethod.InputMethodSubtype);
method @Deprecated public boolean shouldOfferSwitchingToNextInputMethod(android.os.IBinder);
- method public void showInputMethodAndSubtypeEnabler(String);
+ method public void showInputMethodAndSubtypeEnabler(@Nullable String);
method public void showInputMethodPicker();
method public boolean showSoftInput(android.view.View, int);
method public boolean showSoftInput(android.view.View, int, android.os.ResultReceiver);
@@ -57694,7 +57704,7 @@ package android.widget {
method public final void setSpannableFactory(android.text.Spannable.Factory);
method public final void setText(CharSequence);
method public void setText(CharSequence, android.widget.TextView.BufferType);
- method public final void setText(char[], int, int);
+ method public final void setText(@NonNull char[], int, int);
method public final void setText(@StringRes int);
method public final void setText(@StringRes int, android.widget.TextView.BufferType);
method public void setTextAppearance(@StyleRes int);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8a0acd509727..572101c11bd3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -5958,7 +5958,7 @@ package android.location {
method public int getEphemerisSource();
method @FloatRange public double getIonoDelayMeters();
method @IntRange(from=0, to=1023) public int getIssueOfDataClock();
- method @IntRange(from=0, to=255) public int getIssueOfDataEphemeris();
+ method @IntRange(from=0, to=1023) public int getIssueOfDataEphemeris();
method @Nullable public android.location.SatellitePvt.PositionEcef getPositionEcef();
method @IntRange(from=0) public long getTimeOfClockSeconds();
method @IntRange(from=0) public long getTimeOfEphemerisSeconds();
@@ -5986,7 +5986,7 @@ package android.location {
method @NonNull public android.location.SatellitePvt.Builder setEphemerisSource(int);
method @NonNull public android.location.SatellitePvt.Builder setIonoDelayMeters(@FloatRange(from=0.0f, to=100.0f) double);
method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataClock(@IntRange(from=0, to=1023) int);
- method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataEphemeris(@IntRange(from=0, to=255) int);
+ method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataEphemeris(@IntRange(from=0, to=1023) int);
method @NonNull public android.location.SatellitePvt.Builder setPositionEcef(@NonNull android.location.SatellitePvt.PositionEcef);
method @NonNull public android.location.SatellitePvt.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
method @NonNull public android.location.SatellitePvt.Builder setTimeOfEphemerisSeconds(@IntRange(from=0) long);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 5faf782003ca..b13ebf388d1f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -419,6 +419,7 @@ package android.app {
public class TaskInfo {
method public boolean containsLaunchCookie(@NonNull android.os.IBinder);
method @NonNull public android.content.res.Configuration getConfiguration();
+ method public int getDisplayId();
method public int getParentTaskId();
method @Nullable public android.app.PictureInPictureParams getPictureInPictureParams();
method @NonNull public android.window.WindowContainerToken getToken();
@@ -439,7 +440,6 @@ package android.app {
method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
method public void syncInputTransactions();
method public void syncInputTransactions(boolean);
- method @Nullable public android.graphics.Bitmap takeScreenshot(@NonNull android.view.Window);
field @NonNull public static final java.util.Set<java.lang.String> ALL_PERMISSIONS;
}
@@ -823,7 +823,7 @@ package android.content.pm {
}
public abstract class PackageManager {
- method @Nullable public String getContentCaptureServicePackageName();
+ method @Deprecated @Nullable public final String getContentCaptureServicePackageName();
method @Nullable public String getDefaultTextClassifierPackageName();
method @RequiresPermission(android.Manifest.permission.INJECT_EVENTS) public android.os.IBinder getHoldLockToken();
method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 530de0f3af6b..2e89ce83cd36 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -79,7 +79,6 @@ import java.util.List;
* @attr ref android.R.styleable#AccessibilityService_accessibilityEventTypes
* @attr ref android.R.styleable#AccessibilityService_accessibilityFeedbackType
* @attr ref android.R.styleable#AccessibilityService_accessibilityFlags
- * @attr ref android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
* @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
* @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
* @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent
@@ -1424,8 +1423,6 @@ public class AccessibilityServiceInfo implements Parcelable {
return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT";
case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION:
return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION";
- case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
- return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
return "CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS";
case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 493cb87e92d7..d8a48c91c19d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3999,13 +3999,12 @@ public class Activity extends ContextThemeWrapper
/**
* Called when a touch screen event was not handled by any of the views
- * under it. This is most useful to process touch events that happen
+ * inside of the activity. This is most useful to process touch events that happen
* outside of your window bounds, where there is no view to receive it.
*
* @param event The touch screen event being processed.
*
* @return Return true if you have consumed the event, false if you haven't.
- * The default implementation always returns false.
*/
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
@@ -4038,12 +4037,12 @@ public class Activity extends ContextThemeWrapper
* Called when a generic motion event was not handled by any of the
* views inside of the activity.
* <p>
- * Generic motion events describe joystick movements, mouse hovers, track pad
- * touches, scroll wheel movements and other input events. The
- * {@link MotionEvent#getSource() source} of the motion event specifies
+ * Generic motion events describe joystick movements, hover events from mouse or stylus
+ * devices, trackpad touches, scroll wheel movements and other motion events not handled
+ * by {@link #onTouchEvent(MotionEvent)} or {@link #onTrackballEvent(MotionEvent)}.
+ * The {@link MotionEvent#getSource() source} of the motion event specifies
* the class of input that was received. Implementations of this method
* must examine the bits in the source before processing the event.
- * The following code example shows how this is done.
* </p><p>
* Generic motion events with source class
* {@link android.view.InputDevice#SOURCE_CLASS_POINTER}
@@ -4254,6 +4253,8 @@ public class Activity extends ContextThemeWrapper
* @param ev The touch screen event.
*
* @return boolean Return true if this event was consumed.
+ *
+ * @see #onTouchEvent(MotionEvent)
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
@@ -4274,6 +4275,8 @@ public class Activity extends ContextThemeWrapper
* @param ev The trackball event.
*
* @return boolean Return true if this event was consumed.
+ *
+ * @see #onTrackballEvent(MotionEvent)
*/
public boolean dispatchTrackballEvent(MotionEvent ev) {
onUserInteraction();
@@ -4292,6 +4295,8 @@ public class Activity extends ContextThemeWrapper
* @param ev The generic motion event.
*
* @return boolean Return true if this event was consumed.
+ *
+ * @see #onGenericMotionEvent(MotionEvent)
*/
public boolean dispatchGenericMotionEvent(MotionEvent ev) {
onUserInteraction();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index d9e09604bb05..1a06c6fd1642 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1159,7 +1159,6 @@ public class ActivityOptions extends ComponentOptions {
opts.mLaunchIntoPipParams = new PictureInPictureParams.Builder(pictureInPictureParams)
.setIsLaunchIntoPip(true)
.build();
- opts.mLaunchBounds = new Rect(pictureInPictureParams.getSourceRectHint());
return opts;
}
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index 877e7d3b3bf7..57dacd024ba1 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -263,6 +263,11 @@ class ActivityTransitionState {
// After orientation change, the onResume can come in before the top Activity has
// left, so if the Activity is not top, wait a second for the top Activity to exit.
if (mEnterTransitionCoordinator == null || activity.isTopOfTask()) {
+ if (mEnterTransitionCoordinator != null) {
+ mEnterTransitionCoordinator.runAfterTransitionsComplete(() -> {
+ mEnterTransitionCoordinator = null;
+ });
+ }
restoreExitedViews();
restoreReenteringViews();
} else {
@@ -271,6 +276,11 @@ class ActivityTransitionState {
public void run() {
if (mEnterTransitionCoordinator == null ||
mEnterTransitionCoordinator.isWaitingForRemoteExit()) {
+ if (mEnterTransitionCoordinator != null) {
+ mEnterTransitionCoordinator.runAfterTransitionsComplete(() -> {
+ mEnterTransitionCoordinator = null;
+ });
+ }
restoreExitedViews();
restoreReenteringViews();
} else if (mEnterTransitionCoordinator.isReturning()) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 6092b307d50e..9072b5023ce8 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -10291,6 +10291,9 @@ public class AppOpsManager {
// system alert window is disable on low ram phones starting from Q
final PackageManager pm = context.getPackageManager();
+ if (null == pm) {
+ return AppOpsManager.MODE_DEFAULT;
+ }
// TVs are constantly plugged in and has less concern for memory/power
if (ActivityManager.isLowRamDeviceStatic()
&& !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index fea30278aabe..569f4dd8328c 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3657,15 +3657,6 @@ public class ApplicationPackageManager extends PackageManager {
}
@Override
- public String getContentCaptureServicePackageName() {
- try {
- return mPM.getContentCaptureServicePackageName();
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
-
- @Override
public boolean isPackageStateProtected(String packageName, int userId) {
try {
return mPM.isPackageStateProtected(packageName, userId);
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index da6a551175e3..ddfbc6847ed0 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -235,5 +235,6 @@ interface INotificationManager
void setListenerFilter(in ComponentName cn, int userId, in NotificationListenerFilter nlf);
void migrateNotificationFilter(in INotificationListener token, int defaultTypes, in List<String> disallowedPkgs);
+ @EnforcePermission("MANAGE_TOAST_RATE_LIMITING")
void setToastRateLimitingEnabled(boolean enable);
}
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index c9cc1a179102..0e89b25eb37d 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -564,8 +564,10 @@ public final class NotificationChannel implements Parcelable {
/**
* Sets the vibration pattern for notifications posted to this channel. If the provided
- * pattern is valid (non-null, non-empty), will {@link #enableVibration(boolean)} enable
- * vibration} as well. Otherwise, vibration will be disabled.
+ * pattern is valid (non-null, non-empty), will enable vibration on this channel
+ * (equivalent to calling {@link #enableVibration(boolean)} with {@code true}).
+ * Otherwise, vibration will be disabled unless {@link #enableVibration(boolean)} is
+ * used with {@code true}, in which case the default vibration will be used.
*
* Only modifiable before the channel is submitted to
* {@link NotificationManager#createNotificationChannel(NotificationChannel)}.
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 6615374f71ec..36e1eee79d35 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1606,6 +1606,7 @@ public final class SystemServiceRegistry {
case Context.APP_PREDICTION_SERVICE:
case Context.INCREMENTAL_SERVICE:
case Context.ETHERNET_SERVICE:
+ case Context.CONTEXTHUB_SERVICE:
return null;
}
Slog.wtf(TAG, "Manager wrapper not available: " + name);
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index b09463e3074b..a2dc47d44cb9 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -427,6 +427,15 @@ public class TaskInfo {
}
/**
+ * @return The id of the display this task is associated with.
+ * @hide
+ */
+ @TestApi
+ public int getDisplayId() {
+ return displayId;
+ }
+
+ /**
* Returns {@code true} if the parameters that are important for task organizers are equal
* between this {@link TaskInfo} and {@param that}.
* @hide
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index ac6759396c8f..ad7c53b0050d 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1068,10 +1068,7 @@ public final class UiAutomation {
* @param window Window to take a screenshot of
*
* @return The screenshot bitmap on success, null otherwise.
- *
- * @hide
*/
- @TestApi
@Nullable
public Bitmap takeScreenshot(@NonNull Window window) {
if (window == null) {
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 7964ae904392..a045157e02db 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -549,7 +549,6 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
| AccessibilityServiceInfo.FLAG_FORCE_DIRECT_BOOT_AWARE;
info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
| AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
- | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
| AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS);
try {
// Calling out with a lock held is fine since if the system
diff --git a/core/java/android/app/search/SearchAction.java b/core/java/android/app/search/SearchAction.java
index 9e40e7ebaef0..0c4508a4fb8d 100644
--- a/core/java/android/app/search/SearchAction.java
+++ b/core/java/android/app/search/SearchAction.java
@@ -67,7 +67,7 @@ public final class SearchAction implements Parcelable {
private final UserHandle mUserHandle;
@Nullable
- private Bundle mExtras;
+ private final Bundle mExtras;
SearchAction(Parcel in) {
mId = in.readString();
@@ -99,7 +99,7 @@ public final class SearchAction implements Parcelable {
mPendingIntent = pendingIntent;
mIntent = intent;
mUserHandle = userHandle;
- mExtras = extras;
+ mExtras = extras != null ? extras : new Bundle();
if (mPendingIntent == null && mIntent == null) {
throw new IllegalStateException("At least one type of intent should be available.");
diff --git a/core/java/android/app/search/SearchTarget.java b/core/java/android/app/search/SearchTarget.java
index a590a5d7b767..a3874f7cb007 100644
--- a/core/java/android/app/search/SearchTarget.java
+++ b/core/java/android/app/search/SearchTarget.java
@@ -185,7 +185,7 @@ public final class SearchTarget implements Parcelable {
mShortcutInfo = shortcutInfo;
mAppWidgetProviderInfo = appWidgetProviderInfo;
mSliceUri = sliceUri;
- mExtras = extras;
+ mExtras = extras != null ? extras : new Bundle();
int published = 0;
if (mSearchAction != null) published++;
diff --git a/core/java/android/app/timedetector/ITimeDetectorService.aidl b/core/java/android/app/timedetector/ITimeDetectorService.aidl
index b441359b1614..0eb2b5470f58 100644
--- a/core/java/android/app/timedetector/ITimeDetectorService.aidl
+++ b/core/java/android/app/timedetector/ITimeDetectorService.aidl
@@ -20,9 +20,7 @@ import android.app.time.ExternalTimeSuggestion;
import android.app.time.ITimeDetectorListener;
import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.app.timedetector.TimePoint;
@@ -47,9 +45,7 @@ interface ITimeDetectorService {
boolean updateConfiguration(in TimeConfiguration timeConfiguration);
void suggestExternalTime(in ExternalTimeSuggestion timeSuggestion);
- void suggestGnssTime(in GnssTimeSuggestion timeSuggestion);
boolean suggestManualTime(in ManualTimeSuggestion timeSuggestion);
- void suggestNetworkTime(in NetworkTimeSuggestion timeSuggestion);
void suggestTelephonyTime(in TelephonyTimeSuggestion timeSuggestion);
TimePoint latestNetworkTime();
diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java
deleted file mode 100644
index e93c75cb0a0c..000000000000
--- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.timedetector;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.ShellCommand;
-import android.os.TimestampedValue;
-
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * A time signal from a network time source like NTP.
- *
- * <p>See {@link TimeSuggestionHelper} for property information.
- *
- * @hide
- */
-public final class NetworkTimeSuggestion implements Parcelable {
-
- public static final @NonNull Creator<NetworkTimeSuggestion> CREATOR =
- new Creator<NetworkTimeSuggestion>() {
- public NetworkTimeSuggestion createFromParcel(Parcel in) {
- TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
- NetworkTimeSuggestion.class, in);
- return new NetworkTimeSuggestion(helper);
- }
-
- public NetworkTimeSuggestion[] newArray(int size) {
- return new NetworkTimeSuggestion[size];
- }
- };
-
- @NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
-
- public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
- mTimeSuggestionHelper = new TimeSuggestionHelper(
- NetworkTimeSuggestion.class, unixEpochTime);
- }
-
- private NetworkTimeSuggestion(@NonNull TimeSuggestionHelper helper) {
- mTimeSuggestionHelper = Objects.requireNonNull(helper);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
- }
-
- @NonNull
- public TimestampedValue<Long> getUnixEpochTime() {
- return mTimeSuggestionHelper.getUnixEpochTime();
- }
-
- @NonNull
- public List<String> getDebugInfo() {
- return mTimeSuggestionHelper.getDebugInfo();
- }
-
- /**
- * Associates information with the instance that can be useful for debugging / logging. The
- * information is present in {@link #toString()} but is not considered for {@link
- * #equals(Object)} and {@link #hashCode()}.
- */
- public void addDebugInfo(String... debugInfos) {
- mTimeSuggestionHelper.addDebugInfo(debugInfos);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- NetworkTimeSuggestion that = (NetworkTimeSuggestion) o;
- return mTimeSuggestionHelper.handleEquals(that.mTimeSuggestionHelper);
- }
-
- @Override
- public int hashCode() {
- return mTimeSuggestionHelper.hashCode();
- }
-
- @Override
- public String toString() {
- return mTimeSuggestionHelper.handleToString();
- }
-
- /** @hide */
- public static NetworkTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
- throws IllegalArgumentException {
- return new NetworkTimeSuggestion(
- TimeSuggestionHelper.handleParseCommandLineArg(NetworkTimeSuggestion.class, cmd));
- }
-
- /** @hide */
- public static void printCommandLineOpts(PrintWriter pw) {
- TimeSuggestionHelper.handlePrintCommandLineOpts(pw, "Network", NetworkTimeSuggestion.class);
- }
-}
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index abfba3a54a43..9529d4c632a1 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -111,20 +111,4 @@ public interface TimeDetector {
*/
@RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE)
boolean suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion);
-
- /**
- * Suggests the time according to a network time source like NTP.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.SET_TIME)
- void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion);
-
- /**
- * Suggests the time according to a gnss time source.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.SET_TIME)
- void suggestGnssTime(GnssTimeSuggestion timeSuggestion);
}
diff --git a/core/java/android/app/timedetector/TimeDetectorImpl.java b/core/java/android/app/timedetector/TimeDetectorImpl.java
index b0aa3c8d4575..54f8e3f634b5 100644
--- a/core/java/android/app/timedetector/TimeDetectorImpl.java
+++ b/core/java/android/app/timedetector/TimeDetectorImpl.java
@@ -62,28 +62,4 @@ public final class TimeDetectorImpl implements TimeDetector {
throw e.rethrowFromSystemServer();
}
}
-
- @Override
- public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) {
- if (DEBUG) {
- Log.d(TAG, "suggestNetworkTime called: " + timeSuggestion);
- }
- try {
- mITimeDetectorService.suggestNetworkTime(timeSuggestion);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- @Override
- public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
- if (DEBUG) {
- Log.d(TAG, "suggestGnssTime called: " + timeSuggestion);
- }
- try {
- mITimeDetectorService.suggestGnssTime(timeSuggestion);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
}
diff --git a/core/java/android/app/timedetector/TimeSuggestionHelper.java b/core/java/android/app/timedetector/TimeSuggestionHelper.java
index 9b99be61b3c8..e89839c591d9 100644
--- a/core/java/android/app/timedetector/TimeSuggestionHelper.java
+++ b/core/java/android/app/timedetector/TimeSuggestionHelper.java
@@ -201,7 +201,8 @@ public final class TimeSuggestionHelper {
public static void handlePrintCommandLineOpts(
@NonNull PrintWriter pw, @NonNull String typeName, @NonNull Class<?> clazz) {
pw.printf("%s suggestion options:\n", typeName);
- pw.println(" --reference_time <elapsed realtime millis>");
+ pw.println(" --reference_time <elapsed realtime millis> - the elapsed realtime millis when"
+ + " unix epoch time was read");
pw.println(" --unix_epoch_time <Unix epoch time millis>");
pw.println();
pw.println("See " + clazz.getName() + " for more information");
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 45146fd95104..94a9656e2c6b 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -36,6 +36,7 @@ interface ITrustManager {
void setDeviceLockedForUser(int userId, boolean locked);
boolean isDeviceLocked(int userId, int displayId);
boolean isDeviceSecure(int userId, int displayId);
+ @EnforcePermission("TRUST_LISTENER")
boolean isTrustUsuallyManaged(int userId);
void unlockedByBiometricForUser(int userId, in BiometricSourceType source);
void clearAllBiometricRecognized(in BiometricSourceType target, int unlockedUser);
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index d4fbdc6850a4..cc78f1a2ae7c 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -50,11 +50,15 @@ interface IUsageStatsManager {
void reportChooserSelection(String packageName, int userId, String contentType,
in String[] annotations, String action);
int getAppStandbyBucket(String packageName, String callingPackage, int userId);
+ @EnforcePermission("CHANGE_APP_IDLE_STATE")
void setAppStandbyBucket(String packageName, int bucket, int userId);
ParceledListSlice getAppStandbyBuckets(String callingPackage, int userId);
+ @EnforcePermission("CHANGE_APP_IDLE_STATE")
void setAppStandbyBuckets(in ParceledListSlice appBuckets, int userId);
int getAppMinStandbyBucket(String packageName, String callingPackage, int userId);
+ @EnforcePermission("CHANGE_APP_LAUNCH_TIME_ESTIMATE")
void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime, int userId);
+ @EnforcePermission("CHANGE_APP_LAUNCH_TIME_ESTIMATE")
void setEstimatedLaunchTimes(in ParceledListSlice appLaunchTimes, int userId);
void registerAppUsageObserver(int observerId, in String[] packages, long timeLimitMs,
in PendingIntent callback, String callingPackage);
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 966347fb2edb..fd9496947628 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -1167,7 +1167,9 @@ public class AppWidgetManager {
* @param intent The intent of the service which will be providing the data to the
* RemoteViewsAdapter.
* @param connection The callback interface to be notified when a connection is made or lost.
- * @param flags Flags used for binding to the service
+ * @param flags Flags used for binding to the service. Currently only
+ * {@link Context#BIND_AUTO_CREATE} and
+ * {@link Context#BIND_FOREGROUND_SERVICE_WHILE_AWAKE} are supported.
*
* @see Context#getServiceDispatcher(ServiceConnection, Handler, int)
* @hide
diff --git a/core/java/android/content/integrity/AppInstallMetadata.java b/core/java/android/content/integrity/AppInstallMetadata.java
index 9874890ed09e..91b000774457 100644
--- a/core/java/android/content/integrity/AppInstallMetadata.java
+++ b/core/java/android/content/integrity/AppInstallMetadata.java
@@ -129,9 +129,18 @@ public final class AppInstallMetadata {
@Override
public String toString() {
return String.format(
- "AppInstallMetadata { PackageName = %s, AppCerts = %s, InstallerName = %s,"
- + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, StampPresent ="
- + " %b, StampVerified = %b, StampTrusted = %b, StampCert = %s }",
+ "AppInstallMetadata {"
+ + " PackageName = %s,"
+ + " AppCerts = %s,"
+ + " AppCertsLineage = %s,"
+ + " InstallerName = %s,"
+ + " InstallerCerts = %s,"
+ + " VersionCode = %d,"
+ + " PreInstalled = %b,"
+ + " StampPresent = %b,"
+ + " StampVerified = %b,"
+ + " StampTrusted = %b,"
+ + " StampCert = %s }",
mPackageName,
mAppCertificates,
mAppCertificateLineage,
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 2ef1c78474f2..35afe9f727db 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -715,8 +715,6 @@ interface IPackageManager {
String getIncidentReportApproverPackageName();
- String getContentCaptureServicePackageName();
-
boolean isPackageStateProtected(String packageName, int userId);
void sendDeviceCustomizationReadyBroadcast();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 53c23f3fffa7..ccc244190876 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -10083,15 +10083,21 @@ public abstract class PackageManager {
}
/**
- * @return the system defined content capture package name, or null if there's none.
+ * @deprecated This function throws an {@link UnsupportedOperationException}. For pre-granting
+ * permissions, instead of looking up the package that provides {@code ContentCaptureService},
+ * use roles.
*
* @hide
*/
+ // This function cannot yet be removed because it is referenced from GTS tests. The tests have
+ // been updated to not rely on it when running on Android T and above, but in order to compile
+ // the tests we must keep this method.
+ @Deprecated
@TestApi
@Nullable
- public String getContentCaptureServicePackageName() {
+ public final String getContentCaptureServicePackageName() {
throw new UnsupportedOperationException(
- "getContentCaptureServicePackageName not implemented in subclass");
+ "getContentCaptureServicePackageName is deprecated");
}
/**
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index 91f794c161bf..7c3cc10b2b99 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -33,12 +33,15 @@ import android.hardware.biometrics.SensorPropertiesInternal;
*/
interface IAuthService {
// Creates a test session with the specified sensorId
+ @EnforcePermission("TEST_BIOMETRIC")
ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Retrieve static sensor properties for all biometric sensors
+ @EnforcePermission("TEST_BIOMETRIC")
List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
// Retrieve the package where BIometricOrompt's UI is implemented
+ @EnforcePermission("TEST_BIOMETRIC")
String getUiPackage();
// Requests authentication. The service chooses the appropriate biometric to use, and shows
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 42aad36e44c1..08f9ed6203f5 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -31,59 +31,74 @@ import android.hardware.biometrics.SensorPropertiesInternal;
*/
interface IBiometricService {
// Creates a test session with the specified sensorId
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Retrieve static sensor properties for all biometric sensors
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
// Requests authentication. The service chooses the appropriate biometric to use, and shows
// the corresponding BiometricDialog. A requestId is returned that can be used to cancel
// this operation.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long authenticate(IBinder token, long operationId, int userId,
IBiometricServiceReceiver receiver, String opPackageName, in PromptInfo promptInfo);
// Cancel authentication for the given requestId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void cancelAuthentication(IBinder token, String opPackageName, long requestId);
// Checks if biometrics can be used.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
int canAuthenticate(String opPackageName, int userId, int callingUserId, int authenticators);
// Checks if any biometrics are enrolled.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
boolean hasEnrolledBiometrics(int userId, String opPackageName);
// Registers an authenticator (e.g. face, fingerprint, iris).
// Id must be unique, whereas strength and modality don't need to be.
// TODO(b/123321528): Turn strength and modality into enums.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerAuthenticator(int id, int modality, int strength,
IBiometricAuthenticator authenticator);
// Register callback for when keyguard biometric eligibility changes.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback,
int callingUserId);
// Notify BiometricService when <Biometric>Service is ready to start the prepared client.
// Client lifecycle is still managed in <Biometric>Service.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void onReadyForAuthentication(long requestId, int cookie);
// Requests all BIOMETRIC_STRONG sensors to have their authenticatorId invalidated for the
// specified user. This happens when enrollments have been added on devices with multiple
// biometric sensors.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void invalidateAuthenticatorIds(int userId, int fromSensorId, IInvalidationCallback callback);
// Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet
// the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
// land as SIDs, and are used during key generation.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long[] getAuthenticatorIds(int callingUserId);
// See documentation in BiometricManager.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId,
in byte[] hardwareAuthToken);
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
int getCurrentStrength(int sensorId);
// Returns a bit field of the modality (or modalities) that are will be used for authentication.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
int getCurrentModality(String opPackageName, int userId, int callingUserId, int authenticators);
// Returns a bit field of the authentication modalities that are supported by this device.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
int getSupportedModalities(int authenticators);
}
diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl
index f8395a119c0b..df9f504a2c05 100644
--- a/core/java/android/hardware/biometrics/ITestSession.aidl
+++ b/core/java/android/hardware/biometrics/ITestSession.aidl
@@ -27,28 +27,36 @@ interface ITestSession {
// portion of the framework code that would otherwise require human interaction. Note that
// secure pathways such as HAT/Keystore are not testable, since they depend on the TEE or its
// equivalent for the secret key.
+ @EnforcePermission("TEST_BIOMETRIC")
void setTestHalEnabled(boolean enableTestHal);
// Starts the enrollment process. This should generally be used when the test HAL is enabled.
+ @EnforcePermission("TEST_BIOMETRIC")
void startEnroll(int userId);
// Finishes the enrollment process. Simulates the HAL's callback.
+ @EnforcePermission("TEST_BIOMETRIC")
void finishEnroll(int userId);
// Simulates a successful authentication, but does not provide a valid HAT.
+ @EnforcePermission("TEST_BIOMETRIC")
void acceptAuthentication(int userId);
// Simulates a rejected attempt.
+ @EnforcePermission("TEST_BIOMETRIC")
void rejectAuthentication(int userId);
// Simulates an acquired message from the HAL.
+ @EnforcePermission("TEST_BIOMETRIC")
void notifyAcquired(int userId, int acquireInfo);
// Simulates an error message from the HAL.
+ @EnforcePermission("TEST_BIOMETRIC")
void notifyError(int userId, int errorCode);
// Matches the framework's cached enrollments against the HAL's enrollments. Any enrollment
// that isn't known by both sides are deleted. This should generally be used when the test
// HAL is disabled (e.g. to clean up after a test).
+ @EnforcePermission("TEST_BIOMETRIC")
void cleanupInternalState(int userId);
}
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
index ef4f5f9b05e9..200cf736f0c8 100644
--- a/core/java/android/hardware/display/IColorDisplayManager.aidl
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -23,9 +23,12 @@ interface IColorDisplayManager {
boolean isDeviceColorManaged();
boolean setSaturationLevel(int saturationLevel);
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setAppSaturationLevel(String packageName, int saturationLevel);
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean isSaturationActivated();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
int getTransformCapabilities();
boolean isNightDisplayActivated();
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 989b001ca8bf..369248edd580 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -33,24 +33,30 @@ import android.view.Surface;
interface IFaceService {
// Creates a test session with the specified sensorId
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Requests a proto dump of the specified sensor
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
// Retrieve static sensor properties for all face sensors
+ @EnforcePermission("MANAGE_BIOMETRIC")
List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
// Retrieve static sensor properties for the specified sensor
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
FaceSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
// Authenticate with a face. A requestId is returned that can be used to cancel this operation.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
String opPackageName, boolean isKeyguardBypassEnabled);
// Uses the face hardware to detect for the presence of a face, without giving details
// about accept/reject/lockout. A requestId is returned that can be used to cancel this
// operation.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long detectFace(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
// This method prepares the service to start authenticating, but doesn't start authentication.
@@ -58,80 +64,103 @@ interface IFaceService {
// called from BiometricService. The additional uid, pid, userId arguments should be determined
// by BiometricService. To start authentication after the clients are ready, use
// startPreparedClient().
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, long requestId, int cookie,
boolean allowBackgroundAuthentication);
// Starts authentication with the previously prepared client.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void startPreparedClient(int sensorId, int cookie);
// Cancel authentication for the given requestId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void cancelAuthentication(IBinder token, String opPackageName, long requestId);
// Cancel face detection for the given requestId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void cancelFaceDetect(IBinder token, String opPackageName, long requestId);
// Same as above, with extra arguments.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
// Start face enrollment
+ @EnforcePermission("MANAGE_BIOMETRIC")
long enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
String opPackageName, in int [] disabledFeatures,
in Surface previewSurface, boolean debugConsent);
// Start remote face enrollment
+ @EnforcePermission("MANAGE_BIOMETRIC")
long enrollRemotely(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
String opPackageName, in int [] disabledFeatures);
// Cancel enrollment in progress
+ @EnforcePermission("MANAGE_BIOMETRIC")
void cancelEnrollment(IBinder token, long requestId);
// Removes the specified face enrollment for the specified userId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver,
String opPackageName);
// Removes all face enrollments for the specified userId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void removeAll(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
// Get the enrolled face for user.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName);
// Determine if HAL is loaded and ready
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
boolean isHardwareDetected(int sensorId, String opPackageName);
// Get a pre-enrollment authentication token
+ @EnforcePermission("MANAGE_BIOMETRIC")
void generateChallenge(IBinder token, int sensorId, int userId, IFaceServiceReceiver receiver, String opPackageName);
// Finish an enrollment sequence and invalidate the authentication token
+ @EnforcePermission("MANAGE_BIOMETRIC")
void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge);
// Determine if a user has at least one enrolled face
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName);
// Return the LockoutTracker status for the specified user
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
int getLockoutModeForUser(int sensorId, int userId);
// Requests for the specified sensor+userId's authenticatorId to be invalidated
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void invalidateAuthenticatorId(int sensorId, int userId, IInvalidationCallback callback);
// Gets the authenticator ID for face
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long getAuthenticatorId(int sensorId, int callingUserId);
// Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void resetLockout(IBinder token, int sensorId, int userId, in byte [] hardwareAuthToken, String opPackageName);
// Add a callback which gets notified when the face lockout period expired.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback, String opPackageName);
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void setFeature(IBinder token, int userId, int feature, boolean enabled,
in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, String opPackageName);
+ @EnforcePermission("MANAGE_BIOMETRIC")
void getFeature(IBinder token, int userId, int feature, IFaceServiceReceiver receiver,
String opPackageName);
// Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
// AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
// hidlSensors must be non-null and empty. See AuthService.java
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerAuthenticators(in List<FaceSensorPropertiesInternal> hidlSensors);
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 0b6344617663..1fc6eab3fd26 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -37,15 +37,18 @@ import java.util.List;
interface IFingerprintService {
// Creates a test session with the specified sensorId
+ @EnforcePermission("TEST_BIOMETRIC")
ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName);
// Requests a proto dump of the specified sensor
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
// Retrieve static sensor properties for all fingerprint sensors
List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
// Retrieve static sensor properties for the specified sensor
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
FingerprintSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
// Authenticate with a fingerprint. This is protected by USE_FINGERPRINT/USE_BIOMETRIC
@@ -58,6 +61,7 @@ interface IFingerprintService {
// Uses the fingerprint hardware to detect for the presence of a finger, without giving details
// about accept/reject/lockout. A requestId is returned that can be used to cancel this
// operation.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long detectFingerprint(IBinder token, int userId, IFingerprintServiceReceiver receiver,
String opPackageName);
@@ -66,38 +70,47 @@ interface IFingerprintService {
// called from BiometricService. The additional uid, pid, userId arguments should be determined
// by BiometricService. To start authentication after the clients are ready, use
// startPreparedClient().
+ @EnforcePermission("MANAGE_BIOMETRIC")
void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
int cookie, boolean allowBackgroundAuthentication);
// Starts authentication with the previously prepared client.
+ @EnforcePermission("MANAGE_BIOMETRIC")
void startPreparedClient(int sensorId, int cookie);
// Cancel authentication for the given requestId.
void cancelAuthentication(IBinder token, String opPackageName, String attributionTag, long requestId);
// Cancel finger detection for the given requestId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void cancelFingerprintDetect(IBinder token, String opPackageName, long requestId);
// Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes
// an additional uid, pid, userid.
+ @EnforcePermission("MANAGE_BIOMETRIC")
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
// Start fingerprint enrollment
+ @EnforcePermission("MANAGE_FINGERPRINT")
long enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver,
String opPackageName, int enrollReason);
// Cancel enrollment in progress
+ @EnforcePermission("MANAGE_FINGERPRINT")
void cancelEnrollment(IBinder token, long requestId);
// Any errors resulting from this call will be returned to the listener
+ @EnforcePermission("MANAGE_FINGERPRINT")
void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver,
String opPackageName);
// Removes all face enrollments for the specified userId.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void removeAll(IBinder token, int userId, IFingerprintServiceReceiver receiver, String opPackageName);
// Rename the fingerprint specified by fingerId and userId to the given name
+ @EnforcePermission("MANAGE_FINGERPRINT")
void rename(int fingerId, int userId, String name);
// Get a list of enrolled fingerprints in the given userId.
@@ -107,66 +120,85 @@ interface IFingerprintService {
boolean isHardwareDetectedDeprecated(String opPackageName, String attributionTag);
// Determine if the specified HAL is loaded and ready
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
boolean isHardwareDetected(int sensorId, String opPackageName);
// Get a pre-enrollment authentication token
+ @EnforcePermission("MANAGE_FINGERPRINT")
void generateChallenge(IBinder token, int sensorId, int userId, IFingerprintServiceReceiver receiver, String opPackageName);
// Finish an enrollment sequence and invalidate the authentication token
+ @EnforcePermission("MANAGE_FINGERPRINT")
void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge);
// Determine if a user has at least one enrolled fingerprint. Meant to support the deprecated FingerprintManager APIs
boolean hasEnrolledFingerprintsDeprecated(int userId, String opPackageName, String attributionTag);
// Determine if a user has at least one enrolled fingerprint.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName);
// Return the LockoutTracker status for the specified user
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
int getLockoutModeForUser(int sensorId, int userId);
// Requests for the specified sensor+userId's authenticatorId to be invalidated
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void invalidateAuthenticatorId(int sensorId, int userId, IInvalidationCallback callback);
// Gets the authenticator ID for fingerprint
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
long getAuthenticatorId(int sensorId, int callingUserId);
// Reset the timeout when user authenticates with strong auth (e.g. PIN, pattern or password)
+ @EnforcePermission("RESET_FINGERPRINT_LOCKOUT")
void resetLockout(IBinder token, int sensorId, int userId, in byte[] hardwareAuthToken, String opPackageNAame);
// Add a callback which gets notified when the fingerprint lockout period expired.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback, String opPackageName);
// Check if a client request is currently being handled
+ @EnforcePermission("MANAGE_FINGERPRINT")
boolean isClientActive();
// Add a callback which gets notified when the service starts and stops handling client requests
+ @EnforcePermission("MANAGE_FINGERPRINT")
void addClientActiveCallback(IFingerprintClientActiveCallback callback);
// Removes a callback set by addClientActiveCallback
+ @EnforcePermission("MANAGE_FINGERPRINT")
void removeClientActiveCallback(IFingerprintClientActiveCallback callback);
// Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
// AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
// hidlSensors must be non-null and empty. See AuthService.java
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerAuthenticators(in List<FingerprintSensorPropertiesInternal> hidlSensors);
// Adds a callback which gets called when the service registers all of the fingerprint
// authenticators. The callback is automatically removed after it's invoked.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void addAuthenticatorsRegisteredCallback(IFingerprintAuthenticatorsRegisteredCallback callback);
// Notifies about a finger touching the sensor area.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void onPointerDown(long requestId, int sensorId, int x, int y, float minor, float major);
// Notifies about a finger leaving the sensor area.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void onPointerUp(long requestId, int sensorId);
// Notifies about the fingerprint UI being ready (e.g. HBM illumination is enabled).
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void onUiReady(long requestId, int sensorId);
// Sets the controller for managing the UDFPS overlay.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void setUdfpsOverlayController(in IUdfpsOverlayController controller);
// Sets the controller for managing the SideFPS overlay.
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void setSidefpsController(in ISidefpsController controller);
// Registers BiometricStateListener.
diff --git a/core/java/android/hardware/iris/IIrisService.aidl b/core/java/android/hardware/iris/IIrisService.aidl
index 98057d548226..764f4d448843 100644
--- a/core/java/android/hardware/iris/IIrisService.aidl
+++ b/core/java/android/hardware/iris/IIrisService.aidl
@@ -26,5 +26,6 @@ interface IIrisService {
// Registers all HIDL and AIDL sensors. Only HIDL sensor properties need to be provided, because
// AIDL sensor properties are retrieved directly from the available HALs. If no HIDL HALs exist,
// hidlSensors must be non-null and empty. See AuthService.java
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
void registerAuthenticators(in List<SensorPropertiesInternal> hidlSensors);
}
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index 92882c4f93bb..ced75c4d0247 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -35,62 +35,78 @@ import android.hardware.location.IContextHubTransactionCallback;
interface IContextHubService {
// Registers a callback to receive messages
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
int registerCallback(in IContextHubCallback callback);
// Gets a list of available context hub handles
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
int[] getContextHubHandles();
// Gets the properties of a hub
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
ContextHubInfo getContextHubInfo(int contextHubHandle);
// Loads a nanoapp at the specified hub (old API)
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
int loadNanoApp(int contextHubHandle, in NanoApp nanoApp);
// Unloads a nanoapp given its instance ID (old API)
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
int unloadNanoApp(int nanoAppHandle);
// Gets the NanoAppInstanceInfo of a nanoapp give its instance ID
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle);
// Finds all nanoApp instances matching some filter
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
int[] findNanoAppOnHub(int contextHubHandle, in NanoAppFilter filter);
// Sends a message to a nanoApp
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
int sendMessage(int contextHubHandle, int nanoAppHandle, in ContextHubMessage msg);
// Creates a client to send and receive messages
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
IContextHubClient createClient(
int contextHubId, in IContextHubClientCallback client, in String attributionTag,
in String packageName);
// Creates a PendingIntent-based client to send and receive messages
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
IContextHubClient createPendingIntentClient(
int contextHubId, in PendingIntent pendingIntent, long nanoAppId,
in String attributionTag);
// Returns a list of ContextHub objects of available hubs
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
List<ContextHubInfo> getContextHubs();
// Loads a nanoapp at the specified hub (new API)
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
void loadNanoAppOnHub(
int contextHubId, in IContextHubTransactionCallback transactionCallback,
in NanoAppBinary nanoAppBinary);
// Unloads a nanoapp on a specified context hub (new API)
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
void unloadNanoAppFromHub(
int contextHubId, in IContextHubTransactionCallback transactionCallback,
long nanoAppId);
// Enables a nanoapp at the specified hub
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
void enableNanoApp(
int contextHubId, in IContextHubTransactionCallback transactionCallback,
long nanoAppId);
// Disables a nanoapp at the specified hub
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
void disableNanoApp(
int contextHubId, in IContextHubTransactionCallback transactionCallback,
long nanoAppId);
// Queries for a list of nanoapps
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
void queryNanoApps(int contextHubId, in IContextHubTransactionCallback transactionCallback);
}
diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java
index e8e4fc988937..f2525d17e30a 100644
--- a/core/java/android/hardware/radio/ProgramList.java
+++ b/core/java/android/hardware/radio/ProgramList.java
@@ -22,10 +22,11 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArrayMap;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -41,7 +42,7 @@ public final class ProgramList implements AutoCloseable {
private final Object mLock = new Object();
private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mPrograms =
- new HashMap<>();
+ new ArrayMap<>();
private final List<ListCallback> mListCallbacks = new ArrayList<>();
private final List<OnCompleteListener> mOnCompleteListeners = new ArrayList<>();
@@ -184,8 +185,14 @@ public final class ProgramList implements AutoCloseable {
listCallbacksCopied = new ArrayList<>(mListCallbacks);
if (chunk.isPurge()) {
- for (ProgramSelector.Identifier id : mPrograms.keySet()) {
- removeLocked(id, removedList);
+ Iterator<Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo>>
+ programsIterator = mPrograms.entrySet().iterator();
+ while (programsIterator.hasNext()) {
+ RadioManager.ProgramInfo removed = programsIterator.next().getValue();
+ if (removed != null) {
+ removedList.add(removed.getSelector().getPrimaryId());
+ }
+ programsIterator.remove();
}
}
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index b05f7cf241e3..0fb04b9d7299 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.sntp.Duration64;
import android.net.sntp.Timestamp64;
@@ -29,6 +30,7 @@ import com.android.internal.util.TrafficStatsConstants;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@@ -39,9 +41,7 @@ import java.util.Random;
import java.util.function.Supplier;
/**
- * {@hide}
- *
- * Simple SNTP client class for retrieving network time.
+ * Simple, single-use SNTP client class for retrieving network time.
*
* Sample usage:
* <pre>SntpClient client = new SntpClient();
@@ -49,6 +49,10 @@ import java.util.function.Supplier;
* long now = client.getNtpTime() + SystemClock.elapsedRealtime() - client.getNtpTimeReference();
* }
* </pre>
+ *
+ * <p>This class is not thread-safe.
+ *
+ * @hide
*/
public class SntpClient {
private static final String TAG = "SntpClient";
@@ -87,6 +91,9 @@ public class SntpClient {
// The round trip (network) time in milliseconds
private long mRoundTripTime;
+ // Details of the NTP server used to obtain the time last.
+ @Nullable private InetSocketAddress mServerSocketAddress;
+
private static class InvalidServerReplyException extends Exception {
public InvalidServerReplyException(String message) {
super(message);
@@ -202,6 +209,7 @@ public class SntpClient {
mNtpTime = responseTime.plus(clockOffsetDuration).toEpochMilli();
mNtpTimeReference = responseTicks;
mRoundTripTime = roundTripTimeMillis;
+ mServerSocketAddress = new InetSocketAddress(address, port);
} catch (Exception e) {
EventLogTags.writeNtpFailure(address.toString(), e.toString());
if (DBG) Log.d(TAG, "request time failed: " + e);
@@ -284,6 +292,14 @@ public class SntpClient {
return mRoundTripTime;
}
+ /**
+ * Returns the address of the NTP server used in the NTP transaction
+ */
+ @Nullable
+ public InetSocketAddress getServerSocketAddress() {
+ return mServerSocketAddress;
+ }
+
private static void checkValidServerReply(
byte leap, byte mode, int stratum, Timestamp64 transmitTimestamp,
Timestamp64 referenceTimestamp, Timestamp64 randomizedRequestTimestamp,
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 5123a9f45176..3063d3ae92a5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -571,7 +571,8 @@ public final class PowerManager {
WAKE_REASON_DISPLAY_GROUP_ADDED,
WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
WAKE_REASON_UNFOLD_DEVICE,
- WAKE_REASON_DREAM_FINISHED
+ WAKE_REASON_DREAM_FINISHED,
+ WAKE_REASON_TILT
})
@Retention(RetentionPolicy.SOURCE)
public @interface WakeReason{}
@@ -686,6 +687,12 @@ public final class PowerManager {
public static final int WAKE_REASON_DREAM_FINISHED = 13;
/**
+ * Wake up reason code: Waking due to tilt.
+ * @hide
+ */
+ public static final int WAKE_REASON_TILT = 14;
+
+ /**
* Convert the wake reason to a string for debugging purposes.
* @hide
*/
@@ -705,6 +712,7 @@ public final class PowerManager {
case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON";
case WAKE_REASON_UNFOLD_DEVICE: return "WAKE_REASON_UNFOLD_DEVICE";
case WAKE_REASON_DREAM_FINISHED: return "WAKE_REASON_DREAM_FINISHED";
+ case WAKE_REASON_TILT: return "WAKE_REASON_TILT";
default: return Integer.toString(wakeReason);
}
}
@@ -715,28 +723,28 @@ public final class PowerManager {
* @hide
*/
public static class WakeData {
- public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDuration) {
+ public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDurationRealtime) {
this.wakeTime = wakeTime;
this.wakeReason = wakeReason;
- this.sleepDuration = sleepDuration;
+ this.sleepDurationRealtime = sleepDurationRealtime;
}
public final long wakeTime;
public final @WakeReason int wakeReason;
- public final long sleepDuration;
+ public final long sleepDurationRealtime;
@Override
public boolean equals(@Nullable Object o) {
if (o instanceof WakeData) {
final WakeData other = (WakeData) o;
return wakeTime == other.wakeTime && wakeReason == other.wakeReason
- && sleepDuration == other.sleepDuration;
+ && sleepDurationRealtime == other.sleepDurationRealtime;
}
return false;
}
@Override
public int hashCode() {
- return Objects.hash(wakeTime, wakeReason, sleepDuration);
+ return Objects.hash(wakeTime, wakeReason, sleepDurationRealtime);
}
}
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index a0f6598640ba..df0bee7e1f2d 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -52,6 +52,7 @@ interface IStorageManager {
* Shuts down the StorageManagerService and gracefully unmounts all external media.
* Invokes call back once the shutdown is complete.
*/
+ @EnforcePermission("SHUTDOWN")
void shutdown(IStorageShutdownObserver observer) = 19;
/**
* Mounts an Opaque Binary Blob (OBB). Only allows the calling process's UID
@@ -100,33 +101,55 @@ interface IStorageManager {
* Kick off an immediate maintenance operation
* @throws RemoteException
*/
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void runMaintenance() = 42;
DiskInfo[] getDisks() = 44;
VolumeInfo[] getVolumes(int flags) = 45;
VolumeRecord[] getVolumeRecords(int flags) = 46;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void mount(in String volId) = 47;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void unmount(in String volId) = 48;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
void format(in String volId) = 49;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
void partitionPublic(in String diskId) = 50;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
void partitionPrivate(in String diskId) = 51;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
void partitionMixed(in String diskId, int ratio) = 52;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void setVolumeNickname(in String fsUuid, in String nickname) = 53;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void setVolumeUserFlags(in String fsUuid, int flags, int mask) = 54;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void forgetVolume(in String fsUuid) = 55;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void forgetAllVolumes() = 56;
String getPrimaryStorageUuid() = 57;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void setPrimaryStorageUuid(in String volumeUuid, IPackageMoveObserver callback) = 58;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
void benchmark(in String volId, IVoldTaskListener listener) = 59;
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void setDebugFlags(int flags, int mask) = 60;
+ @EnforcePermission("STORAGE_INTERNAL")
void createUserKey(int userId, int serialNumber, boolean ephemeral) = 61;
+ @EnforcePermission("STORAGE_INTERNAL")
void destroyUserKey(int userId) = 62;
void unlockUserKey(int userId, int serialNumber, in byte[] secret) = 63;
+ @EnforcePermission("STORAGE_INTERNAL")
void lockUserKey(int userId) = 64;
boolean isUserKeyUnlocked(int userId) = 65;
+ @EnforcePermission("STORAGE_INTERNAL")
void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 66;
+ @EnforcePermission("STORAGE_INTERNAL")
void destroyUserStorage(in String volumeUuid, int userId, int flags) = 67;
+ @EnforcePermission("STORAGE_INTERNAL")
void addUserKeyAuth(int userId, int serialNumber, in byte[] secret) = 70;
+ @EnforcePermission("STORAGE_INTERNAL")
void fixateNewestUserKeyAuth(int userId) = 71;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
void fstrim(int flags, IVoldTaskListener listener) = 72;
AppFuseMount mountProxyFileDescriptorBridge() = 73;
ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode) = 74;
@@ -139,14 +162,17 @@ interface IStorageManager {
void commitChanges() = 83;
boolean supportsCheckpoint() = 84;
void startCheckpoint(int numTries) = 85;
+ @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
boolean needsCheckpoint() = 86;
void abortChanges(in String message, boolean retry) = 87;
+ @EnforcePermission("STORAGE_INTERNAL")
void clearUserKeyAuth(int userId, int serialNumber, in byte[] secret) = 88;
void fixupAppDir(in String path) = 89;
void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90;
PendingIntent getManageSpaceActivityIntent(in String packageName, int requestCode) = 91;
void notifyAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 92;
void notifyAppIoResumed(in String volumeUuid, int uid, int tid, int reason) = 93;
+ @EnforcePermission("WRITE_MEDIA_STORAGE")
int getExternalStorageMountMode(int uid, in String packageName) = 94;
boolean isAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 95;
void setCloudMediaProvider(in String authority) = 96;
diff --git a/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS b/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS
index cb521c842816..4564c30b5d61 100644
--- a/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS
+++ b/core/java/android/permission/DEFAULT_PERMISSION_GRANT_POLICY_OWNERS
@@ -1,8 +1,7 @@
-ewol@google.com
+ashfall@google.com
hackbod@google.com
jsharkey@google.com
narayan@google.com
patb@google.com
-svetoslavganov@google.com
yamasani@google.com
zhanghai@google.com
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 6a93b354f4da..8534c66f2e90 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -80,6 +80,7 @@ interface IPermissionManager {
long revokeAfterKilledDelay, int importanceToResetTimer,
int importanceToKeepSessionAlive);
+ @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS")
void stopOneTimePermissionSession(String packageName, int userId);
List<String> getAutoRevokeExemptionRequestedPackages(int userId);
diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS
index 49f4bf71c172..d34b45bf1ff1 100644
--- a/core/java/android/permission/OWNERS
+++ b/core/java/android/permission/OWNERS
@@ -2,7 +2,7 @@
evanseverson@google.com
evanxinchen@google.com
-ewol@google.com
+ashfall@google.com
guojing@google.com
jaysullivan@google.com
kvakil@google.com
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6c5066f4e5db..0733607c26a4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11371,6 +11371,7 @@ public final class Settings {
* <li>{@link BatteryManager#BATTERY_PLUGGED_AC} to stay on for AC charger</li>
* <li>{@link BatteryManager#BATTERY_PLUGGED_USB} to stay on for USB charger</li>
* <li>{@link BatteryManager#BATTERY_PLUGGED_WIRELESS} to stay on for wireless charger</li>
+ * <li>{@link BatteryManager#BATTERY_PLUGGED_DOCK} to stay on for dock charger</li>
* </ul>
* These values can be OR-ed together.
*/
@@ -11998,7 +11999,23 @@ public final class Settings {
public static final String NITZ_NETWORK_DISCONNECT_RETENTION =
"nitz_network_disconnect_retention";
- /** Preferred NTP server. {@hide} */
+ /**
+ * The preferred NTP server. This setting overrides Android's static xml configuration when
+ * present and valid.
+ *
+ * <p>The legacy form is the NTP server name as a string.
+ * <p>Newer code should use the form: ntp://{server name}[:port] (the standard NTP port,
+ * 123, is used if not specified).
+ *
+ * <p>For example, the following examples are valid:
+ * <ul>
+ * <li>time.android.com</li>
+ * <li>ntp://time.android.com</li>
+ * <li>ntp://time.android.com:123</li>
+ * </ul>
+ *
+ * @hide
+ */
@Readable
public static final String NTP_SERVER = "ntp_server";
/** Timeout in milliseconds to wait for NTP server. {@hide} */
@@ -17431,7 +17448,8 @@ public final class Settings {
* Whether touch and hold to edit WF is enabled
* @hide
*/
- public static final String TOUCH_AND_HOLD_WATCH_FACE = "touch_and_hold_watchface";
+ public static final String GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED =
+ "gesture_touch_and_hold_watchface_enabled";
/**
* Whether bedtime mode is enabled.
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index e39231c9d64b..7394c22ee93f 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -408,14 +408,14 @@ public class TextLine {
final boolean sameDirection = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
if (targetIsInThisSegment && sameDirection) {
- return h + measureRun(segStart, offset, j, runIsRtl, fmi);
+ return h + measureRun(segStart, offset, j, runIsRtl, fmi, null, 0);
}
- final float segmentWidth = measureRun(segStart, j, j, runIsRtl, fmi);
+ final float segmentWidth = measureRun(segStart, j, j, runIsRtl, fmi, null, 0);
h += sameDirection ? segmentWidth : -segmentWidth;
if (targetIsInThisSegment) {
- return h + measureRun(segStart, offset, j, runIsRtl, null);
+ return h + measureRun(segStart, offset, j, runIsRtl, null, null, 0);
}
if (j != runLimit) { // charAt(j) == TAB_CHAR
@@ -437,6 +437,116 @@ public class TextLine {
}
/**
+ * Return the signed horizontal bounds of the characters in the line.
+ *
+ * The length of the returned array equals to 2 * mLen. The left bound of the i th character
+ * is stored at index 2 * i. And the right bound of the i th character is stored at index
+ * (2 * i + 1).
+ *
+ * Check the following examples. LX(e.g. L0, L1, ...) denotes a character which has LTR BiDi
+ * property. On the other hand, RX(e.g. R0, R1, ...) denotes a character which has RTL BiDi
+ * property. Assuming all character has 1em width.
+ *
+ * Example 1: All LTR chars within LTR context
+ * Input Text (logical) : L0 L1 L2 L3
+ * Input Text (visual) : L0 L1 L2 L3
+ * Output : [0em, 1em, 1em, 2em, 2em, 3em, 3em, 4em]
+ *
+ * Example 2: All RTL chars within RTL context.
+ * Input Text (logical) : R0 R1 R2 R3
+ * Input Text (visual) : R3 R2 R1 R0
+ * Output : [-1em, 0em, -2em, -1em, -3em, -2em, -4em, -3em]
+
+ *
+ * Example 3: BiDi chars within LTR context.
+ * Input Text (logical) : L0 L1 R2 R3 L4 L5
+ * Input Text (visual) : L0 L1 R3 R2 L4 L5
+ * Output : [0em, 1em, 1em, 2em, 3em, 4em, 2em, 3em, 4em, 5em, 5em, 6em]
+
+ *
+ * Example 4: BiDi chars within RTL context.
+ * Input Text (logical) : L0 L1 R2 R3 L4 L5
+ * Input Text (visual) : L4 L5 R3 R2 L0 L1
+ * Output : [-2em, -1em, -1em, 0em, -3em, -2em, -4em, -3em, -6em, -5em, -5em, -4em]
+ *
+ * @param bounds the array to receive the character bounds data. Its length should be at least
+ * 2 times of the line length.
+ * @param advances the array to receive the character advance data, nullable. If provided, its
+ * length should be equal or larger than the line length.
+ *
+ * @throws IllegalArgumentException if the given {@code bounds} is null.
+ * @throws IndexOutOfBoundsException if the given {@code bounds} or {@code advances} doesn't
+ * have enough space to hold the result.
+ */
+ public void measureAllBounds(@NonNull float[] bounds, @Nullable float[] advances) {
+ if (bounds == null) {
+ throw new IllegalArgumentException("bounds can't be null");
+ }
+ if (bounds.length < 2 * mLen) {
+ throw new IndexOutOfBoundsException("bounds doesn't have enough space to receive the "
+ + "result, needed: " + (2 * mLen) + " had: " + bounds.length);
+ }
+ if (advances == null) {
+ advances = new float[mLen];
+ }
+ if (advances.length < mLen) {
+ throw new IndexOutOfBoundsException("advance doesn't have enough space to receive the "
+ + "result, needed: " + mLen + " had: " + advances.length);
+ }
+ float h = 0;
+ for (int runIndex = 0; runIndex < mDirections.getRunCount(); runIndex++) {
+ final int runStart = mDirections.getRunStart(runIndex);
+ if (runStart > mLen) break;
+ final int runLimit = Math.min(runStart + mDirections.getRunLength(runIndex), mLen);
+ final boolean runIsRtl = mDirections.isRunRtl(runIndex);
+
+ int segStart = runStart;
+ for (int j = mHasTabs ? runStart : runLimit; j <= runLimit; j++) {
+ if (j == runLimit || charAt(j) == TAB_CHAR) {
+ final boolean sameDirection = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
+
+ final float segmentWidth =
+ measureRun(segStart, j, j, runIsRtl, null, advances, segStart);
+
+ final float oldh = h;
+ h += sameDirection ? segmentWidth : -segmentWidth;
+ float currh = sameDirection ? oldh : h;
+ for (int offset = segStart; offset < j && offset < mLen; ++offset) {
+ if (runIsRtl) {
+ bounds[2 * offset + 1] = currh;
+ currh -= advances[offset];
+ bounds[2 * offset] = currh;
+ } else {
+ bounds[2 * offset] = currh;
+ currh += advances[offset];
+ bounds[2 * offset + 1] = currh;
+ }
+ }
+
+ if (j != runLimit) { // charAt(j) == TAB_CHAR
+ final float leftX;
+ final float rightX;
+ if (runIsRtl) {
+ rightX = h;
+ h = mDir * nextTab(h * mDir);
+ leftX = h;
+ } else {
+ leftX = h;
+ h = mDir * nextTab(h * mDir);
+ rightX = h;
+ }
+ bounds[2 * j] = leftX;
+ bounds[2 * j + 1] = rightX;
+ advances[j] = rightX - leftX;
+ }
+
+ segStart = j + 1;
+ }
+ }
+ }
+ }
+
+ /**
* @see #measure(int, boolean, FontMetricsInt)
* @return The measure results for all possible offsets
*/
@@ -464,15 +574,15 @@ public class TextLine {
if (j == runLimit || charAt(j) == TAB_CHAR) {
final float oldh = h;
final boolean advance = (mDir == Layout.DIR_RIGHT_TO_LEFT) == runIsRtl;
- final float w = measureRun(segStart, j, j, runIsRtl, fmi);
+ final float w = measureRun(segStart, j, j, runIsRtl, fmi, null, 0);
h += advance ? w : -w;
final float baseh = advance ? oldh : h;
FontMetricsInt crtfmi = advance ? fmi : null;
for (int offset = segStart; offset <= j && offset <= mLen; ++offset) {
if (target[offset] >= segStart && target[offset] < j) {
- measurement[offset] =
- baseh + measureRun(segStart, offset, j, runIsRtl, crtfmi);
+ measurement[offset] = baseh
+ + measureRun(segStart, offset, j, runIsRtl, crtfmi, null, 0);
}
}
@@ -518,14 +628,14 @@ public class TextLine {
boolean needWidth) {
if ((mDir == Layout.DIR_LEFT_TO_RIGHT) == runIsRtl) {
- float w = -measureRun(start, limit, limit, runIsRtl, null);
+ float w = -measureRun(start, limit, limit, runIsRtl, null, null, 0);
handleRun(start, limit, limit, runIsRtl, c, null, x + w, top,
- y, bottom, null, false);
+ y, bottom, null, false, null, 0);
return w;
}
return handleRun(start, limit, limit, runIsRtl, c, null, x, top,
- y, bottom, null, needWidth);
+ y, bottom, null, needWidth, null, 0);
}
/**
@@ -538,12 +648,15 @@ public class TextLine {
* @param runIsRtl true if the run is right-to-left
* @param fmi receives metrics information about the requested
* run, can be null.
+ * @param advances receives the advance information about the requested run, can be null.
+ * @param advancesIndex the start index to fill in the advance information.
* @return the signed width from the start of the run to the leading edge
* of the character at offset, based on the run (not paragraph) direction
*/
private float measureRun(int start, int offset, int limit, boolean runIsRtl,
- FontMetricsInt fmi) {
- return handleRun(start, offset, limit, runIsRtl, null, null, 0, 0, 0, 0, fmi, true);
+ @Nullable FontMetricsInt fmi, @Nullable float[] advances, int advancesIndex) {
+ return handleRun(start, offset, limit, runIsRtl, null, null, 0, 0, 0, 0, fmi, true,
+ advances, advancesIndex);
}
/**
@@ -562,13 +675,14 @@ public class TextLine {
int limit, boolean runIsRtl, float x, boolean needWidth) {
if ((mDir == Layout.DIR_LEFT_TO_RIGHT) == runIsRtl) {
- float w = -measureRun(start, limit, limit, runIsRtl, null);
- handleRun(start, limit, limit, runIsRtl, null, consumer, x + w, 0, 0, 0, null, false);
+ float w = -measureRun(start, limit, limit, runIsRtl, null, null, 0);
+ handleRun(start, limit, limit, runIsRtl, null, consumer, x + w, 0, 0, 0, null,
+ false, null, 0);
return w;
}
return handleRun(start, limit, limit, runIsRtl, null, consumer, x, 0, 0, 0, null,
- needWidth);
+ needWidth, null, 0);
}
@@ -908,14 +1022,16 @@ public class TextLine {
}
private float getRunAdvance(TextPaint wp, int start, int end, int contextStart, int contextEnd,
- boolean runIsRtl, int offset) {
+ boolean runIsRtl, int offset, @Nullable float[] advances, int advancesIndex) {
if (mCharsValid) {
- return wp.getRunAdvance(mChars, start, end, contextStart, contextEnd, runIsRtl, offset);
+ return wp.getRunCharacterAdvance(mChars, start, end, contextStart, contextEnd,
+ runIsRtl, offset, advances, advancesIndex);
} else {
final int delta = mStart;
- if (mComputed == null) {
- return wp.getRunAdvance(mText, delta + start, delta + end,
- delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
+ if (mComputed == null || advances != null) {
+ return wp.getRunCharacterAdvance(mText, delta + start, delta + end,
+ delta + contextStart, delta + contextEnd, runIsRtl,
+ delta + offset, advances, advancesIndex);
} else {
return mComputed.getWidth(start + delta, end + delta);
}
@@ -940,6 +1056,8 @@ public class TextLine {
* @param needWidth true if the width of the run is needed
* @param offset the offset for the purpose of measuring
* @param decorations the list of locations and paremeters for drawing decorations
+ * @param advances receives the advance information about the requested run, can be null.
+ * @param advancesIndex the start index to fill in the advance information.
* @return the signed width of the run based on the run direction; only
* valid if needWidth is true
*/
@@ -947,7 +1065,8 @@ public class TextLine {
int contextStart, int contextEnd, boolean runIsRtl,
Canvas c, TextShaper.GlyphsConsumer consumer, float x, int top, int y, int bottom,
FontMetricsInt fmi, boolean needWidth, int offset,
- @Nullable ArrayList<DecorationInfo> decorations) {
+ @Nullable ArrayList<DecorationInfo> decorations,
+ @Nullable float[] advances, int advancesIndex) {
if (mIsJustifying) {
wp.setWordSpacing(mAddedWidthForJustify);
@@ -967,7 +1086,8 @@ public class TextLine {
final int numDecorations = decorations == null ? 0 : decorations.size();
if (needWidth || ((c != null || consumer != null) && (wp.bgColor != 0
|| numDecorations != 0 || runIsRtl))) {
- totalWidth = getRunAdvance(wp, start, end, contextStart, contextEnd, runIsRtl, offset);
+ totalWidth = getRunAdvance(wp, start, end, contextStart, contextEnd, runIsRtl, offset,
+ advances, advancesIndex);
}
final float leftX, rightX;
@@ -1009,10 +1129,10 @@ public class TextLine {
final int decorationStart = Math.max(info.start, start);
final int decorationEnd = Math.min(info.end, offset);
- float decorationStartAdvance = getRunAdvance(
- wp, start, end, contextStart, contextEnd, runIsRtl, decorationStart);
- float decorationEndAdvance = getRunAdvance(
- wp, start, end, contextStart, contextEnd, runIsRtl, decorationEnd);
+ float decorationStartAdvance = getRunAdvance(wp, start, end, contextStart,
+ contextEnd, runIsRtl, decorationStart, null, 0);
+ float decorationEndAdvance = getRunAdvance(wp, start, end, contextStart,
+ contextEnd, runIsRtl, decorationEnd, null, 0);
final float decorationXLeft, decorationXRight;
if (runIsRtl) {
decorationXLeft = rightX - decorationEndAdvance;
@@ -1179,19 +1299,27 @@ public class TextLine {
* @param bottom the bottom of the line
* @param fmi receives metrics information, can be null
* @param needWidth true if the width is required
+ * @param advances receives the advance information about the requested run, can be null.
+ * @param advancesIndex the start index to fill in the advance information.
* @return the signed width of the run based on the run direction; only
* valid if needWidth is true
*/
private float handleRun(int start, int measureLimit,
int limit, boolean runIsRtl, Canvas c,
TextShaper.GlyphsConsumer consumer, float x, int top, int y,
- int bottom, FontMetricsInt fmi, boolean needWidth) {
+ int bottom, FontMetricsInt fmi, boolean needWidth,
+ @Nullable float[] advances, int advancesIndex) {
if (measureLimit < start || measureLimit > limit) {
throw new IndexOutOfBoundsException("measureLimit (" + measureLimit + ") is out of "
+ "start (" + start + ") and limit (" + limit + ") bounds");
}
+ if (advances != null && advances.length - advancesIndex < measureLimit - start) {
+ throw new IndexOutOfBoundsException("advances doesn't have enough space to receive the "
+ + "result");
+ }
+
// Case of an empty line, make sure we update fmi according to mPaint
if (start == measureLimit) {
final TextPaint wp = mWorkPaint;
@@ -1218,7 +1346,7 @@ public class TextLine {
wp.setStartHyphenEdit(adjustStartHyphenEdit(start, wp.getStartHyphenEdit()));
wp.setEndHyphenEdit(adjustEndHyphenEdit(limit, wp.getEndHyphenEdit()));
return handleText(wp, start, limit, start, limit, runIsRtl, c, consumer, x, top,
- y, bottom, fmi, needWidth, measureLimit, null);
+ y, bottom, fmi, needWidth, measureLimit, null, advances, advancesIndex);
}
// Shaping needs to take into account context up to metric boundaries,
@@ -1257,8 +1385,16 @@ public class TextLine {
}
if (replacement != null) {
- x += handleReplacement(replacement, wp, i, mlimit, runIsRtl, c, x, top, y,
- bottom, fmi, needWidth || mlimit < measureLimit);
+ final float width = handleReplacement(replacement, wp, i, mlimit, runIsRtl, c,
+ x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
+ x += width;
+ if (advances != null) {
+ // For replacement, the entire width is assigned to the first character.
+ advances[advancesIndex + i - start] = runIsRtl ? -width : width;
+ for (int j = i + 1; j < mlimit; ++j) {
+ advances[advancesIndex + j - start] = 0.0f;
+ }
+ }
continue;
}
@@ -1300,7 +1436,8 @@ public class TextLine {
adjustEndHyphenEdit(activeEnd, mPaint.getEndHyphenEdit()));
x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c,
consumer, x, top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
- Math.min(activeEnd, mlimit), mDecorations);
+ Math.min(activeEnd, mlimit), mDecorations,
+ advances, advancesIndex + activeStart - start);
activeStart = j;
activePaint.set(wp);
@@ -1327,7 +1464,8 @@ public class TextLine {
adjustEndHyphenEdit(activeEnd, mPaint.getEndHyphenEdit()));
x += handleText(activePaint, activeStart, activeEnd, i, inext, runIsRtl, c, consumer, x,
top, y, bottom, fmi, needWidth || activeEnd < measureLimit,
- Math.min(activeEnd, mlimit), mDecorations);
+ Math.min(activeEnd, mlimit), mDecorations,
+ advances, advancesIndex + activeStart - start);
}
return x - originalX;
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 4a3f772d3bc6..12e33f56b3c6 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -32,8 +32,12 @@ import android.provider.Settings;
import android.text.TextUtils;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.time.Duration;
import java.time.Instant;
import java.util.Objects;
@@ -47,23 +51,76 @@ import java.util.function.Supplier;
*
* @hide
*/
-public class NtpTrustedTime implements TrustedTime {
+public abstract class NtpTrustedTime implements TrustedTime {
+
+ private static final String URI_SCHEME_NTP = "ntp";
+
+ /**
+ * NTP server configuration.
+ *
+ * @hide
+ */
+ public static final class NtpConfig {
+
+ @NonNull private final URI mServerUri;
+ @NonNull private final Duration mTimeout;
+
+ /**
+ * Creates an instance. If the arguments are invalid then an {@link
+ * IllegalArgumentException} will be thrown. See {@link #parseNtpUriStrict(String)} and
+ * {@link #parseNtpServerSetting(String)} to create valid URIs.
+ */
+ public NtpConfig(@NonNull URI serverUri, @NonNull Duration timeout)
+ throws IllegalArgumentException {
+ try {
+ mServerUri = validateNtpServerUri(Objects.requireNonNull(serverUri));
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException("Bad URI", e);
+ }
+
+ if (timeout.isNegative() || timeout.isZero()) {
+ throw new IllegalArgumentException("timeout < 0");
+ }
+ mTimeout = timeout;
+ }
+
+ @NonNull
+ public URI getServerUri() {
+ return mServerUri;
+ }
+
+ @NonNull
+ public Duration getTimeout() {
+ return mTimeout;
+ }
+
+ @Override
+ public String toString() {
+ return "NtpConnectionInfo{"
+ + "mServerUri=" + mServerUri
+ + ", mTimeout=" + mTimeout
+ + '}';
+ }
+ }
/**
* The result of a successful NTP query.
*
* @hide
*/
- public static class TimeResult {
+ public static final class TimeResult {
private final long mUnixEpochTimeMillis;
private final long mElapsedRealtimeMillis;
- private final long mCertaintyMillis;
+ private final int mUncertaintyMillis;
+ @NonNull private final InetSocketAddress mNtpServerSocketAddress;
public TimeResult(
- long unixEpochTimeMillis, long elapsedRealtimeMillis, long certaintyMillis) {
+ long unixEpochTimeMillis, long elapsedRealtimeMillis, int uncertaintyMillis,
+ @NonNull InetSocketAddress ntpServerSocketAddress) {
mUnixEpochTimeMillis = unixEpochTimeMillis;
mElapsedRealtimeMillis = elapsedRealtimeMillis;
- mCertaintyMillis = certaintyMillis;
+ mUncertaintyMillis = uncertaintyMillis;
+ mNtpServerSocketAddress = Objects.requireNonNull(ntpServerSocketAddress);
}
public long getTimeMillis() {
@@ -74,8 +131,8 @@ public class NtpTrustedTime implements TrustedTime {
return mElapsedRealtimeMillis;
}
- public long getCertaintyMillis() {
- return mCertaintyMillis;
+ public int getUncertaintyMillis() {
+ return mUncertaintyMillis;
}
/**
@@ -100,11 +157,34 @@ public class NtpTrustedTime implements TrustedTime {
}
@Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof TimeResult)) {
+ return false;
+ }
+ TimeResult that = (TimeResult) o;
+ return mUnixEpochTimeMillis == that.mUnixEpochTimeMillis
+ && mElapsedRealtimeMillis == that.mElapsedRealtimeMillis
+ && mUncertaintyMillis == that.mUncertaintyMillis
+ && mNtpServerSocketAddress.equals(
+ that.mNtpServerSocketAddress);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUnixEpochTimeMillis, mElapsedRealtimeMillis, mUncertaintyMillis,
+ mNtpServerSocketAddress);
+ }
+
+ @Override
public String toString() {
return "TimeResult{"
- + "mUnixEpochTimeMillis=" + Instant.ofEpochMilli(mUnixEpochTimeMillis)
- + ", mElapsedRealtimeMillis=" + Duration.ofMillis(mElapsedRealtimeMillis)
- + ", mCertaintyMillis=" + mCertaintyMillis
+ + "unixEpochTime=" + Instant.ofEpochMilli(mUnixEpochTimeMillis)
+ + ", elapsedRealtime=" + Duration.ofMillis(mElapsedRealtimeMillis)
+ + ", mUncertaintyMillis=" + mUncertaintyMillis
+ + ", mNtpServerSocketAddress=" + mNtpServerSocketAddress
+ '}';
}
}
@@ -114,54 +194,23 @@ public class NtpTrustedTime implements TrustedTime {
private static NtpTrustedTime sSingleton;
- @NonNull
- private final Context mContext;
-
- /**
- * A supplier that returns the ConnectivityManager. The Supplier can return null if
- * ConnectivityService isn't running yet.
- */
- private final Supplier<ConnectivityManager> mConnectivityManagerSupplier =
- new Supplier<ConnectivityManager>() {
- private ConnectivityManager mConnectivityManager;
-
- @Nullable
- @Override
- public synchronized ConnectivityManager get() {
- // We can't do this at initialization time: ConnectivityService might not be running
- // yet.
- if (mConnectivityManager == null) {
- mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
- }
- return mConnectivityManager;
- }
- };
-
- /** An in-memory config override for use during tests. */
- @Nullable
- private String mHostnameForTests;
-
- /** An in-memory config override for use during tests. */
- @Nullable
- private Integer mPortForTests;
-
/** An in-memory config override for use during tests. */
+ @GuardedBy("this")
@Nullable
- private Duration mTimeoutForTests;
+ private NtpConfig mNtpConfigForTests;
- // Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
+ // Declared volatile and accessed outside synchronized blocks to avoid blocking reads during
// forceRefresh().
private volatile TimeResult mTimeResult;
- private NtpTrustedTime(Context context) {
- mContext = Objects.requireNonNull(context);
+ protected NtpTrustedTime() {
}
@UnsupportedAppUsage
public static synchronized NtpTrustedTime getInstance(Context context) {
if (sSingleton == null) {
Context appContext = context.getApplicationContext();
- sSingleton = new NtpTrustedTime(appContext);
+ sSingleton = new NtpTrustedTimeImpl(appContext);
}
return sSingleton;
}
@@ -170,63 +219,81 @@ public class NtpTrustedTime implements TrustedTime {
* Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
* test value, i.e. so the normal value will be used next time.
*/
- public void setServerConfigForTests(
- @Nullable String hostname, @Nullable Integer port, @Nullable Duration timeout) {
+ public void setServerConfigForTests(@NonNull NtpConfig ntpConfig) {
synchronized (this) {
- mHostnameForTests = hostname;
- mPortForTests = port;
- mTimeoutForTests = timeout;
+ mNtpConfigForTests = ntpConfig;
}
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean forceRefresh() {
synchronized (this) {
- NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
- if (connectionInfo == null) {
+ NtpConfig ntpConfig = getNtpConfig();
+ if (ntpConfig == null) {
// missing server config, so no NTP time available
if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
return false;
}
- ConnectivityManager connectivityManager = mConnectivityManagerSupplier.get();
- if (connectivityManager == null) {
- if (LOGD) Log.d(TAG, "forceRefresh: no ConnectivityManager");
+ Network network = getNetwork();
+ if (network == null) {
+ if (LOGD) Log.d(TAG, "forceRefresh: no network available");
return false;
}
- final Network network = connectivityManager.getActiveNetwork();
- final NetworkInfo ni = connectivityManager.getNetworkInfo(network);
- // This connectivity check is to avoid performing a DNS lookup for the time server on a
- // unconnected network. There are races to obtain time in Android when connectivity
- // changes, which means that forceRefresh() can be called by various components before
- // the network is actually available. This led in the past to DNS lookup failures being
- // cached (~2 seconds) thereby preventing the device successfully making an NTP request
- // when connectivity had actually been established.
- // A side effect of check is that tests that run a fake NTP server on the device itself
- // will only be able to use it if the active network is connected, even though loopback
- // addresses are actually reachable.
- if (ni == null || !ni.isConnected()) {
- if (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
- return false;
+ if (LOGD) {
+ Log.d(TAG, "forceRefresh: NTP request network=" + network
+ + " ntpConfig=" + ntpConfig);
}
-
- if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
- final SntpClient client = new SntpClient();
- final String serverName = connectionInfo.getServer();
- final int port = connectionInfo.getPort();
- final int timeoutMillis = connectionInfo.getTimeoutMillis();
- if (client.requestTime(serverName, port, timeoutMillis, network)) {
- long ntpCertainty = client.getRoundTripTime() / 2;
- mTimeResult = new TimeResult(
- client.getNtpTime(), client.getNtpTimeReference(), ntpCertainty);
- return true;
- } else {
- return false;
+ TimeResult timeResult =
+ queryNtpServer(network, ntpConfig.getServerUri(), ntpConfig.getTimeout());
+ if (timeResult != null) {
+ // Keep any previous time result.
+ mTimeResult = timeResult;
}
+ return timeResult != null;
}
}
+ @GuardedBy("this")
+ private NtpConfig getNtpConfig() {
+ if (mNtpConfigForTests != null) {
+ return mNtpConfigForTests;
+ }
+ return getNtpConfigInternal();
+ }
+
+ /**
+ * Returns the {@link NtpConfig} to use during an NTP query. This method can return {@code null}
+ * if there is no config, or the config found is invalid.
+ *
+ * <p>This method has been made public for easy replacement during tests.
+ */
+ @VisibleForTesting
+ @Nullable
+ public abstract NtpConfig getNtpConfigInternal();
+
+ /**
+ * Returns the {@link Network} to use during an NTP query. This method can return {@code null}
+ * if there is no connectivity
+ *
+ * <p>This method has been made public for easy replacement during tests.
+ */
+ @VisibleForTesting
+ @Nullable
+ public abstract Network getNetwork();
+
+ /**
+ * Queries the specified NTP server. This is a blocking call. Returns {@code null} if the query
+ * fails.
+ *
+ * <p>This method has been made public for easy replacement during tests.
+ */
+ @VisibleForTesting
+ @Nullable
+ public abstract TimeResult queryNtpServer(
+ @NonNull Network network, @NonNull URI ntpServerUri, @NonNull Duration timeout);
+
/**
* Only kept for UnsupportedAppUsage.
*
@@ -314,90 +381,212 @@ public class NtpTrustedTime implements TrustedTime {
}
}
- private static class NtpConnectionInfo {
-
- @NonNull private final String mServer;
- private final int mPort;
- private final int mTimeoutMillis;
+ /**
+ * Parses and returns an NTP server config URI, or throws an exception if the URI doesn't
+ * conform to expectations.
+ *
+ * <p>NTP server config URIs are in the form "ntp://{hostname}[:port]". This is not a registered
+ * IANA URI scheme.
+ */
+ public static URI parseNtpUriStrict(String ntpServerUriString) throws URISyntaxException {
+ // java.net.URI is used in preference to android.net.Uri, since android.net.Uri is very
+ // forgiving of obvious errors. URI catches issues sooner.
+ URI unvalidatedUri = new URI(ntpServerUriString);
+ return validateNtpServerUri(unvalidatedUri);
+ }
- NtpConnectionInfo(@NonNull String server, int port, int timeoutMillis) {
- mServer = Objects.requireNonNull(server);
- mPort = port;
- mTimeoutMillis = timeoutMillis;
+ /**
+ * Parses a setting string and returns a URI that will be accepted by {@link NtpConfig}, or
+ * {@code null} if the string does not produce a URI considered valid.
+ *
+ * <p>NTP server config URIs are in the form "ntp://{hostname}[:port]". This is not a registered
+ * IANA URI scheme.
+ *
+ * <p>Unlike {@link #parseNtpUriStrict(String)} this method will not throw an exception. It
+ * checks for a leading "ntp:" and will call through to {@link #parseNtpUriStrict(String)} to
+ * attempt to parse it, returning {@code null} if it fails. To support legacy settings values,
+ * it will also accept a string that only consists of a server name, which will be coerced into
+ * a URI in the form "ntp://{server name}".
+ */
+ @VisibleForTesting
+ public static URI parseNtpServerSetting(String ntpServerSetting) {
+ if (TextUtils.isEmpty(ntpServerSetting)) {
+ return null;
+ } else if (ntpServerSetting.startsWith(URI_SCHEME_NTP + ":")) {
+ try {
+ return parseNtpUriStrict(ntpServerSetting);
+ } catch (URISyntaxException e) {
+ Log.w(TAG, "Rejected NTP uri setting=" + ntpServerSetting, e);
+ return null;
+ }
+ } else {
+ // This is the legacy settings path. Assumes that the string is just a host name and
+ // creates a URI in the form ntp://<host name>
+ try {
+ URI uri = new URI(URI_SCHEME_NTP, /*host=*/ntpServerSetting,
+ /*path=*/null, /*fragment=*/null);
+ // Paranoia: validate just in case the host name somehow results in a bad URI.
+ return validateNtpServerUri(uri);
+ } catch (URISyntaxException e) {
+ Log.w(TAG, "Rejected NTP legacy setting=" + ntpServerSetting, e);
+ return null;
+ }
}
+ }
- @NonNull
- public String getServer() {
- return mServer;
+ /**
+ * Checks that the supplied URI can be used to identify an NTP server.
+ * This method currently ignores Uri components that are not used, only checking the parts that
+ * must be present. Returns the supplied {@code uri} if validation is successful.
+ */
+ private static URI validateNtpServerUri(URI uri) throws URISyntaxException {
+ if (!uri.isAbsolute()) {
+ throw new URISyntaxException(uri.toString(), "Relative URI not supported");
}
-
- @NonNull
- public int getPort() {
- return mPort;
+ if (!URI_SCHEME_NTP.equals(uri.getScheme())) {
+ throw new URISyntaxException(uri.toString(), "Unrecognized scheme");
}
-
- int getTimeoutMillis() {
- return mTimeoutMillis;
+ String host = uri.getHost();
+ if (TextUtils.isEmpty(host)) {
+ throw new URISyntaxException(uri.toString(), "Missing host");
}
+ return uri;
+ }
- @Override
- public String toString() {
- return "NtpConnectionInfo{"
- + "mServer='" + mServer + '\''
- + ", mPort='" + mPort + '\''
- + ", mTimeoutMillis=" + mTimeoutMillis
- + '}';
+ /** Prints debug information. */
+ public void dump(PrintWriter pw) {
+ synchronized (this) {
+ pw.println("getNtpConfig()=" + getNtpConfig());
+ pw.println("mTimeResult=" + mTimeResult);
+ if (mTimeResult != null) {
+ pw.println("mTimeResult.getAgeMillis()="
+ + Duration.ofMillis(mTimeResult.getAgeMillis()));
+ }
}
}
- @GuardedBy("this")
- private NtpConnectionInfo getNtpConnectionInfo() {
- final ContentResolver resolver = mContext.getContentResolver();
+ /**
+ * The real implementation of {@link NtpTrustedTime}. Contains the parts that are more difficult
+ * to test.
+ */
+ private static final class NtpTrustedTimeImpl extends NtpTrustedTime {
- final Resources res = mContext.getResources();
+ /**
+ * A supplier that returns the ConnectivityManager. The Supplier can return null if
+ * ConnectivityService isn't running yet.
+ */
+ private final Supplier<ConnectivityManager> mConnectivityManagerSupplier =
+ new Supplier<>() {
+ private ConnectivityManager mConnectivityManager;
+
+ @Nullable
+ @Override
+ public synchronized ConnectivityManager get() {
+ // We can't do this at initialization time: ConnectivityService might not be running
+ // yet.
+ if (mConnectivityManager == null) {
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+ }
+ return mConnectivityManager;
+ }
+ };
- final String hostname;
- if (mHostnameForTests != null) {
- hostname = mHostnameForTests;
- } else {
- String serverGlobalSetting =
+ @NonNull
+ private final Context mContext;
+
+ private NtpTrustedTimeImpl(@NonNull Context context) {
+ mContext = Objects.requireNonNull(context);
+ }
+
+ @Override
+ @VisibleForTesting
+ @Nullable
+ public NtpConfig getNtpConfigInternal() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ final Resources res = mContext.getResources();
+
+ // The Settings value has priority over static config. Check settings first.
+ final String serverGlobalSetting =
Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
- if (serverGlobalSetting != null) {
- hostname = serverGlobalSetting;
+ final URI settingsServerInfo = parseNtpServerSetting(serverGlobalSetting);
+
+ URI ntpServerUri;
+ if (settingsServerInfo != null) {
+ ntpServerUri = settingsServerInfo;
} else {
- hostname = res.getString(com.android.internal.R.string.config_ntpServer);
+ String configValue = res.getString(com.android.internal.R.string.config_ntpServer);
+ try {
+ ntpServerUri = parseNtpUriStrict(configValue);
+ } catch (URISyntaxException e) {
+ ntpServerUri = null;
+ }
}
+
+ final int defaultTimeoutMillis =
+ res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
+ final Duration timeout = Duration.ofMillis(Settings.Global.getInt(
+ resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis));
+ return ntpServerUri == null ? null : new NtpConfig(ntpServerUri, timeout);
}
- final Integer port;
- if (mPortForTests != null) {
- port = mPortForTests;
- } else {
- port = SntpClient.STANDARD_NTP_PORT;
+ @Override
+ public Network getNetwork() {
+ ConnectivityManager connectivityManager = mConnectivityManagerSupplier.get();
+ if (connectivityManager == null) {
+ if (LOGD) Log.d(TAG, "getNetwork: no ConnectivityManager");
+ return null;
+ }
+ final Network network = connectivityManager.getActiveNetwork();
+ final NetworkInfo ni = connectivityManager.getNetworkInfo(network);
+
+ // This connectivity check is to avoid performing a DNS lookup for the time server on a
+ // unconnected network. There are races to obtain time in Android when connectivity
+ // changes, which means that forceRefresh() can be called by various components before
+ // the network is actually available. This led in the past to DNS lookup failures being
+ // cached (~2 seconds) thereby preventing the device successfully making an NTP request
+ // when connectivity had actually been established.
+ // A side effect of check is that tests that run a fake NTP server on the device itself
+ // will only be able to use it if the active network is connected, even though loopback
+ // addresses are actually reachable.
+ if (ni == null || !ni.isConnected()) {
+ if (LOGD) Log.d(TAG, "getNetwork: no connectivity");
+ return null;
+ }
+ return network;
}
- final int timeoutMillis;
- if (mTimeoutForTests != null) {
- timeoutMillis = (int) mTimeoutForTests.toMillis();
- } else {
- int defaultTimeoutMillis =
- res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
- timeoutMillis = Settings.Global.getInt(
- resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+ @Override
+ @Nullable
+ public TimeResult queryNtpServer(
+ @NonNull Network network, @NonNull URI ntpServerUri, @NonNull Duration timeout) {
+
+ final SntpClient client = new SntpClient();
+ final String serverName = ntpServerUri.getHost();
+ final int port = ntpServerUri.getPort() == -1
+ ? SntpClient.STANDARD_NTP_PORT : ntpServerUri.getPort();
+ final int timeoutMillis = saturatedCast(timeout.toMillis());
+ if (client.requestTime(serverName, port, timeoutMillis, network)) {
+ int ntpUncertaintyMillis = saturatedCast(client.getRoundTripTime() / 2);
+ InetSocketAddress ntpServerSocketAddress = client.getServerSocketAddress();
+ return new TimeResult(
+ client.getNtpTime(), client.getNtpTimeReference(), ntpUncertaintyMillis,
+ ntpServerSocketAddress);
+ } else {
+ return null;
+ }
}
- return TextUtils.isEmpty(hostname) ? null :
- new NtpConnectionInfo(hostname, port, timeoutMillis);
- }
- /** Prints debug information. */
- public void dump(PrintWriter pw) {
- synchronized (this) {
- pw.println("getNtpConnectionInfo()=" + getNtpConnectionInfo());
- pw.println("mTimeResult=" + mTimeResult);
- if (mTimeResult != null) {
- pw.println("mTimeResult.getAgeMillis()="
- + Duration.ofMillis(mTimeResult.getAgeMillis()));
+ /**
+ * Casts a {@code long} to an {@code int}, clamping the value within the int range.
+ */
+ private static int saturatedCast(long longValue) {
+ if (longValue > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ }
+ if (longValue < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
}
+ return (int) longValue;
}
}
}
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index 9e66f54321cc..eb8687c47bed 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -16,10 +16,14 @@
package android.view;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+
import android.graphics.Insets;
+import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -52,7 +56,9 @@ public class InsetsFrameProvider implements Parcelable {
public static final int SOURCE_FRAME = 2;
private static final int HAS_INSETS_SIZE = 1;
- private static final int HAS_IME_INSETS_SIZE = 2;
+ private static final int HAS_INSETS_SIZE_OVERRIDE = 2;
+
+ private static Rect sTmpRect = new Rect();
/**
* The type of insets to provide.
@@ -77,29 +83,25 @@ public class InsetsFrameProvider implements Parcelable {
public Insets insetsSize = null;
/**
- * The provided frame based on the source frame. The result will be used as the insets
- * size to IME window. Only one side should be set.
+ * If null, the size set in insetsSize will be applied to all window types. If it contains
+ * element of some types, the insets reported to the window with that types will be overridden.
*/
- public Insets imeInsetsSize = null;
+ public InsetsSizeOverride[] insetsSizeOverrides = null;
public InsetsFrameProvider(int type) {
this(type, SOURCE_FRAME, null, null);
}
public InsetsFrameProvider(int type, Insets insetsSize) {
- this(type, SOURCE_FRAME, insetsSize, insetsSize);
- }
-
- public InsetsFrameProvider(int type, Insets insetsSize, Insets imeInsetsSize) {
- this(type, SOURCE_FRAME, insetsSize, imeInsetsSize);
+ this(type, SOURCE_FRAME, insetsSize, null);
}
public InsetsFrameProvider(int type, int source, Insets insetsSize,
- Insets imeInsetsSize) {
+ InsetsSizeOverride[] insetsSizeOverride) {
this.type = type;
this.source = source;
this.insetsSize = insetsSize;
- this.imeInsetsSize = imeInsetsSize;
+ this.insetsSizeOverrides = insetsSizeOverride;
}
@Override
@@ -127,8 +129,8 @@ public class InsetsFrameProvider implements Parcelable {
if (insetsSize != null) {
sb.append(", insetsSize=").append(insetsSize);
}
- if (imeInsetsSize != null) {
- sb.append(", imeInsetsSize=").append(imeInsetsSize);
+ if (insetsSizeOverrides != null) {
+ sb.append(", insetsSizeOverrides=").append(Arrays.toString(insetsSizeOverrides));
}
sb.append("}");
return sb.toString();
@@ -141,8 +143,8 @@ public class InsetsFrameProvider implements Parcelable {
if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
insetsSize = Insets.CREATOR.createFromParcel(in);
}
- if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
- imeInsetsSize = Insets.CREATOR.createFromParcel(in);
+ if ((insetsSizeModified & HAS_INSETS_SIZE_OVERRIDE) != 0) {
+ insetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
}
}
@@ -152,8 +154,8 @@ public class InsetsFrameProvider implements Parcelable {
if (insetsSize != null) {
insetsSizeModified |= HAS_INSETS_SIZE;
}
- if (imeInsetsSize != null) {
- insetsSizeModified |= HAS_IME_INSETS_SIZE;
+ if (insetsSizeOverrides != null) {
+ insetsSizeModified |= HAS_INSETS_SIZE_OVERRIDE;
}
out.writeInt(insetsSizeModified);
out.writeInt(type);
@@ -161,8 +163,8 @@ public class InsetsFrameProvider implements Parcelable {
if (insetsSize != null) {
insetsSize.writeToParcel(out, flags);
}
- if (imeInsetsSize != null) {
- imeInsetsSize.writeToParcel(out, flags);
+ if (insetsSizeOverrides != null) {
+ out.writeTypedArray(insetsSizeOverrides, flags);
}
}
@@ -177,16 +179,12 @@ public class InsetsFrameProvider implements Parcelable {
InsetsFrameProvider other = (InsetsFrameProvider) o;
return type == other.type && source == other.source
&& Objects.equals(insetsSize, other.insetsSize)
- && Objects.equals(imeInsetsSize, other.imeInsetsSize);
+ && Arrays.equals(insetsSizeOverrides, other.insetsSizeOverrides);
}
@Override
public int hashCode() {
- int result = type;
- result = 31 * result + source;
- result = 31 * result + (insetsSize != null ? insetsSize.hashCode() : 0);
- result = 31 * result + (imeInsetsSize != null ? imeInsetsSize.hashCode() : 0);
- return result;
+ return Objects.hash(type, source, insetsSize, Arrays.hashCode(insetsSizeOverrides));
}
public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
@@ -201,5 +199,96 @@ public class InsetsFrameProvider implements Parcelable {
return new InsetsFrameProvider[size];
}
};
+
+ public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds,
+ Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize,
+ @WindowManager.LayoutParams.PrivateFlags int privateFlags) {
+ boolean extendByCutout = false;
+ if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
+ inOutFrame.set(displayFrame);
+ } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
+ inOutFrame.set(containerBounds);
+ } else {
+ extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
+ }
+ if (insetsSize == null) {
+ return;
+ }
+ // Only one side of the provider shall be applied. Check in the order of left - top -
+ // right - bottom, only the first non-zero value will be applied.
+ if (insetsSize.left != 0) {
+ inOutFrame.right = inOutFrame.left + insetsSize.left;
+ } else if (insetsSize.top != 0) {
+ inOutFrame.bottom = inOutFrame.top + insetsSize.top;
+ } else if (insetsSize.right != 0) {
+ inOutFrame.left = inOutFrame.right - insetsSize.right;
+ } else if (insetsSize.bottom != 0) {
+ inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
+ } else {
+ inOutFrame.setEmpty();
+ }
+
+ if (extendByCutout) {
+ WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect);
+ }
+ }
+
+ /**
+ * Class to describe the insets size to be provided to window with specific window type. If not
+ * used, same insets size will be sent as instructed in the insetsSize and source.
+ */
+ public static class InsetsSizeOverride implements Parcelable {
+ public final int windowType;
+ public Insets insetsSize;
+
+ protected InsetsSizeOverride(Parcel in) {
+ windowType = in.readInt();
+ insetsSize = in.readParcelable(null, android.graphics.Insets.class);
+ }
+
+ public InsetsSizeOverride(int type, Insets size) {
+ windowType = type;
+ insetsSize = size;
+ }
+
+ public static final Creator<InsetsSizeOverride> CREATOR =
+ new Creator<InsetsSizeOverride>() {
+ @Override
+ public InsetsSizeOverride createFromParcel(Parcel in) {
+ return new InsetsSizeOverride(in);
+ }
+
+ @Override
+ public InsetsSizeOverride[] newArray(int size) {
+ return new InsetsSizeOverride[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(windowType);
+ out.writeParcelable(insetsSize, flags);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(32);
+ sb.append("TypedInsetsSize: {");
+ sb.append("windowType=").append(windowType);
+ sb.append(", insetsSize=").append(insetsSize);
+ sb.append("}");
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(windowType, insetsSize);
+ }
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1e9769e6270b..c9c00accbe71 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -310,7 +310,7 @@ import java.util.function.Predicate;
* </tr>
*
* <tr>
- * <td rowspan="4">Event processing</td>
+ * <td rowspan="6">Event processing</td>
* <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
* <td>Called when a new hardware key event occurs.
* </td>
@@ -330,6 +330,16 @@ import java.util.function.Predicate;
* <td>Called when a touch screen motion event occurs.
* </td>
* </tr>
+ * <tr>
+ * <td><code>{@link #onGenericMotionEvent(MotionEvent)}</code></td>
+ * <td>Called when a generic motion event occurs.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td><code>{@link #onHoverEvent(MotionEvent)}</code></td>
+ * <td>Called when a hover motion event occurs.
+ * </td>
+ * </tr>
*
* <tr>
* <td rowspan="2">Focus</td>
@@ -15077,6 +15087,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
+ *
+ * @see #onTouchEvent(MotionEvent)
*/
public boolean dispatchTouchEvent(MotionEvent event) {
// If the event should be handled by accessibility focus first.
@@ -15171,6 +15183,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
+ *
+ * @see #onTrackballEvent(MotionEvent)
*/
public boolean dispatchTrackballEvent(MotionEvent event) {
if (mInputEventConsistencyVerifier != null) {
@@ -15205,11 +15219,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Generic motion events with source class {@link InputDevice#SOURCE_CLASS_POINTER}
* are delivered to the view under the pointer. All other generic motion events are
* delivered to the focused view. Hover events are handled specially and are delivered
- * to {@link #onHoverEvent(MotionEvent)}.
+ * to {@link #onHoverEvent(MotionEvent)} first.
* </p>
*
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
+ *
+ * @see #onHoverEvent(MotionEvent)
+ * @see #onGenericMotionEvent(MotionEvent)
*/
public boolean dispatchGenericMotionEvent(MotionEvent event) {
if (mInputEventConsistencyVerifier != null) {
@@ -16040,13 +16057,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Implement this method to handle trackball motion events. The
- * <em>relative</em> movement of the trackball since the last event
+ * Implement this method to handle trackball motion events.
+ * <p>
+ * The <em>relative</em> movement of the trackball since the last event
* can be retrieve with {@link MotionEvent#getX MotionEvent.getX()} and
* {@link MotionEvent#getY MotionEvent.getY()}. These are normalized so
* that a movement of 1 corresponds to the user pressing one DPAD key (so
* they will often be fractional values, representing the more fine-grained
* movement information available from a trackball).
+ * </p>
*
* @param event The motion event.
* @return True if the event was handled, false otherwise.
@@ -16058,9 +16077,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Implement this method to handle generic motion events.
* <p>
- * Generic motion events describe joystick movements, mouse hovers, track pad
- * touches, scroll wheel movements and other input events. The
- * {@link MotionEvent#getSource() source} of the motion event specifies
+ * Generic motion events describe joystick movements, hover events from mouse or stylus
+ * devices, trackpad touches, scroll wheel movements and other motion events not handled
+ * by {@link #onTouchEvent(MotionEvent)} or {@link #onTrackballEvent(MotionEvent)}.
+ * The {@link MotionEvent#getSource() source} of the motion event specifies
* the class of input that was received. Implementations of this method
* must examine the bits in the source before processing the event.
* The following code example shows how this is done.
@@ -16079,7 +16099,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
* switch (event.getAction()) {
* case MotionEvent.ACTION_HOVER_MOVE:
- * // process the mouse hover movement...
+ * // process the hover movement...
* return true;
* case MotionEvent.ACTION_SCROLL:
* // process the scroll wheel movement...
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 827bda2779ee..cb8b9736ed85 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -179,6 +179,7 @@ import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityWindowAttributes;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityEmbeddedConnection;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -1362,6 +1363,7 @@ public final class ViewRootImpl implements ViewParent,
if (mAccessibilityManager.isEnabled()) {
mAccessibilityInteractionConnectionManager.ensureConnection();
+ setAccessibilityWindowAttributesIfNeeded();
}
if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
@@ -1390,6 +1392,17 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ private void setAccessibilityWindowAttributesIfNeeded() {
+ final boolean registered = mAttachInfo.mAccessibilityWindowId
+ != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
+ if (registered) {
+ final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
+ mWindowAttributes);
+ mAccessibilityManager.setAccessibilityWindowAttributes(getDisplayId(),
+ mAttachInfo.mAccessibilityWindowId, attributes);
+ }
+ }
+
/**
* Register any kind of listeners if setView was success.
*/
@@ -1707,6 +1720,7 @@ public final class ViewRootImpl implements ViewParent,
mWindowAttributesChanged = true;
scheduleTraversals();
+ setAccessibilityWindowAttributesIfNeeded();
}
}
@@ -10294,6 +10308,7 @@ public final class ViewRootImpl implements ViewParent,
public void onAccessibilityStateChanged(boolean enabled) {
if (enabled) {
ensureConnection();
+ setAccessibilityWindowAttributesIfNeeded();
if (mAttachInfo.mHasWindowFocus && (mView != null)) {
mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
View focusedView = mView.findFocus();
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index ed8350afc109..2c077c3e9e63 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -109,8 +109,6 @@ public final class ViewTreeObserver {
/**
* Interface definition for a callback to be invoked when the view hierarchy's window
* visibility changes.
- *
- * @hide
*/
public interface OnWindowVisibilityChangeListener {
/**
@@ -569,8 +567,6 @@ public final class ViewTreeObserver {
* @param listener The callback to add
*
* @throws IllegalStateException If {@link #isAlive()} returns false
- *
- * @hide
*/
public void addOnWindowVisibilityChangeListener(
@NonNull OnWindowVisibilityChangeListener listener) {
@@ -593,8 +589,6 @@ public final class ViewTreeObserver {
*
* @see #addOnWindowVisibilityChangeListener(
* android.view.ViewTreeObserver.OnWindowVisibilityChangeListener)
- *
- * @hide
*/
public void removeOnWindowVisibilityChangeListener(
@NonNull OnWindowVisibilityChangeListener victim) {
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 0941ee8a714f..57a0330e3c18 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -274,7 +274,7 @@ public class WindowLayout {
}
if (extendedByCutout) {
- extendFrameByCutout(attrs.gravity, displayCutoutSafe, outDisplayFrame, outFrame,
+ extendFrameByCutout(displayCutoutSafe, outDisplayFrame, outFrame,
mTempRect);
}
@@ -291,7 +291,7 @@ public class WindowLayout {
+ " requestedVisibilities=" + requestedVisibilities);
}
- public static void extendFrameByCutout(int gravity, Rect displayCutoutSafe,
+ public static void extendFrameByCutout(Rect displayCutoutSafe,
Rect displayFrame, Rect inOutFrame, Rect tempRect) {
if (displayCutoutSafe.contains(inOutFrame)) {
return;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 13ea7af7a623..b8808eebee8e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -820,6 +820,33 @@ public interface WindowManager extends ViewManager {
public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
/**
+ * Application level {@link android.content.pm.PackageManager.Property} tag for developers to
+ * provide consent for their app to allow OEMs to manually provide ActivityEmbedding split
+ * rule configuration on behalf of the app.
+ *
+ * <p>If {@code true}, the system CAN override the windowing behaviors for the app, such as
+ * showing some activities side-by-side. In this case, it will report that ActivityEmbedding
+ * APIs are disabled for the app to avoid conflict.
+ *
+ * <p>If {@code false}, the system MUST NOT override the window behavior for the app. It should
+ * be used if the app wants to provide their own ActivityEmbedding split rules, or if the app
+ * wants to opt-out of system overrides for any other reason.
+ *
+ * <p>Default is {@code false}.
+ *
+ * <p>Example usage:
+ * <pre>
+ * &lt;application&gt;
+ * &lt;property
+ * android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"
+ * android:value="true|false"/&gt;
+ * &lt;/application&gt;
+ * </pre>
+ */
+ String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE =
+ "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
+
+ /**
* Request for keyboard shortcuts to be retrieved asynchronously.
*
* @param receiver The callback to be triggered when the result is ready.
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 25445abefca2..d37756551db3 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -404,9 +404,10 @@ public final class WindowManagerGlobal {
try {
root.setView(view, wparams, panelParentView, userId);
} catch (RuntimeException e) {
+ final int viewIndex = (index >= 0) ? index : (mViews.size() - 1);
// BadTokenException or InvalidDisplayException, clean up.
- if (index >= 0) {
- removeViewLocked(index, true);
+ if (viewIndex >= 0) {
+ removeViewLocked(viewIndex, true);
}
throw e;
}
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index c6cd2e81bbf5..9e3195aec8a6 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -1832,6 +1832,32 @@ public final class AccessibilityManager {
}
}
+
+ /**
+ * Sets the {@link AccessibilityWindowAttributes} to the window associated with the given
+ * window id.
+ *
+ * @param displayId The display id of the window.
+ * @param windowId The id of the window.
+ * @param attributes The accessibility window attributes.
+ * @hide
+ */
+ public void setAccessibilityWindowAttributes(int displayId, int windowId,
+ AccessibilityWindowAttributes attributes) {
+ final IAccessibilityManager service;
+ synchronized (mLock) {
+ service = getServiceLocked();
+ if (service == null) {
+ return;
+ }
+ }
+ try {
+ service.setAccessibilityWindowAttributes(displayId, windowId, mUserId, attributes);
+ } catch (RemoteException re) {
+ re.rethrowFromSystemServer();
+ }
+ }
+
private IAccessibilityManager getServiceLocked() {
if (mService == null) {
tryConnectToServiceLocked(null);
diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl b/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
index 81475ec8156d..09174588c115 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.aidl
+++ b/core/java/android/view/accessibility/AccessibilityWindowAttributes.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
+/**
+ * Copyright (c) 2022, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.app.timedetector;
+package android.view.accessibility;
-parcelable GnssTimeSuggestion;
+parcelable AccessibilityWindowAttributes;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowAttributes.java b/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
new file mode 100644
index 000000000000..562300c62f6d
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.view.WindowManager;
+
+/**
+ * This class represents the attributes of a window needed for {@link AccessibilityWindowInfo}.
+ *
+ * @hide
+ */
+public final class AccessibilityWindowAttributes implements Parcelable {
+
+ private final CharSequence mWindowTitle;
+
+ public AccessibilityWindowAttributes(@NonNull WindowManager.LayoutParams layoutParams) {
+ mWindowTitle = populateWindowTitle(layoutParams);
+ }
+
+ private AccessibilityWindowAttributes(Parcel in) {
+ mWindowTitle = in.readCharSequence();
+ }
+
+ public CharSequence getWindowTitle() {
+ return mWindowTitle;
+ }
+
+ private CharSequence populateWindowTitle(@NonNull WindowManager.LayoutParams layoutParams) {
+ CharSequence windowTitle = layoutParams.accessibilityTitle;
+ // Panel windows have no public way to set the a11y title directly. Use the
+ // regular title as a fallback.
+ final boolean isPanelWindow =
+ (layoutParams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW)
+ && (layoutParams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW);
+ // Accessibility overlays should have titles that work for accessibility, and can't set
+ // the a11y title themselves.
+ final boolean isAccessibilityOverlay =
+ layoutParams.type == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+
+ if (TextUtils.isEmpty(windowTitle) && (isPanelWindow
+ || isAccessibilityOverlay)) {
+ windowTitle = TextUtils.isEmpty(layoutParams.getTitle()) ? null
+ : layoutParams.getTitle();
+ }
+ return windowTitle;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AccessibilityWindowAttributes)) return false;
+
+ AccessibilityWindowAttributes that = (AccessibilityWindowAttributes) o;
+
+ return TextUtils.equals(mWindowTitle, that.mWindowTitle);
+ }
+
+ @Override
+ public int hashCode() {
+ return mWindowTitle.hashCode();
+ }
+
+ public static final Creator<AccessibilityWindowAttributes> CREATOR =
+ new Creator<AccessibilityWindowAttributes>() {
+ @Override
+ public AccessibilityWindowAttributes createFromParcel(Parcel in) {
+ return new AccessibilityWindowAttributes(in);
+ }
+
+ @Override
+ public AccessibilityWindowAttributes[] newArray(int size) {
+ return new AccessibilityWindowAttributes[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeCharSequence(mWindowTitle);
+ }
+
+ @Override
+ public String toString() {
+ return "AccessibilityWindowAttributes{"
+ + "mAccessibilityWindowTitle=" + mWindowTitle
+ + '}';
+ }
+}
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 4fc9a077299a..1e060987b69f 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -25,6 +25,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
import android.view.accessibility.IAccessibilityManagerClient;
+import android.view.accessibility.AccessibilityWindowAttributes;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.IWindow;
@@ -105,4 +106,6 @@ interface IAccessibilityManager {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_SYSTEM_AUDIO_CAPTION)")
void setSystemAudioCaptioningUiEnabled(boolean isEnabled, int userId);
+
+ oneway void setAccessibilityWindowAttributes(int displayId, int windowId, int userId, in AccessibilityWindowAttributes attributes);
}
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
index 3111fe0cb875..489e70242a95 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java
@@ -18,10 +18,13 @@ package android.view.inputmethod;
import android.annotation.AnyThread;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.inputmethod.DirectBootAwareness;
@@ -54,8 +57,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void addClient(IInputMethodClient client, IRemoteInputConnection fallbackInputConnection,
- int untrustedDisplayId) {
+ void addClient(@NonNull IInputMethodClient client,
+ @NonNull IRemoteInputConnection fallbackInputConnection, int untrustedDisplayId) {
try {
mTarget.addClient(client, fallbackInputConnection, untrustedDisplayId);
} catch (RemoteException e) {
@@ -64,6 +67,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
+ @NonNull
List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) {
try {
return mTarget.getInputMethodList(userId);
@@ -73,6 +77,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
+ @NonNull
List<InputMethodInfo> getAwareLockedInputMethodList(@UserIdInt int userId,
@DirectBootAwareness int directBootAwareness) {
try {
@@ -83,6 +88,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
+ @NonNull
List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) {
try {
return mTarget.getEnabledInputMethodList(userId);
@@ -92,7 +98,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
+ @NonNull
+ List<InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable String imiId,
boolean allowsImplicitlySelectedSubtypes) {
try {
return mTarget.getEnabledInputMethodSubtypeList(imiId,
@@ -103,6 +110,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
+ @Nullable
InputMethodSubtype getLastInputMethodSubtype() {
try {
return mTarget.getLastInputMethodSubtype();
@@ -112,8 +120,9 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- boolean showSoftInput(IInputMethodClient client, IBinder windowToken,
- int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+ boolean showSoftInput(@NonNull IInputMethodClient client, @Nullable IBinder windowToken,
+ int flags, @Nullable ResultReceiver resultReceiver,
+ @SoftInputShowHideReason int reason) {
try {
return mTarget.showSoftInput(client, windowToken, flags, resultReceiver, reason);
} catch (RemoteException e) {
@@ -122,8 +131,9 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- boolean hideSoftInput(IInputMethodClient client, IBinder windowToken,
- int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+ boolean hideSoftInput(@NonNull IInputMethodClient client, @Nullable IBinder windowToken,
+ int flags, @Nullable ResultReceiver resultReceiver,
+ @SoftInputShowHideReason int reason) {
try {
return mTarget.hideSoftInput(client, windowToken, flags, resultReceiver, reason);
} catch (RemoteException e) {
@@ -132,13 +142,14 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
+ @NonNull
InputBindResult startInputOrWindowGainedFocus(@StartInputReason int startInputReason,
- IInputMethodClient client, IBinder windowToken,
- @StartInputFlags int startInputFlags,
- @android.view.WindowManager.LayoutParams.SoftInputModeFlags int softInputMode,
- int windowFlags, EditorInfo editorInfo, IRemoteInputConnection remoteInputConnection,
- IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion, ImeOnBackInvokedDispatcher imeDispatcher) {
+ @NonNull IInputMethodClient client, @Nullable IBinder windowToken,
+ @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
+ @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
+ @Nullable IRemoteInputConnection remoteInputConnection,
+ @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
+ int unverifiedTargetSdkVersion, @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
try {
return mTarget.startInputOrWindowGainedFocus(startInputReason, client, windowToken,
startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
@@ -149,7 +160,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void showInputMethodPickerFromClient(IInputMethodClient client, int auxiliarySubtypeMode) {
+ void showInputMethodPickerFromClient(@NonNull IInputMethodClient client,
+ int auxiliarySubtypeMode) {
try {
mTarget.showInputMethodPickerFromClient(client, auxiliarySubtypeMode);
} catch (RemoteException e) {
@@ -158,8 +170,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void showInputMethodPickerFromSystem(IInputMethodClient client, int auxiliarySubtypeMode,
- int displayId) {
+ void showInputMethodPickerFromSystem(@NonNull IInputMethodClient client,
+ int auxiliarySubtypeMode, int displayId) {
try {
mTarget.showInputMethodPickerFromSystem(client, auxiliarySubtypeMode, displayId);
} catch (RemoteException e) {
@@ -168,7 +180,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient client, String imeId) {
+ void showInputMethodAndSubtypeEnablerFromClient(@NonNull IInputMethodClient client,
+ @Nullable String imeId) {
try {
mTarget.showInputMethodAndSubtypeEnablerFromClient(client, imeId);
} catch (RemoteException e) {
@@ -186,6 +199,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
+ @Nullable
InputMethodSubtype getCurrentInputMethodSubtype() {
try {
return mTarget.getCurrentInputMethodSubtype();
@@ -195,7 +209,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void setAdditionalInputMethodSubtypes(String imeId, InputMethodSubtype[] subtypes) {
+ void setAdditionalInputMethodSubtypes(@NonNull String imeId,
+ @NonNull InputMethodSubtype[] subtypes) {
try {
mTarget.setAdditionalInputMethodSubtypes(imeId, subtypes);
} catch (RemoteException e) {
@@ -204,7 +219,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- int getInputMethodWindowVisibleHeight(IInputMethodClient client) {
+ int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) {
try {
return mTarget.getInputMethodWindowVisibleHeight(client);
} catch (RemoteException e) {
@@ -213,8 +228,8 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void reportVirtualDisplayGeometryAsync(IInputMethodClient client, int childDisplayId,
- float[] matrixValues) {
+ void reportVirtualDisplayGeometryAsync(@NonNull IInputMethodClient client, int childDisplayId,
+ @Nullable float[] matrixValues) {
try {
mTarget.reportVirtualDisplayGeometryAsync(client, childDisplayId, matrixValues);
} catch (RemoteException e) {
@@ -223,7 +238,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
+ void reportPerceptibleAsync(@NonNull IBinder windowToken, boolean perceptible) {
try {
mTarget.reportPerceptibleAsync(windowToken, perceptible);
} catch (RemoteException e) {
@@ -232,7 +247,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void removeImeSurfaceFromWindowAsync(IBinder windowToken) {
+ void removeImeSurfaceFromWindowAsync(@NonNull IBinder windowToken) {
try {
mTarget.removeImeSurfaceFromWindowAsync(windowToken);
} catch (RemoteException e) {
@@ -241,7 +256,7 @@ final class IInputMethodManagerInvoker {
}
@AnyThread
- void startStylusHandwriting(IInputMethodClient client) {
+ void startStylusHandwriting(@NonNull IInputMethodClient client) {
try {
mTarget.startStylusHandwriting(client);
} catch (RemoteException e) {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 8f6a42f7a43a..52947a54e167 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -266,10 +266,10 @@ import java.util.function.Consumer;
@SystemService(Context.INPUT_METHOD_SERVICE)
@RequiresFeature(PackageManager.FEATURE_INPUT_METHODS)
public final class InputMethodManager {
- static final boolean DEBUG = false;
- static final String TAG = "InputMethodManager";
+ private static final boolean DEBUG = false;
+ private static final String TAG = "InputMethodManager";
- static final String PENDING_EVENT_COUNTER = "aq:imm";
+ private static final String PENDING_EVENT_COUNTER = "aq:imm";
private static final int NOT_A_SUBTYPE_ID = -1;
@@ -361,7 +361,7 @@ public final class InputMethodManager {
/**
* Timeout in milliseconds for delivering a key to an IME.
*/
- static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500;
+ private static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500;
/** @hide */
public static final int DISPATCH_IN_PROGRESS = -1;
@@ -400,7 +400,7 @@ public final class InputMethodManager {
@Deprecated
@UnsupportedAppUsage
final IInputMethodManager mService;
- final Looper mMainLooper;
+ private final Looper mMainLooper;
@NonNull
private final IInputMethodManagerInvoker mServiceInvoker;
@@ -422,7 +422,7 @@ public final class InputMethodManager {
/**
* True if this input method client is active, initially false.
*/
- boolean mActive = false;
+ private boolean mActive = false;
/**
* {@code true} if next {@link ImeFocusController#onPostWindowFocus} needs to
@@ -433,7 +433,7 @@ public final class InputMethodManager {
/**
* As reported by IME through InputConnection.
*/
- boolean mFullscreenMode;
+ private boolean mFullscreenMode;
// -----------------------------------------------------------
@@ -447,33 +447,33 @@ public final class InputMethodManager {
* This is set when we are in the process of connecting, to determine
* when we have actually finished.
*/
- boolean mServedConnecting;
+ private boolean mServedConnecting;
/**
* This is non-null when we have connected the served view; it holds
* the attributes that were last retrieved from the served view and given
* to the input connection.
*/
- EditorInfo mCurrentEditorInfo;
+ private EditorInfo mCurrentEditorInfo;
/**
* The InputConnection that was last retrieved from the served view.
*/
- RemoteInputConnectionImpl mServedInputConnection;
+ private RemoteInputConnectionImpl mServedInputConnection;
/**
* The completions that were last provided by the served view.
*/
- CompletionInfo[] mCompletions;
+ private CompletionInfo[] mCompletions;
// Cursor position on the screen.
@UnsupportedAppUsage
Rect mTmpCursorRect = new Rect();
@UnsupportedAppUsage
Rect mCursorRect = new Rect();
- int mCursorSelStart;
- int mCursorSelEnd;
- int mCursorCandStart;
- int mCursorCandEnd;
- int mInitialSelStart;
- int mInitialSelEnd;
+ private int mCursorSelStart;
+ private int mCursorSelEnd;
+ private int mCursorCandStart;
+ private int mCursorCandEnd;
+ private int mInitialSelStart;
+ private int mInitialSelEnd;
/**
* Handler for {@link RemoteInputConnectionImpl#getInputConnection()}.
@@ -534,8 +534,8 @@ public final class InputMethodManager {
private final SparseArray<IAccessibilityInputMethodSessionInvoker>
mAccessibilityInputMethodSession = new SparseArray<>();
- InputChannel mCurChannel;
- ImeInputEventSender mCurSender;
+ private InputChannel mCurChannel;
+ private ImeInputEventSender mCurSender;
private static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_NONE = 0x0;
@@ -551,25 +551,25 @@ public final class InputMethodManager {
*/
private ImeInsetsSourceConsumer mImeInsetsConsumer;
- final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
- final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
+ private final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
+ private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
- final DelegateImpl mDelegate = new DelegateImpl();
+ private final DelegateImpl mDelegate = new DelegateImpl();
// -----------------------------------------------------------
- static final int MSG_DUMP = 1;
- static final int MSG_BIND = 2;
- static final int MSG_UNBIND = 3;
- static final int MSG_SET_ACTIVE = 4;
- static final int MSG_SEND_INPUT_EVENT = 5;
- static final int MSG_TIMEOUT_INPUT_EVENT = 6;
- static final int MSG_FLUSH_INPUT_EVENT = 7;
- static final int MSG_REPORT_FULLSCREEN_MODE = 10;
- static final int MSG_BIND_ACCESSIBILITY_SERVICE = 11;
- static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 12;
- static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30;
- static final int MSG_ON_SHOW_REQUESTED = 31;
+ private static final int MSG_DUMP = 1;
+ private static final int MSG_BIND = 2;
+ private static final int MSG_UNBIND = 3;
+ private static final int MSG_SET_ACTIVE = 4;
+ private static final int MSG_SEND_INPUT_EVENT = 5;
+ private static final int MSG_TIMEOUT_INPUT_EVENT = 6;
+ private static final int MSG_FLUSH_INPUT_EVENT = 7;
+ private static final int MSG_REPORT_FULLSCREEN_MODE = 10;
+ private static final int MSG_BIND_ACCESSIBILITY_SERVICE = 11;
+ private static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 12;
+ private static final int MSG_UPDATE_VIRTUAL_DISPLAY_TO_SCREEN_MATRIX = 30;
+ private static final int MSG_ON_SHOW_REQUESTED = 31;
private static boolean isAutofillUIShowing(View servedView) {
AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class);
@@ -637,7 +637,7 @@ public final class InputMethodManager {
* {@link android.view.WindowInsetsController}.
* @hide
*/
- public void reportPerceptible(IBinder windowToken, boolean perceptible) {
+ public void reportPerceptible(@NonNull IBinder windowToken, boolean perceptible) {
mServiceInvoker.reportPerceptibleAsync(windowToken, perceptible);
}
@@ -921,7 +921,7 @@ public final class InputMethodManager {
mRequestUpdateCursorAnchorInfoMonitorMode =
REQUEST_UPDATE_CURSOR_ANCHOR_INFO_NONE;
- setInputChannelLocked(res.channel);
+ updateInputChannelLocked(res.channel);
mCurMethod = res.method; // for @UnsupportedAppUsage
mCurBindState = new BindState(res);
mCurId = res.id; // for @UnsupportedAppUsage
@@ -1142,7 +1142,7 @@ public final class InputMethodManager {
}
}
- final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
+ private final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
// No need to check for dump permission, since we only give this
@@ -1396,6 +1396,7 @@ public final class InputMethodManager {
*
* @return {@link List} of {@link InputMethodInfo}.
*/
+ @NonNull
public List<InputMethodInfo> getInputMethodList() {
// We intentionally do not use UserHandle.getCallingUserId() here because for system
// services InputMethodManagerInternal.getInputMethodListAsUser() should be used
@@ -1474,6 +1475,7 @@ public final class InputMethodManager {
*
* @return {@link List} of {@link InputMethodInfo}.
*/
+ @NonNull
public List<InputMethodInfo> getEnabledInputMethodList() {
// We intentionally do not use UserHandle.getCallingUserId() here because for system
// services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used
@@ -1498,12 +1500,14 @@ public final class InputMethodManager {
*
* <p>On multi user environment, this API returns a result for the calling process user.</p>
*
- * @param imi An input method info whose subtypes list will be returned.
+ * @param imi The {@link InputMethodInfo} whose subtypes list will be returned. If {@code null},
+ * returns enabled subtypes for the currently selected {@link InputMethodInfo}.
* @param allowsImplicitlySelectedSubtypes A boolean flag to allow to return the implicitly
* selected subtypes. If an input method info doesn't have enabled subtypes, the framework
* will implicitly enable subtypes according to the current system language.
*/
- public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
+ @NonNull
+ public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(@Nullable InputMethodInfo imi,
boolean allowsImplicitlySelectedSubtypes) {
return mServiceInvoker.getEnabledInputMethodSubtypeList(
imi == null ? null : imi.getId(),
@@ -1620,10 +1624,10 @@ public final class InputMethodManager {
* Reset all of the state associated with being bound to an input method.
*/
@GuardedBy("mH")
- void clearBindingLocked() {
+ private void clearBindingLocked() {
if (DEBUG) Log.v(TAG, "Clearing binding!");
clearConnectionLocked();
- setInputChannelLocked(null);
+ updateInputChannelLocked(null);
mCurId = null; // for @UnsupportedAppUsage
mCurMethod = null; // for @UnsupportedAppUsage
// We only reset sequence number for input method, but not accessibility.
@@ -1634,47 +1638,57 @@ public final class InputMethodManager {
* Reset all of the state associated with being bound to an accessibility service.
*/
@GuardedBy("mH")
- void clearAccessibilityBindingLocked(int id) {
+ private void clearAccessibilityBindingLocked(int id) {
if (DEBUG) Log.v(TAG, "Clearing accessibility binding " + id);
mAccessibilityInputMethodSession.remove(id);
}
/**
- * Reset all of the state associated with being bound to all ccessibility services.
+ * Reset all of the state associated with being bound to all accessibility services.
*/
@GuardedBy("mH")
- void clearAllAccessibilityBindingLocked() {
+ private void clearAllAccessibilityBindingLocked() {
if (DEBUG) Log.v(TAG, "Clearing all accessibility bindings");
mAccessibilityInputMethodSession.clear();
}
- void setInputChannelLocked(InputChannel channel) {
- if (mCurChannel == channel) {
- return;
- }
- if (mCurChannel != null && channel != null
- && mCurChannel.getToken() == channel.getToken()) {
- // channel is a dupe of 'mCurChannel', because they have the same token, and represent
- // the same connection. Ignore the incoming channel and keep using 'mCurChannel' to
- // avoid confusing the InputEventReceiver.
+ @GuardedBy("mH")
+ private void updateInputChannelLocked(InputChannel channel) {
+ if (areSameInputChannel(mCurChannel, channel)) {
return;
}
+ // TODO(b/238720598) : Requirements when design a new protocol for InputChannel
+ // channel is a dupe of 'mCurChannel', because they have the same token, and represent
+ // the same connection. Ignore the incoming channel and keep using 'mCurChannel' to
+ // avoid confusing the InputEventReceiver.
if (mCurSender != null) {
flushPendingEventsLocked();
mCurSender.dispose();
mCurSender = null;
}
+
if (mCurChannel != null) {
mCurChannel.dispose();
}
mCurChannel = channel;
}
+ private static boolean areSameInputChannel(@Nullable InputChannel lhs,
+ @Nullable InputChannel rhs) {
+ if (lhs == rhs) {
+ return true;
+ }
+ if (lhs == null || rhs == null) {
+ return false;
+ }
+ return lhs.getToken() == rhs.getToken();
+ }
+
/**
* Reset all of the state associated with a served view being connected
* to an input method
*/
- void clearConnectionLocked() {
+ private void clearConnectionLocked() {
mCurrentEditorInfo = null;
if (mServedInputConnection != null) {
mServedInputConnection.deactivate();
@@ -2224,7 +2238,7 @@ public final class InputMethodManager {
* Note that this method should *NOT* be called inside of {@code mH} lock to prevent start input
* background thread may blocked by other methods which already inside {@code mH} lock.
*/
- boolean startInputInner(@StartInputReason int startInputReason,
+ private boolean startInputInner(@StartInputReason int startInputReason,
@Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags,
@SoftInputModeFlags int softInputMode, int windowFlags) {
final View view;
@@ -2384,7 +2398,7 @@ public final class InputMethodManager {
}
mVirtualDisplayToScreenMatrix = res.getVirtualDisplayToScreenMatrix();
if (res.id != null) {
- setInputChannelLocked(res.channel);
+ updateInputChannelLocked(res.channel);
mCurMethod = res.method; // for @UnsupportedAppUsage
mCurBindState = new BindState(res);
mAccessibilityInputMethodSession.clear();
@@ -2596,7 +2610,7 @@ public final class InputMethodManager {
* @param windowToken The client window token that requests the IME to remove its surface.
* @hide
*/
- public void removeImeSurface(IBinder windowToken) {
+ public void removeImeSurface(@NonNull IBinder windowToken) {
synchronized (mH) {
mServiceInvoker.removeImeSurfaceFromWindowAsync(windowToken);
}
@@ -3065,7 +3079,7 @@ public final class InputMethodManager {
}
// Must be called on the main looper
- void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
+ private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
final boolean handled;
synchronized (mH) {
int result = sendInputEventOnMainLooperLocked(p);
@@ -3080,7 +3094,7 @@ public final class InputMethodManager {
}
// Must be called on the main looper
- int sendInputEventOnMainLooperLocked(PendingEvent p) {
+ private int sendInputEventOnMainLooperLocked(PendingEvent p) {
if (mCurChannel != null) {
if (mCurSender == null) {
mCurSender = new ImeInputEventSender(mCurChannel, mH.getLooper());
@@ -3105,7 +3119,7 @@ public final class InputMethodManager {
return DISPATCH_NOT_HANDLED;
}
- void finishedInputEvent(int seq, boolean handled, boolean timeout) {
+ private void finishedInputEvent(int seq, boolean handled, boolean timeout) {
final PendingEvent p;
synchronized (mH) {
int index = mPendingEvents.indexOfKey(seq);
@@ -3129,7 +3143,7 @@ public final class InputMethodManager {
}
// Assumes the event has already been removed from the queue.
- void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) {
+ private void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) {
p.mHandled = handled;
if (p.mHandler.getLooper().isCurrentThread()) {
// Already running on the callback handler thread so we can send the
@@ -3228,7 +3242,7 @@ public final class InputMethodManager {
* @param imiId An input method, whose subtypes settings will be shown. If imiId is null,
* subtypes of all input methods will be shown.
*/
- public void showInputMethodAndSubtypeEnabler(String imiId) {
+ public void showInputMethodAndSubtypeEnabler(@Nullable String imiId) {
mServiceInvoker.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId);
}
@@ -3237,6 +3251,7 @@ public final class InputMethodManager {
* the current input method. This method returns null when the current input method doesn't
* have any input method subtype.
*/
+ @Nullable
public InputMethodSubtype getCurrentInputMethodSubtype() {
return mServiceInvoker.getCurrentInputMethodSubtype();
}
@@ -3471,10 +3486,12 @@ public final class InputMethodManager {
* of "Additional Subtype" may be completely dropped in a future version of Android.
*/
@Deprecated
- public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
+ public void setAdditionalInputMethodSubtypes(@NonNull String imiId,
+ @NonNull InputMethodSubtype[] subtypes) {
mServiceInvoker.setAdditionalInputMethodSubtypes(imiId, subtypes);
}
+ @Nullable
public InputMethodSubtype getLastInputMethodSubtype() {
return mServiceInvoker.getLastInputMethodSubtype();
}
@@ -3489,7 +3506,7 @@ public final class InputMethodManager {
return mDisplayId;
}
- void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ private void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
if (processDump(fd, args)) {
return;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 83d77172031e..b7bb09153fcc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6456,9 +6456,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void setText(CharSequence text, BufferType type) {
setText(text, type, true, 0);
- if (mCharWrapper != null) {
- mCharWrapper.mChars = null;
- }
+ // drop any potential mCharWrappper leaks
+ mCharWrapper = null;
}
@UnsupportedAppUsage
@@ -6672,11 +6671,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* since the TextView has no way to know that the text
* has changed and that it needs to invalidate and re-layout.
*
+ * @throws NullPointerException if text is null
+ * @throws IndexOutOfBoundsException if start or start+len are not in 0 to text.length
+ *
* @param text char array to be displayed
* @param start start index in the char array
* @param len length of char count after {@code start}
*/
- public final void setText(char[] text, int start, int len) {
+ public final void setText(@NonNull char[] text, int start, int len) {
int oldlen = 0;
if (start < 0 || len < 0 || start + len > text.length) {
@@ -13942,16 +13944,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private static class CharWrapper implements CharSequence, GetChars, GraphicsOperations {
+ @NonNull
private char[] mChars;
private int mStart, mLength;
- public CharWrapper(char[] chars, int start, int len) {
+ CharWrapper(@NonNull char[] chars, int start, int len) {
mChars = chars;
mStart = start;
mLength = len;
}
- /* package */ void set(char[] chars, int start, int len) {
+ /* package */ void set(@NonNull char[] chars, int start, int len) {
mChars = chars;
mStart = start;
mLength = len;
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 681693b1dbad..4b01357877ed 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -129,6 +129,7 @@ interface IVoiceInteractionManagerService {
* @param activityToken optional token of activity that needs to be on top
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
boolean showSessionForActiveService(in Bundle args, int sourceFlags,
IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken);
@@ -136,6 +137,7 @@ interface IVoiceInteractionManagerService {
* Hides the session from the active service, if it is showing.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
void hideCurrentSession();
/**
@@ -143,12 +145,14 @@ interface IVoiceInteractionManagerService {
* be called if {@link #activeServiceSupportsLaunchFromKeyguard()} returns true.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
void launchVoiceAssistFromKeyguard();
/**
* Indicates whether there is a voice session running (but not necessarily showing).
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
boolean isSessionRunning();
/**
@@ -156,6 +160,7 @@ interface IVoiceInteractionManagerService {
* assist gesture.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
boolean activeServiceSupportsAssist();
/**
@@ -163,18 +168,21 @@ interface IVoiceInteractionManagerService {
* from the lockscreen.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
boolean activeServiceSupportsLaunchFromKeyguard();
/**
* Called when the lockscreen got shown.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
void onLockscreenShown();
/**
* Register a voice interaction listener.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
void registerVoiceInteractionSessionListener(IVoiceInteractionSessionListener listener);
/**
@@ -182,6 +190,7 @@ interface IVoiceInteractionManagerService {
* Returns all supported voice actions.
* @RequiresPermission Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
void getActiveServiceSupportedActions(in List<String> voiceActions,
in IVoiceActionCheckCallback callback);
@@ -214,6 +223,7 @@ interface IVoiceInteractionManagerService {
* NOTE: it's only effective when the service itself is available / enabled in the device, so
* calling setDisable(false) would be a no-op when it isn't.
*/
+ @EnforcePermission("ACCESS_VOICE_INTERACTION_SERVICE")
void setDisabled(boolean disabled);
/**
@@ -244,6 +254,7 @@ interface IVoiceInteractionManagerService {
* @param callback Use this to report {@link HotwordDetectionService} status.
* @param detectorType Indicate which detector is used.
*/
+ @EnforcePermission("MANAGE_HOTWORD_DETECTION")
void updateState(
in Identity originatorIdentity,
in PersistableBundle options,
@@ -256,6 +267,7 @@ interface IVoiceInteractionManagerService {
*/
void shutdownHotwordDetectionService();
+ @EnforcePermission(allOf={"RECORD_AUDIO", "CAPTURE_AUDIO_HOTWORD"})
void startListeningFromMic(
in AudioFormat audioFormat,
in IMicrophoneHotwordDetectionVoiceInteractionCallback callback);
@@ -271,6 +283,7 @@ interface IVoiceInteractionManagerService {
/**
* Test API to simulate to trigger hardware recognition event for test.
*/
+ @EnforcePermission(allOf={"RECORD_AUDIO", "CAPTURE_AUDIO_HOTWORD"})
void triggerHardwareRecognitionEventForTest(
in SoundTrigger.KeyphraseRecognitionEvent event,
in IHotwordRecognitionStatusCallback callback);
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 737d5e348249..b32afb44852a 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -417,8 +417,9 @@ public class ResolverListAdapter extends BaseAdapter {
if (ii == null) {
continue;
}
- ActivityInfo ai = ii.resolveActivityInfo(
- mPm, 0);
+ // Because of AIDL bug, resolveActivityInfo can't accept subclasses of Intent.
+ final Intent rii = (ii.getClass() == Intent.class) ? ii : new Intent(ii);
+ ActivityInfo ai = rii.resolveActivityInfo(mPm, 0);
if (ai == null) {
Log.w(TAG, "No activity found for " + ii);
continue;
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 100fcd817812..01dcf9624ed5 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -136,12 +136,15 @@ public class ResolverListController {
int baseFlags) {
List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null;
for (int i = 0, N = intents.size(); i < N; i++) {
- final Intent intent = intents.get(i);
+ Intent intent = intents.get(i);
int flags = baseFlags;
if (intent.isWebIntent()
|| (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
flags |= PackageManager.MATCH_INSTANT;
}
+ // Because of AIDL bug, queryIntentActivitiesAsUser can't accept subclasses of Intent.
+ intent = (intent.getClass() == Intent.class) ? intent : new Intent(
+ intent);
final List<ResolveInfo> infos = mpm.queryIntentActivitiesAsUser(intent, flags,
userHandle);
if (infos != null) {
diff --git a/core/java/com/android/internal/graphics/fonts/IFontManager.aidl b/core/java/com/android/internal/graphics/fonts/IFontManager.aidl
index 87df5eb9e75a..512ace6145c6 100644
--- a/core/java/com/android/internal/graphics/fonts/IFontManager.aidl
+++ b/core/java/com/android/internal/graphics/fonts/IFontManager.aidl
@@ -28,6 +28,7 @@ import java.util.List;
* @hide
*/
interface IFontManager {
+ @EnforcePermission("UPDATE_FONTS")
FontConfig getFontConfig();
int updateFontFamily(in List<FontUpdateRequest> request, int baseVersion);
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 825b486d0635..dbfa4d35974b 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -26,10 +26,12 @@ import static android.view.SurfaceControl.JankData.SURFACE_FLINGER_SCHEDULING;
import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_CANCEL;
import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_END;
+import static com.android.internal.jank.InteractionJankMonitor.EXECUTOR_TASK_TIMEOUT;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiThread;
import android.graphics.HardwareRendererObserver;
import android.os.Handler;
import android.os.Trace;
@@ -85,8 +87,9 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
public @interface Reasons {
}
+ @VisibleForTesting
+ public final InteractionJankMonitor mMonitor;
private final HardwareRendererObserver mObserver;
- private SurfaceControl mSurfaceControl;
private final int mTraceThresholdMissedFrames;
private final int mTraceThresholdFrameTimeMillis;
private final ThreadedRendererWrapper mRendererWrapper;
@@ -99,17 +102,17 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
private final Handler mHandler;
private final ChoreographerWrapper mChoreographer;
private final StatsLogWrapper mStatsLog;
- private final Object mLock = InteractionJankMonitor.getInstance().getLock();
private final boolean mDeferMonitoring;
+ private final FrameTrackerListener mListener;
@VisibleForTesting
public final boolean mSurfaceOnly;
+ private SurfaceControl mSurfaceControl;
private long mBeginVsyncId = INVALID_ID;
private long mEndVsyncId = INVALID_ID;
private boolean mMetricsFinalized;
private boolean mCancelled = false;
- private FrameTrackerListener mListener;
private boolean mTracingStarted = false;
private Runnable mWaitForFinishTimedOut;
@@ -142,16 +145,52 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
this.jankType = jankType;
this.isFirstFrame = isFirstFrame;
}
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder();
+ switch (jankType) {
+ case JANK_NONE:
+ str.append("JANK_NONE");
+ break;
+ case JANK_APP_DEADLINE_MISSED:
+ str.append("JANK_APP_DEADLINE_MISSED");
+ break;
+ case JANK_SURFACEFLINGER_DEADLINE_MISSED:
+ str.append("JANK_SURFACEFLINGER_DEADLINE_MISSED");
+ break;
+ case JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED:
+ str.append("JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED");
+ break;
+ case DISPLAY_HAL:
+ str.append("DISPLAY_HAL");
+ break;
+ case PREDICTION_ERROR:
+ str.append("PREDICTION_ERROR");
+ break;
+ case SURFACE_FLINGER_SCHEDULING:
+ str.append("SURFACE_FLINGER_SCHEDULING");
+ break;
+ default:
+ str.append("UNKNOWN: ").append(jankType);
+ break;
+ }
+ str.append(", ").append(frameVsyncId);
+ str.append(", ").append(totalDurationNanos);
+ return str.toString();
+ }
}
- public FrameTracker(@NonNull Session session, @NonNull Handler handler,
- @Nullable ThreadedRendererWrapper renderer, @Nullable ViewRootWrapper viewRootWrapper,
+ public FrameTracker(@NonNull InteractionJankMonitor monitor, @NonNull Session session,
+ @NonNull Handler handler, @Nullable ThreadedRendererWrapper renderer,
+ @Nullable ViewRootWrapper viewRootWrapper,
@NonNull SurfaceControlWrapper surfaceControlWrapper,
@NonNull ChoreographerWrapper choreographer,
@Nullable FrameMetricsWrapper metrics,
@NonNull StatsLogWrapper statsLog,
int traceThresholdMissedFrames, int traceThresholdFrameTimeMillis,
@Nullable FrameTrackerListener listener, @NonNull Configuration config) {
+ mMonitor = monitor;
mSurfaceOnly = config.isSurfaceOnly();
mSession = session;
mHandler = handler;
@@ -186,17 +225,15 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
mSurfaceChangedCallback = new ViewRootImpl.SurfaceChangedCallback() {
@Override
public void surfaceCreated(SurfaceControl.Transaction t) {
- synchronized (mLock) {
+ getHandler().runWithScissors(() -> {
if (mSurfaceControl == null) {
mSurfaceControl = mViewRoot.getSurfaceControl();
if (mBeginVsyncId != INVALID_ID) {
- mSurfaceControlWrapper.addJankStatsListener(
- FrameTracker.this, mSurfaceControl);
- markEvent("FT#deferMonitoring");
- postTraceStartMarker();
+ // Previous begin invocation is not successfully, begin it again.
+ begin();
}
}
- }
+ }, EXECUTOR_TASK_TIMEOUT);
}
@Override
@@ -208,18 +245,16 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
// Wait a while to give the system a chance for the remaining
// frames to arrive, then force finish the session.
- mHandler.postDelayed(() -> {
- synchronized (mLock) {
- if (DEBUG) {
- Log.d(TAG, "surfaceDestroyed: " + mSession.getName()
- + ", finalized=" + mMetricsFinalized
- + ", info=" + mJankInfos.size()
- + ", vsync=" + mBeginVsyncId);
- }
- if (!mMetricsFinalized) {
- end(REASON_END_SURFACE_DESTROYED);
- finish();
- }
+ getHandler().postDelayed(() -> {
+ if (DEBUG) {
+ Log.d(TAG, "surfaceDestroyed: " + mSession.getName()
+ + ", finalized=" + mMetricsFinalized
+ + ", info=" + mJankInfos.size()
+ + ", vsync=" + mBeginVsyncId);
+ }
+ if (!mMetricsFinalized) {
+ end(REASON_END_SURFACE_DESTROYED);
+ finish();
}
}, 50);
}
@@ -230,35 +265,42 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
}
}
+ @VisibleForTesting
+ public Handler getHandler() {
+ return mHandler;
+ }
+
/**
* Begin a trace session of the CUJ.
*/
+ @UiThread
public void begin() {
- synchronized (mLock) {
- final long currentVsync = mChoreographer.getVsyncId();
- // In normal case, we should begin at the next frame,
- // the id of the next frame is not simply increased by 1,
- // but we can exclude the current frame at least.
+ final long currentVsync = mChoreographer.getVsyncId();
+ // In normal case, we should begin at the next frame,
+ // the id of the next frame is not simply increased by 1,
+ // but we can exclude the current frame at least.
+ if (mBeginVsyncId == INVALID_ID) {
mBeginVsyncId = mDeferMonitoring ? currentVsync + 1 : currentVsync;
+ }
+ if (mSurfaceControl != null) {
if (DEBUG) {
Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId
- + ", defer=" + mDeferMonitoring);
+ + ", defer=" + mDeferMonitoring + ", current=" + currentVsync);
}
- if (mSurfaceControl != null) {
- if (mDeferMonitoring) {
- markEvent("FT#deferMonitoring");
- // Normal case, we begin the instrument from the very beginning,
- // will exclude the first frame.
- postTraceStartMarker();
- } else {
- // If we don't begin the instrument from the very beginning,
- // there is no need to skip the frame where the begin invocation happens.
- beginInternal();
- }
- mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
+ if (mDeferMonitoring && currentVsync < mBeginVsyncId) {
+ markEvent("FT#deferMonitoring");
+ // Normal case, we begin the instrument from the very beginning,
+ // will exclude the first frame.
+ postTraceStartMarker(this::beginInternal);
+ } else {
+ // If we don't begin the instrument from the very beginning,
+ // there is no need to skip the frame where the begin invocation happens.
+ beginInternal();
}
- if (!mSurfaceOnly) {
- mRendererWrapper.addObserver(mObserver);
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "begin: defer beginning since the surface is not ready for CUJ="
+ + mSession.getName());
}
}
}
@@ -267,89 +309,89 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
* Start trace section at appropriate time.
*/
@VisibleForTesting
- public void postTraceStartMarker() {
- mChoreographer.mChoreographer.postCallback(
- Choreographer.CALLBACK_INPUT, this::beginInternal, null);
+ public void postTraceStartMarker(Runnable action) {
+ mChoreographer.mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, action, null);
}
+ @UiThread
private void beginInternal() {
- synchronized (mLock) {
- if (mCancelled || mEndVsyncId != INVALID_ID) {
- return;
- }
- mTracingStarted = true;
- markEvent("FT#begin");
- Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ if (mCancelled || mEndVsyncId != INVALID_ID) {
+ return;
+ }
+ mTracingStarted = true;
+ markEvent("FT#begin");
+ Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
+ if (!mSurfaceOnly) {
+ mRendererWrapper.addObserver(mObserver);
}
}
/**
* End the trace session of the CUJ.
*/
+ @UiThread
public boolean end(@Reasons int reason) {
- synchronized (mLock) {
- if (mCancelled || mEndVsyncId != INVALID_ID) return false;
- mEndVsyncId = mChoreographer.getVsyncId();
- // Cancel the session if:
- // 1. The session begins and ends at the same vsync id.
- // 2. The session never begun.
- if (mBeginVsyncId == INVALID_ID) {
- return cancel(REASON_CANCEL_NOT_BEGUN);
- } else if (mEndVsyncId <= mBeginVsyncId) {
- return cancel(REASON_CANCEL_SAME_VSYNC);
- } else {
- if (DEBUG) {
- Log.d(TAG, "end: " + mSession.getName()
- + ", end=" + mEndVsyncId + ", reason=" + reason);
- }
- markEvent("FT#end#" + reason);
- Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
- mSession.setReason(reason);
-
- // We don't remove observer here,
- // will remove it when all the frame metrics in this duration are called back.
- // See onFrameMetricsAvailable for the logic of removing the observer.
- // Waiting at most 10 seconds for all callbacks to finish.
- mWaitForFinishTimedOut = () -> {
- Log.e(TAG, "force finish cuj because of time out:" + mSession.getName());
- finish();
- };
- mHandler.postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10));
- notifyCujEvent(ACTION_SESSION_END);
- return true;
+ if (mCancelled || mEndVsyncId != INVALID_ID) return false;
+ mEndVsyncId = mChoreographer.getVsyncId();
+ // Cancel the session if:
+ // 1. The session begins and ends at the same vsync id.
+ // 2. The session never begun.
+ if (mBeginVsyncId == INVALID_ID) {
+ return cancel(REASON_CANCEL_NOT_BEGUN);
+ } else if (mEndVsyncId <= mBeginVsyncId) {
+ return cancel(REASON_CANCEL_SAME_VSYNC);
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "end: " + mSession.getName()
+ + ", end=" + mEndVsyncId + ", reason=" + reason);
}
+ markEvent("FT#end#" + reason);
+ Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ mSession.setReason(reason);
+
+ // We don't remove observer here,
+ // will remove it when all the frame metrics in this duration are called back.
+ // See onFrameMetricsAvailable for the logic of removing the observer.
+ // Waiting at most 10 seconds for all callbacks to finish.
+ mWaitForFinishTimedOut = () -> {
+ Log.e(TAG, "force finish cuj because of time out:" + mSession.getName());
+ finish();
+ };
+ getHandler().postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10));
+ notifyCujEvent(ACTION_SESSION_END);
+ return true;
}
}
/**
* Cancel the trace session of the CUJ.
*/
+ @UiThread
public boolean cancel(@Reasons int reason) {
- synchronized (mLock) {
- final boolean cancelFromEnd =
- reason == REASON_CANCEL_NOT_BEGUN || reason == REASON_CANCEL_SAME_VSYNC;
- if (mCancelled || (mEndVsyncId != INVALID_ID && !cancelFromEnd)) return false;
- mCancelled = true;
- markEvent("FT#cancel#" + reason);
- // We don't need to end the trace section if it never begun.
- if (mTracingStarted) {
- Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
- }
-
- // Always remove the observers in cancel call to avoid leakage.
- removeObservers();
+ final boolean cancelFromEnd =
+ reason == REASON_CANCEL_NOT_BEGUN || reason == REASON_CANCEL_SAME_VSYNC;
+ if (mCancelled || (mEndVsyncId != INVALID_ID && !cancelFromEnd)) return false;
+ mCancelled = true;
+ markEvent("FT#cancel#" + reason);
+ // We don't need to end the trace section if it has never begun.
+ if (mTracingStarted) {
+ Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ }
- if (DEBUG) {
- Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId
- + ", end=" + mEndVsyncId + ", reason=" + reason);
- }
+ // Always remove the observers in cancel call to avoid leakage.
+ removeObservers();
- mSession.setReason(reason);
- // Notify the listener the session has been cancelled.
- // We don't notify the listeners if the session never begun.
- notifyCujEvent(ACTION_SESSION_CANCEL);
- return true;
+ if (DEBUG) {
+ Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId
+ + ", end=" + mEndVsyncId + ", reason=" + reason);
}
+
+ mSession.setReason(reason);
+ // Notify the listener the session has been cancelled.
+ // We don't notify the listeners if the session never begun.
+ notifyCujEvent(ACTION_SESSION_CANCEL);
+ return true;
}
private void markEvent(String desc) {
@@ -364,8 +406,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
@Override
public void onJankDataAvailable(SurfaceControl.JankData[] jankData) {
- synchronized (mLock) {
- if (mCancelled) {
+ postCallback(() -> {
+ if (mCancelled || mMetricsFinalized) {
return;
}
@@ -384,10 +426,19 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
}
}
processJankInfos();
- }
+ });
}
- private @Nullable JankInfo findJankInfo(long frameVsyncId) {
+ /**
+ * For easier argument capture.
+ */
+ @VisibleForTesting
+ public void postCallback(Runnable callback) {
+ getHandler().post(callback);
+ }
+
+ @Nullable
+ private JankInfo findJankInfo(long frameVsyncId) {
return mJankInfos.get((int) frameVsyncId);
}
@@ -400,8 +451,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
@Override
public void onFrameMetricsAvailable(int dropCountSinceLastInvocation) {
- synchronized (mLock) {
- if (mCancelled) {
+ postCallback(() -> {
+ if (mCancelled || mMetricsFinalized) {
return;
}
@@ -426,9 +477,10 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
frameVsyncId, totalDurationNanos, isFirstFrame));
}
processJankInfos();
- }
+ });
}
+ @UiThread
private boolean hasReceivedCallbacksAfterEnd() {
if (mEndVsyncId == INVALID_ID) {
return false;
@@ -451,6 +503,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
return false;
}
+ @UiThread
private void processJankInfos() {
if (mMetricsFinalized) {
return;
@@ -467,9 +520,12 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
: info.hwuiCallbackFired && info.surfaceControlCallbackFired;
}
+ @UiThread
private void finish() {
- mHandler.removeCallbacks(mWaitForFinishTimedOut);
+ getHandler().removeCallbacks(mWaitForFinishTimedOut);
mWaitForFinishTimedOut = null;
+ if (mMetricsFinalized || mCancelled) return;
+ markEvent("FT#finish#" + mJankInfos.size());
mMetricsFinalized = true;
// The tracing has been ended, remove the observer, see if need to trigger perfetto.
@@ -496,7 +552,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
totalFramesCount++;
boolean missedFrame = false;
if ((info.jankType & JANK_APP_DEADLINE_MISSED) != 0) {
- Log.w(TAG, "Missed App frame:" + info.jankType);
+ Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + mSession.getName());
missedAppFramesCount++;
missedFrame = true;
}
@@ -505,7 +561,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
|| (info.jankType & JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED) != 0
|| (info.jankType & SURFACE_FLINGER_SCHEDULING) != 0
|| (info.jankType & PREDICTION_ERROR) != 0) {
- Log.w(TAG, "Missed SF frame:" + info.jankType);
+ Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + mSession.getName());
missedSfFramesCount++;
missedFrame = true;
}
@@ -520,13 +576,15 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
// TODO (b/174755489): Early latch currently gets fired way too often, so we have
// to ignore it for now.
if (!mSurfaceOnly && !info.hwuiCallbackFired) {
- Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId);
+ Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId
+ + ", CUJ=" + mSession.getName());
}
}
if (!mSurfaceOnly && info.hwuiCallbackFired) {
maxFrameTimeNanos = Math.max(info.totalDurationNanos, maxFrameTimeNanos);
if (!info.surfaceControlCallbackFired) {
- Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId);
+ Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId
+ + ", CUJ=" + mSession.getName());
}
}
}
@@ -586,6 +644,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
* Remove all the registered listeners, observers and callbacks.
*/
@VisibleForTesting
+ @UiThread
public void removeObservers() {
mSurfaceControlWrapper.removeJankStatsListener(this);
if (!mSurfaceOnly) {
@@ -601,7 +660,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
* Trigger the prefetto daemon.
*/
public void triggerPerfetto() {
- InteractionJankMonitor.getInstance().trigger(mSession);
+ mMonitor.trigger(mSession);
}
/**
@@ -666,10 +725,18 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
mViewRoot = viewRoot;
}
+ /**
+ * {@link ViewRootImpl#addSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback)}
+ * @param callback {@link ViewRootImpl.SurfaceChangedCallback}
+ */
public void addSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback callback) {
mViewRoot.addSurfaceChangedCallback(callback);
}
+ /**
+ * {@link ViewRootImpl#removeSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback)}
+ * @param callback {@link ViewRootImpl.SurfaceChangedCallback}
+ */
public void removeSurfaceChangedCallback(ViewRootImpl.SurfaceChangedCallback callback) {
mViewRoot.removeSurfaceChangedCallback(callback);
}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 22340c6b0c55..8f10a5e3f049 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -53,6 +53,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_COLLAPSE_LOCK;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
@@ -85,8 +86,11 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UiThread;
+import android.annotation.WorkerThread;
import android.content.Context;
import android.os.Build;
+import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.provider.DeviceConfig;
@@ -97,6 +101,7 @@ import android.view.Choreographer;
import android.view.SurfaceControl;
import android.view.View;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.FrameTracker.ChoreographerWrapper;
import com.android.internal.jank.FrameTracker.FrameMetricsWrapper;
@@ -130,6 +135,7 @@ public class InteractionJankMonitor {
private static final String DEFAULT_WORKER_NAME = TAG + "-Worker";
private static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2L);
+ static final long EXECUTOR_TASK_TIMEOUT = 500;
private static final String SETTINGS_ENABLED_KEY = "enabled";
private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
private static final String SETTINGS_THRESHOLD_MISSED_FRAMES_KEY =
@@ -210,6 +216,7 @@ public class InteractionJankMonitor {
public static final int CUJ_USER_DIALOG_OPEN = 59;
public static final int CUJ_TASKBAR_EXPAND = 60;
public static final int CUJ_TASKBAR_COLLAPSE = 61;
+ public static final int CUJ_SHADE_CLEAR_ALL = 62;
private static final int NO_STATSD_LOGGING = -1;
@@ -280,6 +287,7 @@ public class InteractionJankMonitor {
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL,
};
private static volatile InteractionJankMonitor sInstance;
@@ -287,13 +295,14 @@ public class InteractionJankMonitor {
private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
this::updateProperties;
- private final FrameMetricsWrapper mMetrics;
+ @GuardedBy("mLock")
private final SparseArray<FrameTracker> mRunningTrackers;
+ @GuardedBy("mLock")
private final SparseArray<Runnable> mTimeoutActions;
private final HandlerThread mWorker;
private final Object mLock = new Object();
- private boolean mEnabled = DEFAULT_ENABLED;
+ private volatile boolean mEnabled = DEFAULT_ENABLED;
private int mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
private int mTraceThresholdMissedFrames = DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES;
private int mTraceThresholdFrameTimeMillis = DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS;
@@ -361,7 +370,8 @@ public class InteractionJankMonitor {
CUJ_SHADE_DIALOG_OPEN,
CUJ_USER_DIALOG_OPEN,
CUJ_TASKBAR_EXPAND,
- CUJ_TASKBAR_COLLAPSE
+ CUJ_TASKBAR_COLLAPSE,
+ CUJ_SHADE_CLEAR_ALL
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -394,9 +404,7 @@ public class InteractionJankMonitor {
mRunningTrackers = new SparseArray<>();
mTimeoutActions = new SparseArray<>();
mWorker = worker;
- mMetrics = new FrameMetricsWrapper();
mWorker.start();
- mEnabled = DEFAULT_ENABLED;
mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
// Post initialization to the background in case we're running on the main
@@ -409,10 +417,7 @@ public class InteractionJankMonitor {
DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
new HandlerExecutor(mWorker.getThreadHandler()),
mPropertiesChangedListener);
- }
-
- Object getLock() {
- return mLock;
+ mEnabled = DEFAULT_ENABLED;
}
/**
@@ -429,27 +434,27 @@ public class InteractionJankMonitor {
view == null ? null : new ThreadedRendererWrapper(view.getThreadedRenderer());
final ViewRootWrapper viewRoot =
view == null ? null : new ViewRootWrapper(view.getViewRootImpl());
-
final SurfaceControlWrapper surfaceControl = new SurfaceControlWrapper();
final ChoreographerWrapper choreographer =
new ChoreographerWrapper(Choreographer.getInstance());
+ final FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s);
+ final FrameMetricsWrapper frameMetrics = new FrameMetricsWrapper();
- synchronized (mLock) {
- FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s);
- return new FrameTracker(session, mWorker.getThreadHandler(),
- threadedRenderer, viewRoot, surfaceControl, choreographer,
- mMetrics, new FrameTracker.StatsLogWrapper(),
- mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis,
- eventsListener, config);
- }
+ return new FrameTracker(this, session, config.getHandler(), threadedRenderer, viewRoot,
+ surfaceControl, choreographer, frameMetrics, new FrameTracker.StatsLogWrapper(),
+ mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis,
+ eventsListener, config);
}
+ @UiThread
private void handleCujEvents(String action, Session session) {
// Clear the running and timeout tasks if the end / cancel was fired within the tracker.
// Or we might have memory leaks.
if (needRemoveTasks(action, session)) {
- removeTimeout(session.getCuj());
- removeTracker(session.getCuj());
+ getTracker(session.getCuj()).getHandler().runWithScissors(() -> {
+ removeTimeout(session.getCuj());
+ removeTracker(session.getCuj());
+ }, EXECUTOR_TASK_TIMEOUT);
}
}
@@ -466,7 +471,7 @@ public class InteractionJankMonitor {
synchronized (mLock) {
Runnable timeout = mTimeoutActions.get(cujType);
if (timeout != null) {
- mWorker.getThreadHandler().removeCallbacks(timeout);
+ getTracker(cujType).getHandler().removeCallbacks(timeout);
mTimeoutActions.remove(cujType);
}
}
@@ -491,9 +496,7 @@ public class InteractionJankMonitor {
*/
public boolean begin(View v, @CujType int cujType) {
try {
- return beginInternal(
- Configuration.Builder.withView(cujType, v)
- .build());
+ return begin(Configuration.Builder.withView(cujType, v));
} catch (IllegalArgumentException ex) {
Log.d(TAG, "Build configuration failed!", ex);
return false;
@@ -504,35 +507,42 @@ public class InteractionJankMonitor {
* Begins a trace session.
*
* @param builder the builder of the configurations for instrumenting the CUJ.
- * @return boolean true if the tracker is started successfully, false otherwise.
+ * @return boolean true if the tracker is begun successfully, false otherwise.
*/
public boolean begin(@NonNull Configuration.Builder builder) {
try {
- return beginInternal(builder.build());
+ final Configuration config = builder.build();
+ final TrackerResult result = new TrackerResult();
+ final boolean success = config.getHandler().runWithScissors(
+ () -> result.mResult = beginInternal(config), EXECUTOR_TASK_TIMEOUT);
+ if (!success) {
+ Log.d(TAG, "begin failed due to timeout, CUJ=" + getNameOfCuj(config.mCujType));
+ return false;
+ }
+ return result.mResult;
} catch (IllegalArgumentException ex) {
Log.d(TAG, "Build configuration failed!", ex);
return false;
}
}
+ @UiThread
private boolean beginInternal(@NonNull Configuration conf) {
- synchronized (mLock) {
- int cujType = conf.mCujType;
- if (!shouldMonitor(cujType)) return false;
- FrameTracker tracker = getTracker(cujType);
- // Skip subsequent calls if we already have an ongoing tracing.
- if (tracker != null) return false;
-
- // begin a new trace session.
- tracker = createFrameTracker(conf, new Session(cujType, conf.mTag));
- mRunningTrackers.put(cujType, tracker);
- tracker.begin();
-
- // Cancel the trace if we don't get an end() call in specified duration.
- scheduleTimeoutAction(
- cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT));
- return true;
- }
+ int cujType = conf.mCujType;
+ if (!shouldMonitor(cujType)) return false;
+ FrameTracker tracker = getTracker(cujType);
+ // Skip subsequent calls if we already have an ongoing tracing.
+ if (tracker != null) return false;
+
+ // begin a new trace session.
+ tracker = createFrameTracker(conf, new Session(cujType, conf.mTag));
+ putTracker(cujType, tracker);
+ tracker.begin();
+
+ // Cancel the trace if we don't get an end() call in specified duration.
+ scheduleTimeoutAction(
+ cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT));
+ return true;
}
/**
@@ -561,8 +571,10 @@ public class InteractionJankMonitor {
*/
@VisibleForTesting
public void scheduleTimeoutAction(@CujType int cuj, long timeout, Runnable action) {
- mTimeoutActions.put(cuj, action);
- mWorker.getThreadHandler().postDelayed(action, timeout);
+ synchronized (mLock) {
+ mTimeoutActions.put(cuj, action);
+ getTracker(cuj).getHandler().postDelayed(action, timeout);
+ }
}
/**
@@ -572,18 +584,35 @@ public class InteractionJankMonitor {
* @return boolean true if the tracker is ended successfully, false otherwise.
*/
public boolean end(@CujType int cujType) {
- synchronized (mLock) {
- // remove the timeout action first.
- removeTimeout(cujType);
- FrameTracker tracker = getTracker(cujType);
- // Skip this call since we haven't started a trace yet.
- if (tracker == null) return false;
- // if the end call doesn't return true, another thread is handling end of the cuj.
- if (tracker.end(REASON_END_NORMAL)) {
- removeTracker(cujType);
+ FrameTracker tracker = getTracker(cujType);
+ // Skip this call since we haven't started a trace yet.
+ if (tracker == null) return false;
+ try {
+ final TrackerResult result = new TrackerResult();
+ final boolean success = tracker.getHandler().runWithScissors(
+ () -> result.mResult = endInternal(cujType), EXECUTOR_TASK_TIMEOUT);
+ if (!success) {
+ Log.d(TAG, "end failed due to timeout, CUJ=" + getNameOfCuj(cujType));
+ return false;
}
- return true;
+ return result.mResult;
+ } catch (IllegalArgumentException ex) {
+ Log.d(TAG, "Execute end task failed!", ex);
+ return false;
+ }
+ }
+
+ @UiThread
+ private boolean endInternal(@CujType int cujType) {
+ // remove the timeout action first.
+ removeTimeout(cujType);
+ FrameTracker tracker = getTracker(cujType);
+ if (tracker == null) return false;
+ // if the end call doesn't return true, another thread is handling end of the cuj.
+ if (tracker.end(REASON_END_NORMAL)) {
+ removeTracker(cujType);
}
+ return true;
}
/**
@@ -602,39 +631,66 @@ public class InteractionJankMonitor {
*/
@VisibleForTesting
public boolean cancel(@CujType int cujType, @Reasons int reason) {
- synchronized (mLock) {
- // remove the timeout action first.
- removeTimeout(cujType);
- FrameTracker tracker = getTracker(cujType);
- // Skip this call since we haven't started a trace yet.
- if (tracker == null) return false;
- // if the cancel call doesn't return true, another thread is handling cancel of the cuj.
- if (tracker.cancel(reason)) {
- removeTracker(cujType);
+ FrameTracker tracker = getTracker(cujType);
+ // Skip this call since we haven't started a trace yet.
+ if (tracker == null) return false;
+ try {
+ final TrackerResult result = new TrackerResult();
+ final boolean success = tracker.getHandler().runWithScissors(
+ () -> result.mResult = cancelInternal(cujType, reason), EXECUTOR_TASK_TIMEOUT);
+ if (!success) {
+ Log.d(TAG, "cancel failed due to timeout, CUJ=" + getNameOfCuj(cujType));
+ return false;
}
- return true;
+ return result.mResult;
+ } catch (IllegalArgumentException ex) {
+ Log.d(TAG, "Execute cancel task failed!", ex);
+ return false;
+ }
+ }
+
+ @UiThread
+ private boolean cancelInternal(@CujType int cujType, @Reasons int reason) {
+ // remove the timeout action first.
+ removeTimeout(cujType);
+ FrameTracker tracker = getTracker(cujType);
+ if (tracker == null) return false;
+ // if the cancel call doesn't return true, another thread is handling cancel of the cuj.
+ if (tracker.cancel(reason)) {
+ removeTracker(cujType);
+ }
+ return true;
+ }
+
+ private void putTracker(@CujType int cuj, @NonNull FrameTracker tracker) {
+ synchronized (mLock) {
+ mRunningTrackers.put(cuj, tracker);
}
}
private FrameTracker getTracker(@CujType int cuj) {
- return mRunningTrackers.get(cuj);
+ synchronized (mLock) {
+ return mRunningTrackers.get(cuj);
+ }
}
private void removeTracker(@CujType int cuj) {
- mRunningTrackers.remove(cuj);
+ synchronized (mLock) {
+ mRunningTrackers.remove(cuj);
+ }
}
+ @WorkerThread
private void updateProperties(DeviceConfig.Properties properties) {
- synchronized (mLock) {
- mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
- DEFAULT_SAMPLING_INTERVAL);
- mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
- mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY,
- DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
- mTraceThresholdFrameTimeMillis = properties.getInt(
- SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY,
- DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
- }
+ mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
+ DEFAULT_SAMPLING_INTERVAL);
+ mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY,
+ DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
+ mTraceThresholdFrameTimeMillis = properties.getInt(
+ SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY,
+ DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
+ // The memory visibility is powered by the volatile field, mEnabled.
+ mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
}
@VisibleForTesting
@@ -804,10 +860,16 @@ public class InteractionJankMonitor {
return "TASKBAR_EXPAND";
case CUJ_TASKBAR_COLLAPSE:
return "TASKBAR_COLLAPSE";
+ case CUJ_SHADE_CLEAR_ALL:
+ return "SHADE_CLEAR_ALL";
}
return "UNKNOWN";
}
+ private static class TrackerResult {
+ private boolean mResult;
+ }
+
/**
* Configurations used while instrumenting the CUJ. <br/>
* <b>It may refer to an attached view, don't use static reference for any purpose.</b>
@@ -821,6 +883,7 @@ public class InteractionJankMonitor {
private final SurfaceControl mSurfaceControl;
private final @CujType int mCujType;
private final boolean mDeferMonitor;
+ private final Handler mHandler;
/**
* A builder for building Configuration. {@link #setView(View)} is essential
@@ -964,6 +1027,7 @@ public class InteractionJankMonitor {
mSurfaceControl = surfaceControl;
mDeferMonitor = deferMonitor;
validate();
+ mHandler = mSurfaceOnly ? mContext.getMainThreadHandler() : mView.getHandler();
}
private void validate() {
@@ -1012,20 +1076,25 @@ public class InteractionJankMonitor {
return mSurfaceControl;
}
- View getView() {
+ @VisibleForTesting
+ /**
+ * @return a view which is attached to the view tree.
+ */
+ public View getView() {
return mView;
}
- Context getContext() {
- return mContext;
- }
-
/**
* @return true if the monitoring should be deferred to the next frame, false otherwise.
*/
public boolean shouldDeferMonitor() {
return mDeferMonitor;
}
+
+ @VisibleForTesting
+ public Handler getHandler() {
+ return mHandler;
+ }
}
/**
@@ -1078,7 +1147,8 @@ public class InteractionJankMonitor {
mReason = reason;
}
- public @Reasons int getReason() {
+ @Reasons
+ public int getReason() {
return mReason;
}
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 4ddbaa6cb0af..95cb729b3f7f 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -49,14 +49,14 @@ interface IInputMethodManager {
+ "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
List<InputMethodInfo> getEnabledInputMethodList(int userId);
- List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
+ List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in @nullable String imiId,
boolean allowsImplicitlySelectedSubtypes);
- InputMethodSubtype getLastInputMethodSubtype();
+ @nullable InputMethodSubtype getLastInputMethodSubtype();
- boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
- in ResultReceiver resultReceiver, int reason);
- boolean hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
- in ResultReceiver resultReceiver, int reason);
+ boolean showSoftInput(in IInputMethodClient client, @nullable IBinder windowToken, int flags,
+ in @nullable ResultReceiver resultReceiver, int reason);
+ boolean hideSoftInput(in IInputMethodClient client, @nullable IBinder windowToken, int flags,
+ in @nullable ResultReceiver resultReceiver, int reason);
// If windowToken is null, this just does startInput(). Otherwise this reports that a window
// has gained focus, and if 'editorInfo' is non-null then also does startInput.
@@ -65,34 +65,42 @@ interface IInputMethodManager {
+ "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
InputBindResult startInputOrWindowGainedFocus(
/* @StartInputReason */ int startInputReason,
- in IInputMethodClient client, in IBinder windowToken,
+ in IInputMethodClient client, in @nullable IBinder windowToken,
/* @StartInputFlags */ int startInputFlags,
/* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
- int windowFlags, in EditorInfo editorInfo, in IRemoteInputConnection inputConnection,
- in IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
+ /* @android.view.WindowManager.LayoutParams.Flags */ int windowFlags,
+ in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
+ in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
int unverifiedTargetSdkVersion, in ImeOnBackInvokedDispatcher imeDispatcher);
void showInputMethodPickerFromClient(in IInputMethodClient client,
int auxiliarySubtypeMode);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.WRITE_SECURE_SETTINGS)")
void showInputMethodPickerFromSystem(in IInputMethodClient client,
int auxiliarySubtypeMode, int displayId);
- void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
+ void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client,
+ @nullable String topId);
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.TEST_INPUT_METHOD)")
boolean isInputMethodPickerShownForTest();
- InputMethodSubtype getCurrentInputMethodSubtype();
+
+ @nullable InputMethodSubtype getCurrentInputMethodSubtype();
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
// This is kept due to @UnsupportedAppUsage.
// TODO(Bug 113914148): Consider removing this.
int getInputMethodWindowVisibleHeight(in IInputMethodClient client);
oneway void reportVirtualDisplayGeometryAsync(in IInputMethodClient parentClient,
- int childDisplayId, in float[] matrixValues);
+ int childDisplayId, in @nullable float[] matrixValues);
oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible);
+ @EnforcePermission("INTERNAL_SYSTEM_WINDOW")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.INTERNAL_SYSTEM_WINDOW)")
void removeImeSurface();
@@ -116,6 +124,7 @@ interface IInputMethodManager {
boolean isStylusHandwritingAvailableAsUser(int userId);
/** add virtual stylus id for test Stylus handwriting session **/
+ @EnforcePermission("INJECT_EVENTS")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.INJECT_EVENTS)")
void addVirtualStylusIdForTestSession(in IInputMethodClient client);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 17a47d3cdc2b..57c32b7f52b1 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -180,8 +180,6 @@ public class LockPatternUtils {
public static final String SYNTHETIC_PASSWORD_KEY_PREFIX = "synthetic_password_";
public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle";
- public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp";
- public static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
public static final String PASSWORD_HISTORY_DELIMITER = ",";
@UnsupportedAppUsage
@@ -1709,19 +1707,6 @@ public class LockPatternUtils {
}
}
- public void enableSyntheticPassword() {
- setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1L, UserHandle.USER_SYSTEM);
- }
-
- public void disableSyntheticPassword() {
- setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0L, UserHandle.USER_SYSTEM);
- }
-
- public boolean isSyntheticPasswordEnabled() {
- return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT,
- UserHandle.USER_SYSTEM) != 0;
- }
-
/**
* Returns whether the given user has pending escrow tokens
*/
diff --git a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
index 83e2f2b3f89e..22798563e8f5 100644
--- a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
+++ b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
@@ -21,17 +21,17 @@
#include "jni.h"
namespace android {
-static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject thiz,
+static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jclass clazz,
jboolean hasConnectivity) {
setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
}
-static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket) {
+static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jclass clazz, jint socket) {
return (jboolean)!protectFromVpn(socket);
}
-static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jobject thiz, jobject javaFd) {
- return android_net_utils_protectFromVpn(env, thiz, AFileDescriptor_getFd(env, javaFd));
+static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jclass clazz, jobject javaFd) {
+ return android_net_utils_protectFromVpn(env, clazz, AFileDescriptor_getFd(env, javaFd));
}
static const JNINativeMethod gNetworkUtilMethods[] = {
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 04f4d7b09d82..bd4f99044b17 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -238,6 +238,7 @@ message PowerServiceSettingsAndConfigurationDumpProto {
optional bool is_stay_on_while_plugged_in_ac = 1;
optional bool is_stay_on_while_plugged_in_usb = 2;
optional bool is_stay_on_while_plugged_in_wireless = 3;
+ optional bool is_stay_on_while_plugged_in_dock = 4;
}
message ScreenBrightnessSettingLimitsProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 92ac389ece67..505ef30949ce 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -578,7 +578,7 @@ message InsetsSourceProviderProto {
optional WindowStateProto pending_control_target = 6;
optional WindowStateProto fake_control_target = 7;
optional .android.view.SurfaceControlProto captured_leash = 8;
- optional .android.graphics.RectProto ime_overridden_frame = 9;
+ optional .android.graphics.RectProto ime_overridden_frame = 9 [deprecated=true];
optional bool is_leash_ready_for_dispatching = 10;
optional bool client_visible = 11;
optional bool server_visible = 12;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c2fcd1d0612a..81808647f18e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4068,6 +4068,11 @@
<permission android:name="android.permission.BIND_INPUT_METHOD"
android:protectionLevel="signature" />
+ <!-- Allows access to Test APIs defined in {@link android.view.inputmethod.InputMethodManager}.
+ @hide -->
+ <permission android:name="android.permission.TEST_INPUT_METHOD"
+ android:protectionLevel="signature" />
+
<!-- Must be required by an {@link android.media.midi.MidiDeviceService},
to ensure that only the system can bind to it.
<p>Protection level: signature
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d1c38767680f..e9381e04b02a 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Laat die program toe om die skermslot-kompleksiteitvlak (hoog, medium, laag of geen) te leer, wat die moontlike omvang van die lengte en soort skermslot aandui. Hierdie program kan ook aan gebruikers voorstel dat hulle die skermslot na \'n sekere vlak opdateer, maar gebruikers kan dit uit vrye wil ignoreer en weggaan. Let daarop dat die skermslot nie in skoonteks geberg word nie en die program dus nie die presiese wagwoord ken nie."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"wys kennisgewings"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Laat die program toe om kennisgewings te wys"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"skakel die skerm aan"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Laat die program toe om die skerm aan te skakel."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"gebruik biometriese hardeware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Laat die program toe om biometriese hardeware vir stawing te gebruik"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"bestuur vingerafdrukhardeware"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan nie toegang tot die foon se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan nie toegang tot die tablet se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
<string name="system_locale_title" msgid="711882686834677268">"Stelselverstek"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 21751c8721be..78f383c2f9f8 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -416,7 +416,7 @@
<string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"መተግበሪያው በእርስዎ ስልክ ላይ ስለተከማቹ እውቂያዎችዎ ያለ ውሂብን እንዲቀይር ያስችለዋል። ይህ ፈቃድ መተግበሪያዎች የእውቂያ ውሂብን እንዲሰርዙ ያስችላቸዋል።"</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"የጥሪ ምዝግብ ማስታወሻን ያንብቡ"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"ይህ መተግበሪያ የእርስዎን የጥሪ ታሪክ ማንበብ ይችላል።"</string>
- <string name="permlab_writeCallLog" msgid="670292975137658895">"የጥሪ ምዝግብ ማስታወሻን ፃፍ"</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="default" msgid="5903033505665134802">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"መተግበሪያው የማያ ገጽ መቆለፊያው ውስብስብነት ደረጃ (ከፍተኛ፣ መካከለኛ፣ ዝቅተኛ ወይም ምንም) እንዲያውቅ ያስችለዋል፣ ይህም ሊሆኑ የሚችለው የማያ ገጽ መቆለፊያው ርዝመት እና ዓይነት ክልል ያመለክታል። መተግበሪያው እንዲሁም ለተጠቃሚዎች የማያ ገጽ መቆለፊያውን ወደተወሰነ ደረጃ እንዲያዘምኑት ሊጠቁማቸው ይችላል። የማያ ገጽ መቆለፊያው በስነጣ አልባ ጽሑፍ እንደማይከማች ልብ ይበሉ፣ በዚህም መተግበሪያው ትክክለኛውን የይለፍ ቃል አያውቅም።"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"ማሳወቂያዎች አሳይ"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"መተግበሪያው ማሳወቂያዎችን እንዲያሳይ ያስችለዋል"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ማያ ገጹን አብራ"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"መተግበሪያው ማያ ገጹን እንዲያበራ ይፈቅድለታል።"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ባዮሜትራዊ ሃርድዌርን መጠቀም"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"መተግበሪያው የባዮሜትራዊ ሃርድዌር ለማረጋገጥ ስራ እንዲጠቀም ያስችለዋል"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"የጣት አሻራ ሃርድዌርን አስተዳድር"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"የስልኩን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ጡባዊውን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string>
<string name="system_locale_title" msgid="711882686834677268">"የሥርዓት ነባሪ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b75f9622ed98..5d25ba402992 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -557,6 +557,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"للسماح للتطبيق بمعرفة مستوى صعوبة قفل الشاشة (عالي أو متوسط أو منخفض الصعوبة أو بدون)، والذي يحدّد النطاق المحتمل لطول ونوع قفل الشاشة. ويمكن أن يقترح التطبيق للمستخدمين أيضًا تعديل قفل الشاشة إلى مستوى معيّن، ولهم مطلق الحرية في تجاهل هذا الاقتراح ورفضه. وتجدر الإشارة إلى أنه لا يتم حفظ قفل الشاشة في نص عادي، لذا لا يعرف التطبيق كلمة المرور تحديدًا."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"عرض الإشعارات"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"السماح للتطبيق بعرض إشعارات"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"تفعيل الشاشة"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"يسمح هذا الإذن للتطبيق بتفعيل الشاشة."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"استخدام الأجهزة البيومترية"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"للسماح للتطبيق باستخدام الأجهزة البيومترية للمصادقة"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"لإدارة أجهزة بصمة الإصبع"</string>
@@ -2079,10 +2081,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزيد من المعلومات"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏تم إبدال الإشعارات التكيُّفية لنظام التشغيل Android في الإصدار 12 منه بالإشعارات المحسّنة. تعرض هذه الميزة إجراءات وردودًا مقترحة وتنظِّم الإشعارات.\n\nيمكن للإشعارات المحسّنة الوصول إلى محتوى الإشعارات، بما في ذلك المعلومات الشخصية، مثلاً أسماء جهات الاتصال والرسائل. يمكن لهذه الميزة أيضًا إغلاق الإشعارات أو الاستجابة لها، مثلاً الردّ على مكالمات الهاتف والتحكّم في ميزة \"عدم الإزعاج\"."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"إشعار معلومات \"وضع سلسلة الإجراءات\""</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"تم تفعيل ميزة توفير شحن البطارية"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"يتم تقليل استخدام البطارية لإطالة عمرها."</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>
@@ -2290,4 +2290,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"يتعذّر الوصول إلى كاميرا الهاتف من على جهاز <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"يتعذّر الوصول إلى كاميرا الجهاز اللوحي من على جهاز <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
<string name="system_locale_title" msgid="711882686834677268">"الإعداد التلقائي للنظام"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index c1c1e96222d5..39647251b41f 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"এপ্‌টোক স্ক্ৰীন লকৰ জটিলতাৰ স্তৰ (উচ্চ, মধ্যম, নিম্ন বা একেবাৰে নাই)ৰ বিষয়ে জানিবলৈ অনুমতি দিয়ে, যিয়ে স্ক্ৰীন লকৰ সম্ভাব্য দৈৰ্ঘ্য বা স্ক্ৰীন লকৰ প্ৰকাৰ দৰ্শায়। লগতে এপ্‌টোৱে ব্যৱহাৰকাৰীক স্ক্ৰীন লকটো এটা নিৰ্দিষ্ট স্তৰলৈ আপডে’ট কৰিবলৈ পৰামৰ্শ দিব পাৰে যিটো ব্যৱহাৰকাৰীয়ে অৱজ্ঞা কৰি পৰৱর্তী পৃষ্ঠালৈ যাব পাৰে। মনত ৰাখিব যে স্ক্ৰীন লকটো সাধাৰণ পাঠ হিচাপে ষ্ট\'ৰ কৰা নহয়; সেয়েহে, এপ্‌টোৱে সঠিক পাছৱৰ্ডটো জানিব নোৱাৰে।"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"জাননী দেখুৱাওক"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"এপ্‌টোক জাননী দেখুৱাবলৈ দিয়ে"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"স্ক্ৰীনখন অন কৰক"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"এপ্‌টোক স্ক্ৰীনখন অন কৰিবলৈ দিয়ে।"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্যৱহাৰ কৰক"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ পৰিচালনা কৰিব পাৰে"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"অধিক জানক"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12ত Androidৰ অভিযোজিত জাননীক উন্নত জাননীৰ দ্বাৰা সলনি কৰা হৈছে। এই সুবিধাটোৱে পৰামৰ্শ দিয়া কাৰ্য আৰু প্ৰত্যুত্তৰ দেখুৱায় আৰু আপোনাৰ জাননীসমূহ শৃংখলাবদ্ধ কৰে।\n\nউন্নত জাননীয়ে সম্পৰ্কৰ নাম আৰু বাৰ্তাৰ দৰে ব্যক্তিগত তথ্যকে ধৰি জাননীৰ সমল এক্সেছ কৰিব পাৰে। এই সুবিধাটোৱে জাননী অগ্ৰাহ্য কৰিব অথবা জাননীৰ প্ৰতি সঁহাৰি জনাবও পাৰে, যেনে ফ’ন কলৰ উত্তৰ দিয়া আৰু অসুবিধা নিদিব সুবিধাটো নিয়ন্ত্ৰণ কৰা আদি।"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ৰুটিন ম’ডৰ তথ্য জাননী"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"বেটাৰী সঞ্চয়কাৰী অন কৰা হৈছে"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"বেটাৰীৰ জীৱনকাল বৃদ্ধি কৰিবলৈ বেটাৰীৰ ব্যৱহাৰ কমোৱা হৈছে"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা ফ’নটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা টেবলেটটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
<string name="system_locale_title" msgid="711882686834677268">"ছিষ্টেম ডিফ’ল্ট"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 8343ae683a8a..c41f4d7b3488 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Tətbiqin ekran kilidinin uzunluğunu və növünü göstərən mürəkəblilik dərəcəsini (yüksək, orta, aşağı və ya heç biri) öyrənməsinə icazə verir. Tətbiq ekran kilidinin müəyyən səviyyəyə yenilənməsini təklif edə bilər. İstifadəçilər bu təklifdən imtina edə və davam edə bilər. Yadda saxlayın ekran kilidi açıq mətn formatında saxlanılmır, buna görə də tətbiq dəqiq parolu bilməyəcək."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"bildirişləri göstərmək"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Tətbiqə bildirişləri göstərmək icazəsi verir"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekranı aktiv etmək"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tətbiqə ekranı aktiv etməyə icazə verir."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"biometrik proqramdan istifadə edin"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Doğrulama üçün biometrik proqramdan istifadə etməyə imkan verir"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"barmaq izi avadanlığını idarə edin"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ətraflı məlumat"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-də qabaqcıl bildirişlər var. Bu funksiya bütün bildirişləri qaydaya salır, cavab və əməliyyatlara dair tövsiyə verir.\n\nFunksiyanın kontaktlar, mesajlar və şəxsi məlumatlar daxil olmaqla bütün bildirişlərə girişi var. Zənglərə cavab verə, \"Narahat etməyin\" rejimini idarə edə, bildirişləri qapada və cavablaya bilər."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rejim üçün məlumat bildirişi"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Enerjiyə Qənaət aktivdir"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Batareyanın ömrünü uzatmaq üçün batareyadan istifadəni azaldın"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Enerjiyə qənaət"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Enerjiyə qənaət deaktivdir"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonun kifayət qədər enerjisi var. Funksiyalar artıq məhdud deyil."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına giriş etmək olmur"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan planşetin kamerasına giriş etmək olmur"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistem defoltu"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index f1efc7a93b4e..9bc0a9123071 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -554,6 +554,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"prikazivanje obaveštenja"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obaveštenja"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključivanje ekrana"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Dozvoljava aplikaciji da uključi ekran."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"koristi biometrijski hardver"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljaj hardverom za otiske prstiju"</string>
@@ -2285,4 +2287,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
<string name="system_locale_title" msgid="711882686834677268">"Podrazumevani sistemski"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 7c313c8d5592..34bbb0ef2c97 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дазваляе праграме вызначаць узровень складанасці блакіроўкі экрана (высокі, сярэдні, нізкі ці нулявы), які залежыць ад даўжыні пароля і ад тыпу блакіроўкі экрана. Праграма можа прапанаваць карыстальнікам ускладніць блакіроўку экрана, аднак гэту прапанову можна ігнараваць. Заўважце, што праграма не можа ведаць тып і пароль блакіроўкі экрана, таму што яны захоўваюцца ў зашыфраваным выглядзе."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"паказваць апавяшчэнні"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Дазваляе праграме паказваць апавяшчэнні"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"уключаць экран"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дазваляе праграме ўключаць экран."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"выкарыстоўваць біяметрычнае абсталяванне"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Дазваляе праграме выкарыстоўваць для аўтэнтыфікацыі біяметрычнае абсталяванне"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"кіраваць апаратнымі сродкамі для адбіткаў пальцаў"</string>
@@ -2077,10 +2079,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Даведацца больш"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"У версіі Android 12 Адаптыўныя апавяшчэнні Android заменены Палепшанымі апавяшчэннямі. Гэта функцыя ўпарадкоўвае вашы апавяшчэнні і паказвае прапановы дзеянняў і адказаў.\n\nПалепшаныя апавяшчэнні маюць доступ да змесціва ўсіх апавяшчэнняў, у тым ліку да асабістай інфармацыі – імён кантактаў і паведамленняў. Яшчэ гэта функцыя можа адхіляць апавяшчэнні ці адказваць на іх, напрыклад рэагаваць на тэлефонныя выклікі і кіраваць функцыяй \"Не турбаваць\"."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Апавяшчэнне з інфармацыяй пра ўсталяваны рэжым"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Рэжым энергазберажэння ўключаны"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Абмежаванне выкарыстання зараду для падаўжэння часу працы ад акумулятара"</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>
@@ -2288,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не ўдалося атрымаць доступ да камеры тэлефона з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не ўдалося атрымаць доступ да камеры планшэта з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
<string name="system_locale_title" msgid="711882686834677268">"Стандартная сістэмная налада"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d52e3e23ae8f..575e3471dbb9 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Разрешава на приложението да разбере нивото на сложност на опцията за заключване на екрана (високо, средно, ниско или липса на такова), което указва възможния диапазон на дължината и типа на опцията. Приложението може също да предложи на потребителите да актуализират опцията за заключване на екрана до определено ниво, но те могат да пренебрегнат това и да излязат от него. Обърнете внимание, че опцията за заключване на екрана не се съхранява като обикновен текст, така че приложението не знае точната парола."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"показване на известията"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Разрешава на приложението да показва известия"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"включване на екрана"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Разрешава на приложението да включва екрана."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"използване на хардуера за биометрични данни"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Разрешава на приложението да използва хардуера за биометрични данни с цел удостоверяване"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"управление на хардуера за отпечатъци"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Научете повече"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Адаптивните известия бяха заменени от функцията за подобрени известия в Android 12. Тя показва предложени действия и отговори и организира известията ви.\n\nФункцията може да осъществява достъп до съдържанието в известията, включително личната информация, като например имената на контактите и текстовите съобщения. Тя има възможност да отхвърля известията или да предприема действия в тях, като например приемане на телефонни обаждания или контролиране на режима „Не безпокойте“."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Известие с информация за режима на поредица"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Режимът за запазване на батерията е включен"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Използването на батерията се намалява с цел удължаване на живота ѝ"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Няма достъп до камерата на телефона от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Няма достъп до камерата на таблета от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Стандартно за системата"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 7ba759fc4717..45935fafe3ca 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"এটি অ্যাপটিকে স্ক্রিন লকের জটিলতার লেভেল বুঝতে সাহায্য করে (খুব বেশি, মাঝারি, অল্প জটিল বা কোনও জটিলতা নেই), যা স্ক্রিন লকটি সম্ভবত কত দীর্ঘ ও সেটির ধরন কীরকম, তার ইঙ্গিত দেয়। এই অ্যাপটি একটি নির্দিষ্ট লেভেল পর্যন্ত স্ক্রিন লক আপডেট করার সাজেশনও দিতে পারে, তবে ব্যবহারকারী তা উপেক্ষা করে অন্য কোথাও চলে যেতে পারেন। মনে রাখবেন যে স্ক্রিন লক প্লেন টেক্সট হিসেবে সংরক্ষণ করা হয় না, তাই অ্যাপ কখনও আসল পাসওয়ার্ড জানতে পারে না।"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"বিজ্ঞপ্তি দেখুন"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"অ্যাপকে বিজ্ঞপ্তি দেখানোর জন্য অনুমতি দেয়"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"স্ক্রিন চালু করতে চাই"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"অ্যাপকে স্ক্রিন চালু করার অনুমতি দেয়।"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করুন"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"অ্যাপটিকে যাচাইকরণের জন্য বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করার অনুমতি দেয়"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার পরিচালনা করুন"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ফোনের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ট্যাবলেটের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
<string name="system_locale_title" msgid="711882686834677268">"সিস্টেম ডিফল্ট"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 5616dd8f4ea8..0b8d3d3f5d8a 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -554,6 +554,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Omogućava aplikaciji da sazna nivo kompleksnosti zaključavanja ekrana (visoki, srednji, niski ili bez zaključavanja), što naznačava mogući raspon trajanja i vrste zaključavanja ekrana. Aplikacija također može korisnicima predložiti da ažuriraju zaključavanje ekrana do određenog nivoa, ali korisnici slobodno mogu ignorirati prijedlog i napustiti stranicu. Važno je napomenuti da se zaključavanje ekrana ne pohranjuje kao obični tekst tako da aplikacija ne zna tačnu lozinku."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"prikaz obavještenja"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obavještenja"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključivanje ekrana"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Omogućava aplikaciji da uključi ekran."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"koristi biometrijski hardver za otiske prstij"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Omogućava aplikaciji da za autentifikaciju koristi biometrijski hardver"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljanje hardverom za otisak prsta"</string>
@@ -2076,8 +2078,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Poboljšana obavještenja su zamijenila Prilagodljiva obavještenja Androida u verziji Android 12. Ova funkcija prikazuje predložene radnje i odgovore te organizira vaša obavještenja.\n\nPoboljšana obavještenja mogu pristupiti sadržaju obavještenja, uključujući lične informacije kao što su imena kontakata i poruke. Ova funkcija također može odbacivati obavještenja ili reagirati na njih, npr. može odgovarati na telefonske pozive i kontrolirati funkciju Ne ometaj."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještenje za informacije Rutinskog načina"</string>
- <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Uključena je štednja baterije"</string>
- <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Smanjuje se potrošnja baterije radi produženja njezinog trajanja"</string>
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ušteda baterije je uključena"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Smanjena je potrošnja baterije da se produži vijek trajanja baterije"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ušteda baterije"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ušteda baterije je isključena"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon se dovoljno napunio. Funkcije nisu više ograničene."</string>
@@ -2285,4 +2287,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nije moguće pristupiti kameri telefona s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nije moguće pristupiti kameri tableta s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistemski zadano"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 70faff59ea0b..c595ee195786 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permet que l\'aplicació conegui el nivell de complexitat del bloqueig de pantalla (alt, mitjà, baix o cap), que indica la llargària i el tipus de bloqueig de pantalla possibles. L\'aplicació també pot suggerir que els usuaris actualitzin el bloqueig de pantalla a un nivell determinat, però els usuaris poden ignorar aquestes recomanacions. Tingues en compte que el bloqueig de pantalla no s\'emmagatzema com a text sense format, de manera que l\'aplicació no coneix la contrasenya exacta."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostra notificacions"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permet que l\'aplicació mostri notificacions"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"activar la pantalla"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet a l\'aplicació activar la pantalla."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utilitza maquinari biomètric"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet que l\'aplicació faci servir maquinari biomètric per a l\'autenticació"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gestionar el maquinari d\'empremtes digitals"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No es pot accedir a la càmera del telèfon des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No es pot accedir a la càmera de la tauleta des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Valor predeterminat del sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c42b888e2e70..cf7fc26b0167 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Umožňuje aplikaci zjistit úroveň složitosti zámku obrazovky (vysoká, střední, nízká nebo žádná), která ukazuje možnou délku a typ zámku obrazovky. Aplikace také může uživatelům navrhovat, aby zámek obrazovky upravili na určitou úroveň, ale uživatelé mohou návrhy klidně ignorovat a odejít. Zámek obrazovky není uložen jako prostý text, a tak aplikace přesné heslo nezná."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"zobrazovat oznámení"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Povolí aplikaci zobrazovat oznámení"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"zapnutí obrazovky"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Umožňuje aplikaci zapnout obrazovku."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"použití biometrického hardwaru"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Umožňuje aplikaci použít k ověření biometrický hardware"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"správa hardwaru na čtení otisků prstů"</string>
@@ -2286,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu telefonu"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu tabletu"</string>
<string name="system_locale_title" msgid="711882686834677268">"Výchozí nastavení systému"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 80476bb4f166..749b5e8a2bae 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Giver appen tilladelse til at kende skærmlåsens kompleksitet (høj, medium, lav eller ingen), hvilket kan afsløre oplysninger om skærmlåsens længde og type. Appen kan også foreslå brugerne at opdatere deres skærmlås til et bestemt niveau, men brugerne kan frit ignorere det og gå videre. Bemærk! Skærmlåsen gemmes ikke som almindelig tekst, så appen kender ikke den nøjagtige adgangskode."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"vise notifikationer"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Giver appen tilladelse til at vise notifikationer"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"tænd skærmen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tillader, at appen tænder skærmen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"brug biometrisk hardware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Tillader, at appen kan bruge biometrisk hardware til godkendelse"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"administrer hardware til fingeraftryk"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kameraet på din telefon kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kameraet på din tablet kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 4cfb46f2d836..875964087668 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Ermöglicht es der App, die Komplexitätsstufe der Displaysperre (hoch, mittel, niedrig oder keine) zu ermitteln, was auf Art und mögliche Dauer der Displaysperre hinweist. Die App kann Nutzern auch vorschlagen, die Displaysperre auf eine bestimmte Stufe zu setzen. Nutzer können diesen Vorschlag jedoch einfach ignorieren und fortfahren. Beachten Sie, dass die Displaysperre nicht im Klartext gespeichert ist, sodass die App nicht das genaue Passwort kennt."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"Benachrichtigungen anzeigen"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Ermöglicht der App, Benachrichtigungen anzuzeigen"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"das Display einschalten"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ermöglicht der App, das Display einzuschalten."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"Biometrische Hardware verwenden"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Erlaubt der App, biometrische Hardware zur Authentifizierung zu verwenden"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"Fingerabdruckhardware verwalten"</string>
@@ -1625,7 +1627,7 @@
<string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Integrierter Bildschirm"</string>
<string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI-Bildschirm"</string>
<string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Overlay-Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
- <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+ <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> × <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
<string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", sicher"</string>
<string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Muster vergessen"</string>
<string name="kg_wrong_pattern" msgid="1342812634464179931">"Falsches Muster"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Weitere Informationen"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Die adaptiven Benachrichtigungen wurden in Android 12 durch die Funktion „Erweiterte Benachrichtigungen“ ersetzt. Diese Funktion zeigt Vorschläge für Aktionen und Antworten an und sortiert Benachrichtigungen.\n\nDie Funktion hat Zugriff auf alle Benachrichtigungen, darunter auch personenbezogene Daten wie Kontaktnamen und Nachrichten. Außerdem kann sie auf Benachrichtigungen antworten oder diese schließen und so beispielsweise Anrufe entgegennehmen oder „Bitte nicht stören“ steuern."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Infomitteilung zum Ablaufmodus"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Energiesparmodus aktiviert"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduzierung der Akkunutzung, um die Akkulaufzeit zu verlängern"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Energiesparmodus"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Energiesparmodus deaktiviert"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Das Smartphone ist ausreichend geladen. Es sind keine Funktionen mehr beschränkt."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Zugriff auf die Kamera des Smartphones über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Zugriff auf die Kamera des Tablets über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
<string name="system_locale_title" msgid="711882686834677268">"Standardeinstellung des Systems"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b246d0b138a6..7f8160c8f476 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Επιτρέπει στην εφαρμογή να μάθει το επίπεδο πολυπλοκότητας του κλειδώματος οθόνης (υψηλό, μέσο, χαμηλό ή κανένα), το οποίο υποδεικνύει το πιθανό εύρος του μήκους και του τύπου κλειδώματος οθόνης. Η εφαρμογή μπορεί επίσης να προτείνει στους χρήστες να ενημερώσουν το κλείδωμα οθόνης σε ένα συγκεκριμένο επίπεδο, όμως οι χρήστες μπορούν να την αγνοήσουν και να συνεχίσουν. Λάβετε υπόψη ότι το κλείδωμα οθόνης δεν αποθηκεύεται σε απλό κείμενο. Συνεπώς, η εφαρμογή δεν γνωρίζει τον κωδικό."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"εμφάνιση ειδοποιήσεων"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Επιτρέπει στην εφαρμογή να εμφανίζει ειδοποιήσεις"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ενεργοποίηση της οθόνης"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Επιτρέπει στην εφαρμογή να ενεργοποιεί την οθόνη."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"χρήση βιομετρικού εξοπλισμού"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί βιομετρικό εξοπλισμό για έλεγχο ταυτότητας"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"διαχείριση εξοπλισμού δακτυλικού αποτυπώματος"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του τηλεφώνου από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του tablet από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Προεπιλογή συστήματος"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 32ad56dcd861..138bb3ba0894 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index a678b28c61f9..1972db35390d 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 38c97dbf86a6..bb3a9d17ef9c 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 06dd854ecaa6..526b0d5fd5f9 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"show notifications"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Allows the app to show notifications"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"turn on the screen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Allows the app to turn on the screen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"use biometric hardware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Allows the app to use biometric hardware for authentication"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"manage fingerprint hardware"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"System default"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 1bac742e8273..daa0685f46a2 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‏‎Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plaintext so the app does not know the exact password.‎‏‎‎‏‎"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎show notifications‎‏‎‎‏‎"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎Allows the app to show notifications‎‏‎‎‏‎"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎turn on the screen‎‏‎‎‏‎"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎Allows the app to turn on the screen.‎‏‎‎‏‎"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎use biometric hardware‎‏‎‎‏‎"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎Allows the app to use biometric hardware for authentication‎‏‎‎‏‎"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎manage fingerprint hardware‎‏‎‎‏‎"</string>
@@ -2284,4 +2286,5 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎Can’t access the phone’s camera from your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎Can’t access the tablet’s camera from your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="system_locale_title" msgid="711882686834677268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎System default‎‏‎‎‏‎"</string>
+ <string name="default_card_name" msgid="9198284935962911468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎CARD ‎‏‎‎‏‏‎<xliff:g id="CARDNUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f67c65939f27..2b46223c5abb 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que la app conozca el nivel de complejidad del bloqueo de pantalla (alta, media, baja o ninguna), lo que indica el rango de duración posible y el tipo de bloqueo. La app también puede sugerirles a los usuarios que actualicen el bloqueo de pantalla a un determinado nivel, aunque ellos pueden ignorar esta sugerencia y seguir navegando. Ten en cuenta que el bloqueo de pantalla no se almacena como texto sin formato, por lo que la app no conoce la contraseña exacta."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificaciones"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que la app muestre notificaciones"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"encender la pantalla"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que la app encienda la pantalla."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"usar hardware biométrico"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que la app use hardware biométrico para realizar la autenticación"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"Administrar el hardware de huellas dactilares"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del dispositivo desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara de la tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 408d71d4c970..a71491b3e0f3 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que la aplicación entienda el nivel de complejidad del bloqueo de pantalla (alto, medio, bajo o ninguno) que indica la longitud y el tipo del bloqueo de pantalla posibles. La aplicación también puede sugerir a los usuarios que actualicen el bloqueo de pantalla para que tenga un nivel concreto de complejidad, pero los usuarios pueden ignorar la advertencia libremente. El bloqueo de pantalla no se almacena en texto sin formato, así que la aplicación no puede saber cuál es la contraseña exacta."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificaciones"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que la aplicación muestre notificaciones"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"encender la pantalla"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que la aplicación active la pantalla."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"usar hardware biométrico"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que la aplicación utilice el hardware biométrico para realizar la autenticación"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"administrar hardware de huellas digitales"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas sustituyeron las notificaciones adaptativas en Android 12. Esta función te muestra acciones y respuestas sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder al contenido de tus notificaciones, incluida información personal, como nombres de contactos y mensajes. También permiten descartar o responder a notificaciones; por ejemplo, es posible contestar llamadas telefónicas y controlar el modo No molestar."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación sobre el modo rutina"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ahorro de batería activado"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduciendo el uso de batería para prolongar su duración"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ahorro de batería"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ahorro de batería desactivado"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"El teléfono tiene suficiente batería. Las funciones ya no están restringidas."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del teléfono desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara del tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predeterminado del sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index cbfe44be67a4..6e00da736f2c 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lubab rakendusel vaadata ekraaniluku keerukuse taset (kõrge, keskmine, madal või puudub), mis näitab ekraaniluku võimalikku pikkust ja tüüpi. Rakendus võib kasutajatele soovitada ka ekraaniluku viimist teatud tasemele, kuid kasutajad võivad seda eirata ja kuvalt lahkuda. Pange tähele, et ekraanilukku ei salvestata lihttekstina, seega ei tea rakendus täpset parooli."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"märguannete kuvamine"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Lubab rakendusel märguandeid kuvada"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekraani sisselülitamine"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Lubab rakendusel ekraani sisse lülitada."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"kasutada biomeetrilist riistvara"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Võimaldab rakendusel autentimiseks kasutada biomeetrilist riistvara"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"sõrmejälje riistvara haldamine"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lisateave"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Androidi versioonis 12 asendasid täiustatud märguanded Androidi kohanduvad märguanded. See funktsioon näitab soovitatud toiminguid ja vastuseid ning korrastab teie märguandeid.\n\nTäiustatud märguanded pääsevad juurde märguande sisule, sh isiklikule teabele, nagu kontaktide nimed ja sõnumid. Samuti saab selle funktsiooni abil märguannetest loobuda või neile vastata (nt vastata telefonikõnedele ja juhtida funktsiooni Mitte segada)."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutiinirežiimi teabe märguanne"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Akusäästja lülitati sisse"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Aku tööea pikendamiseks vähendatakse akukasutust"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akusäästja"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akusäästja on välja lülitatud"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon on piisavalt laetud. Funktsioonid ei ole enam piiratud."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse telefoni kaamerale juurde"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tahvelarvuti kaamerale juurde"</string>
<string name="system_locale_title" msgid="711882686834677268">"Süsteemi vaikeseade"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4d955bb47d2c..9ec55253940a 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Pantailaren blokeoaren konplexutasun-maila (handia, ertaina, txikia edo bat ere ez) jakiteko baimena ematen die aplikazioei. Informazio horrekin, pantailaren blokeoaren luzera-barruti edo mota posiblea ondoriozta liteke. Halaber, pantailaren blokeoa maila jakin batera igotzeko iradoki diezaiekete aplikazioek erabiltzaileei, baina horri ez ikusi egin eta aplikazioak erabiltzen jarraitzeko aukera dute erabiltzaileek. Kontuan izan pantailaren blokeoa ez dela gordetzen testu arrunt gisa; beraz, aplikazioek ez dute jakingo pasahitz zehatza zein den."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"jakinarazpenak erakutsi"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Jakinarazpenak erakusteko baimena ematen die aplikazioei"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"piztu pantaila"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Pantaila pizteko baimena ematen dio aplikazioari."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"erabili hardware biometrikoa"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Autentifikatzeko hardware biometrikoa erabiltzeko baimena ematen die aplikazioei."</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"kudeatu hatz-marken hardwarea"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ezin da atzitu telefonoaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ezin da atzitu tabletaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistemaren balio lehenetsia"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d15780cf01d4..8aa014b22682 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"به برنامه اجازه می‌دهد سطح پیچیدگی قفل صفحه (بالا، متوسط، پایین، یا هیچ‌کدام) را بیاموزد که نشان‌دهنده بازه ممکن طول و نوع قفل صفحه است. همچنین برنامه می‌تواند به کاربران پیشنهاد دهد قفل صفحه را به سطح خاصی به‌روزرسانی کنند، اما کاربران می‌توانند آزادانه این پیشنهاد را نادیده بگیرند و به سطح دیگری بروند. توجه داشته باشید که قفل صفحه در قالب نوشتار ساده ذخیره نمی‌شود، بنابراین برنامه گذرواژه دقیق را نمی‌داند."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"نمایش اعلان"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"به این برنامه اجازه می‌دهد اعلان نمایش دهد"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"روشن کردن صفحه‌نمایش"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"به برنامه اجازه می‌دهد صفحه‌نمایش را روشن کند."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"استفاده از سخت‌افزار بیومتریک"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"به برنامه امکان می‌دهد از سخت‌افزار بیومتریک برای اصالت‌سنجی استفاده کند"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"مدیریت سخت‌افزار اثر انگشت"</string>
@@ -623,7 +625,7 @@
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهره‌تان ضربه بزنید، سپس چهره‌تان را دوباره اضافه کنید"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"راه‌اندازی «قفل‌گشایی با چهره»"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"برای باز کردن قفل تلفن خود به آن نگاه کنید"</string>
- <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"‏برای استفاده از «قفل‌گشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات &gt; حریم‌خصوصی» روشن کنید"</string>
+ <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"‏برای استفاده از «قفل‌گشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات &gt; حریم خصوصی» روشن کنید"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"راه‌اندازی روش‌های بیشتر برای باز کردن قفل"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"برای افزودن اثر انگشت، ضربه بزنید"</string>
<string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"قفل‌گشایی با اثر انگشت"</string>
@@ -1046,7 +1048,7 @@
<string name="permlab_writeGeolocationPermissions" msgid="8605631647492879449">"تغییر مجوزهای مکان جغرافیایی مرورگر"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="5817346421222227772">"‏به برنامه اجازه می‎دهد تا مجوزهای جغرافیایی مرورگر را تغییر دهد. برنامه‌های مخرب می‎توانند از آن استفاده کنند تا اطلاعات موقعیت مکانی را به سایت‌های وب کتابخانه بفرستند."</string>
<string name="save_password_message" msgid="2146409467245462965">"می‌خواهید مرورگر این گذرواژه را به خاطر داشته باشد؟"</string>
- <string name="save_password_notnow" msgid="2878327088951240061">"اکنون نه"</string>
+ <string name="save_password_notnow" msgid="2878327088951240061">"حالا نه"</string>
<string name="save_password_remember" msgid="6490888932657708341">"به خاطر سپردن"</string>
<string name="save_password_never" msgid="6776808375903410659">"هیچ‌وقت"</string>
<string name="open_permission_deny" msgid="5136793905306987251">"شما اجازه بازکردن این صفحه را ندارید."</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"بیشتر بدانید"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏در Android نسخه ۱۲، اعلان‌های بهبودیافته جایگزین «اعلان‌های تطبیقی» شده است. این ویژگی پاسخ‌ها و کنش‌های پیشنهادی را نمایش می‌دهد و اعلان‌هایتان را سازمان‌دهی می‌کند.\n\nاعلان‌های بهبودیافته می‌توانند به محتوای اعلان، ازجمله اطلاعات شخصی مثل نام‌ها و پیام‌های مخاطبین دسترسی داشته باشند. این ویژگی همچنین می‌تواند اعلان‌ها را رد کند یا به آن‌ها پاسخ دهد؛ مثلاً پاسخ به تماس‌های تلفنی و کنترل کردن «مزاحم نشوید»."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"اعلان اطلاعات حالت روال معمول"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"«بهینه‌سازی باتری» روشن شد"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"برای افزایش عمر باتری، مصرف باتری کاهش می‌یابد"</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>
@@ -2270,7 +2270,7 @@
<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="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>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"بررسی تنظیمات دسترسی"</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"نمی‌توان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین تلفن دسترسی داشت"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"نمی‌توان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین رایانه لوحی دسترسی داشت"</string>
<string name="system_locale_title" msgid="711882686834677268">"پیش‌فرض سیستم"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 33b43ba54fd0..8e65d49e81f0 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Sovellus saa luvan selvittää näytön lukituksen monimutkaisuuden (korkea, keskitaso tai matala) eli sen pituusluokan ja tyypin. Sovellus voi myös ehdottaa käyttäjille näytön lukituksen vaihtamista tietylle tasolle, mutta he voivat ohittaa tämän ja poistua. Itse näytön lukitusta ei säilytetä tekstimuodossa, joten sovellus ei tiedä sitä tarkalleen."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"näyttää ilmoituksia"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Antaa sovelluksen näyttää ilmoituksia"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"laita näyttö päälle"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Salli sovelluksen laittaa näyttö päälle."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"käytä biometristä laitteistoa"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Sallii sovelluksen käyttää biometristä laitteistoa todennukseen"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"sormenjälkilaitteiston hallinnointi"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lue lisää"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Parannetut ilmoitukset korvasivat Androidin mukautuvat ilmoitukset Android 12:ssa. Tämä ominaisuus näyttää toiminto- ja vastausehdotuksia ja järjestää ilmoituksesi.\n\nParannetuilla ilmoituksilla on pääsy kaikkeen ilmoitussisältöön, myös henkilökohtaisiin tietoihin (esim. kontaktien nimet ja viestit). Ominaisuus voi myös ohittaa ilmoituksia tai vastata niihin, esim. vastata puheluihin ja ohjata Älä häiritse ‑tilaa."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohjelmatilan tietoilmoitus"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Virransäästö päällä"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Akun käyttöä rajoitetaan akunkeston pidentämiseksi"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Virransäästö"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Virransäästö laitettiin pois päältä"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Puhelimessa on tarpeeksi virtaa. Ominaisuuksia ei enää rajoiteta."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse puhelimen kameraan"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tabletin kameraan"</string>
<string name="system_locale_title" msgid="711882686834677268">"Järjestelmän oletusarvo"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 23b8f0453452..2240a91164ac 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Autorise l\'application à apprendre le niveau de complexité de l\'écran de verrouillage (élevé, moyen, faible ou aucun), qui indique la gamme possible de longueur et de type de verrouillage d\'écran. L\'application peut aussi suggérer aux utilisateurs de mettre à jour l\'écran de verrouillage afin d\'utiliser un certain niveau de complexité, mais ils peuvent ignorer la suggestion. Notez que le verrouillage d\'écran n\'est pas stocké en texte brut pour de manière à ce que l\'application n\'ait pas accès au mot de passe exact."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"afficher les notifications"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permet à l\'application d\'afficher les notifications"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"allumer l\'écran"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet à l\'application d\'allumer l\'écran."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utiliser le matériel biométrique"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet à l\'application d\'utiliser du matériel biométrique pour l\'authentification"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gérer le lecteur d\'empreintes digitales"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notifications améliorées ont remplacé les notifications adaptatives Android sous Android 12. Cette fonctionnalité vous présente des suggestions d\'actions et de réponses, et organise vos notifications.\n\nLes notifications améliorées peuvent accéder au contenu de toutes les notifications, y compris les renseignements personnels comme le nom des contacts et les messages. Cette fonctionnalité peut aussi fermer des notifications ou interagir avec elles, comme répondre aux appels téléphoniques et gérer le mode Ne pas déranger."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Économiseur de pile activé"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Réduction de l\'utilisation de la pile pour en prolonger l\'autonomie"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Économiseur de pile"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Le mode Économiseur de pile est désactivé"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Le téléphone est suffisamment chargé. Ces fonctionnalités ne sont plus restreintes."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e14d5064ff6c..2b1421961925 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permet à l\'application de connaître le niveau de complexité du verrouillage de l\'écran (élevé, moyen, faible ou aucun), qui indique les possibilités en matière de longueur du mot de passe et de type de verrouillage de l\'écran. L\'application peut également suggérer aux utilisateurs de modifier la complexité du verrouillage, mais ces derniers peuvent librement l\'ignorer. Remarque : Comme le verrouillage de l\'écran n\'est pas stocké au format texte brut, l\'application ne connaît pas le mot de passe exact."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"afficher des notifications"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Autorise l\'appli à afficher des notifications"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"Allumer l\'écran"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Autorise l\'appli à allumer l\'écran."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utiliser les composants biométriques"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Autoriser l\'application à utiliser les composants biométriques pour l\'authentification"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gérer le matériel d\'empreintes digitales"</string>
@@ -623,7 +625,7 @@
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Appuyez pour supprimer votre empreinte faciale, puis ajoutez de nouveau votre visage"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"Configurer le déverrouillage par reconnaissance faciale"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string>
- <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pour utiliser Face Unlock, activez "<b>"Accès à l\'appareil photo"</b>" dans Paramètres &gt; Confidentialité"</string>
+ <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Pour utiliser le déverrouillage par reconnaissance faciale, activez "<b>"Accès à l\'appareil photo"</b>" dans Paramètres &gt; Confidentialité"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Appuyez pour ajouter une empreinte digitale"</string>
<string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Déverrouillage par empreinte digitale"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notifications améliorées remplacent les notifications intelligentes dans Android 12. Cette fonctionnalité affiche les suggestions d\'actions et de réponses, et organise vos notifications.\n\nElle a accès au contenu des notifications, y compris aux informations personnelles tels que les noms des contacts et les messages. Elle peut aussi fermer les notifications ou effectuer des actions comme répondre à un appel téléphonique et contrôler le mode Ne pas déranger."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Économiseur de batterie activé"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Réduction de l\'utilisation de la batterie pour prolonger son autonomie"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Économiseur de batterie"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Économiseur de batterie désactivé"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Téléphone suffisamment chargé. Les fonctionnalités ne sont plus restreintes."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Paramètre système par défaut"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 72f0dcc21ac5..52c26cad1a80 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que a aplicación consulte o nivel (alto, medio, baixo ou inexistente) de complexidade do bloqueo de pantalla para saber a lonxitude aproximada do contrasinal e o tipo de bloqueo de pantalla. A aplicación tamén pode suxerirlles aos usuarios que aumenten o nivel de complexidade do bloqueo de pantalla, aínda que poden ignorar a suxestión e seguir navegando. Ten en conta que o bloqueo de pantalla non se almacena como texto sen formato, polo que a aplicación non pode consultar o contrasinal exacto."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificacións"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que a aplicación mostre notificacións"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"activar pantalla"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que a aplicación active a pantalla."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utilizar hardware biométrico"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que a aplicación utilice hardware biométrico para a autenticación"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"xestionar hardware de impresión dixital"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Máis información"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"En Android 12, as notificacións melloradas substitúen as notificacións intelixentes. Esta función ofréceche suxestións de accións e respostas, ademais de organizar as notificacións.\n\nEste servizo pode acceder ao contido das notificacións, mesmo á información persoal, como os nomes dos contactos e as mensaxes. Ademais, esta función pode ignorar ou responder as notificacións (por exemplo, coller chamadas telefónicas e controlar o modo Non molestar)."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación da información do modo de rutina"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Activouse Aforro de batería"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Estase limitando o uso da batería para aumentar a súa duración"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Aforro de batería"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Desactivouse a función Aforro de batería."</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"O teléfono non ten suficiente batería. Xa non se restrinxirán as funcións."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Non se puido acceder á cámara do teléfono desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Non se puido acceder á cámara da tableta desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
<string name="system_locale_title" msgid="711882686834677268">"Opción predeterminada do sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f1f0b86e744f..713e33f0c2e7 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ઍપને સ્ક્રીન લૉકની જટિલતાનું લેવલ (ઊંચું, મધ્યમ, નીચું અથવા કોઈ નહીં) જાણવાની મંજૂરી આપે છે, જે સ્ક્રીન લૉકના પ્રકાર અને લંબાઈની સંભવિત શ્રેણી સૂચવે છે. ઍપ વપરાશકર્તાઓને સ્ક્રીન લૉકને ચોક્કસ લેવલ સુધી અપડેટ કરવાનું સૂચન પણ કરી શકે છે, પરંતુ વપરાશકર્તાઓ મુક્ત રીતે અવગણીને નૅવિગેટ કરી શકે છે. નોંધી લો કે સ્ક્રીન લૉકનો plaintextમાં સંગ્રહ કરવામાં આવતો નથી, તેથી ઍપને ચોક્કસ પાસવર્ડની જાણ હોતી નથી."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"નોટિફિકેશન બતાવો"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ઍપને નોટિફિકેશન બતાવવાની મંજૂરી આપે છે"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"સ્ક્રીન ચાલુ કરો"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ઍપને સ્ક્રીન ચાલુ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ફિંગરપ્રિન્ટ હાર્ડવેરને મેનેજ કરો"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ફોનના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ટૅબ્લેટના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string>
<string name="system_locale_title" msgid="711882686834677268">"સિસ્ટમ ડિફૉલ્ટ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6d90d53c528b..ddf0aa7f3f5c 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -302,9 +302,9 @@
<string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
<string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइलें"</string>
<string name="permgroupdesc_storage" msgid="5378659041354582769">"अपने डिवाइस में मौजूद फ़ाइलों का ऐक्सेस दें"</string>
- <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो के ऐक्सेस"</string>
<string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"आपके डिवाइस पर संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
- <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो के ऐक्सेस"</string>
<string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"आपके डिवाइस पर फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफ़ोन"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडियो रिकॉर्ड करें"</string>
@@ -550,9 +550,11 @@
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"अपना स्‍क्रीन लॉक अक्षम करें"</string>
<string name="permdesc_disableKeyguard" msgid="3223710003098573038">"ऐप्स को कीलॉक और कोई भी संबद्ध पासवर्ड सुरक्षा बंद करने देता है. उदाहरण के लिए, इनकमिंग फ़ोन कॉल पाते समय फ़ोन, कीलॉक को बंद कर देता है, फिर कॉल खत्म होने पर कीलॉक को फिर से चालू कर देता है."</string>
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"जानें कि स्क्रीन लॉक कितना मुश्किल बनाया गया है"</string>
- <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिल्कुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string>
+ <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिलकुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय लेवल तक अपडेट करें. लेकिन उपयोगकर्ता इसे बेझिझक अनदेखा करके छोड़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को सटीक पासवर्ड पता नहीं होता है."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाएं दिखाएं"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ऐप्लिकेशन को सूचनाएं दिखाने की अनुमति दें"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रीन चालू करें"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ऐप्लिकेशन को स्क्रीन चालू करने की अनुमति दें."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमीट्रिक हार्डवेयर इस्तेमाल करने दें"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"पुष्टि के लिए, ऐप्लिकेशन को बायोमीट्रिक हार्डवेयर इस्तेमाल करने की मंज़ूरी दें"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"फ़िंगरप्रिंट हार्डवेयर को प्रबंधित करें"</string>
@@ -644,9 +646,9 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"कृपया फिर से अपने चेहरे की पहचान कराएं."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"चेहरे की पहचान नहीं हुई. फिर से कोशिश करें."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"अपने सिर की पोज़िशन को थोड़ा बदलें"</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"अपने फ़ोन की तरफ़ बिल्कुल सीधा देखें"</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"अपने फ़ोन की तरफ़ बिलकुल सीधा देखें"</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"आपके चेहरे को छिपाने वाली सभी चीज़ों को हटाएं."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"अपनी स्क्रीन के सबसे ऊपरी हिस्से को साफ़ करें, जिसमें काले रंग वाला बार भी शामिल है"</string>
<string name="face_acquired_dark_glasses_detected" msgid="7263638432128692048">"आपका पूरा चेहरा दिखना चाहिए"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से फ़ोन के कैमरे को ऐक्सेस नहीं किया जा सकता"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से टैबलेट के कैमरे को ऐक्सेस नहीं किया जा सकता"</string>
<string name="system_locale_title" msgid="711882686834677268">"सिस्टम डिफ़ॉल्ट"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 63782e8bf446..48aece52c6f9 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -554,6 +554,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Omogućuje aplikaciji da sazna razinu složenosti zaključavanja zaslona (visoka, srednja, niska ili nijedna), što upućuje na mogući raspon duljine i vrstu zaključavanja zaslona. Aplikacija također korisnicima može predložiti da ažuriraju zaključavanje zaslona na određenu razinu, no korisnici to mogu slobodno zanemariti i nastaviti dalje. Napominjemo da se zaključavanje zaslona ne pohranjuje u običnom tekstu, pa aplikacija ne zna točnu zaporku."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"prikazati obavijesti"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Aplikaciji omogućuje prikazivanje obavijesti"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključiti zaslon"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Aplikaciji omogućuje uključivanje zaslona."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"koristiti biometrijski hardver"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Aplikaciji omogućuje upotrebu biometrijskog hardvera radi autentifikacije"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljanje hardverom za čitanje otisaka prstiju"</string>
@@ -2285,4 +2287,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu telefona"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu tableta"</string>
<string name="system_locale_title" msgid="711882686834677268">"Zadane postavke sustava"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index ed656ac240ce..f752b82d35d3 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lehetővé teszi az alkalmazás számára, hogy megismerje a képernyőzár összetettségi szintjét (magas, közepes, alacsony vagy nincs), amely jelzi a képernyőzár lehetséges típusát és hosszát. Az alkalmazás ezenkívül javaslatot tehet a felhasználóknak a képernyőzár bizonyos szintre való frissítésére, de ezt a javaslatot a felhasználók figyelmen kívül hagyhatják. A képernyőzárat nem egyszerű szöveges formátumban tárolja a rendszer, ezért az alkalmazás nem fogja tudni a pontos jelszót."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"értesítések megjelenítése"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Lehetővé teszi az alkalmazás számára az értesítések megjelenítését"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"képernyő bekapcsolása"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Engedélyezi az alkalmazásnak a képernyő bekapcsolását."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"biometrikus hardver használata"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Lehetővé teszi az alkalmazás számára a biometrikus hardver hitelesítésre való használatát"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ujjlenyomat-olvasó hardver kezelése"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nem lehet hozzáférni a telefon kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nem lehet hozzáférni a táblagép kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Rendszerbeállítás"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 282a212ed822..e162499affbe 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Հավելվածին հասանելի կդառնան էկրանի կողպման բարդության մակարդակի մասին տեղեկությունները (բարձր, միջին, ցածր կամ ոչ մեկը), այդ թվում՝ կողպման տեսակի և գաղտնաբառի երկարության մասին տվյալները: Բացի այդ, հավելվածը կկարողանա առաջարկել օգտատերերին բարձրացնել կողպման բարդության մակարդակը: Օգտատերերը կարող են անտեսել այդ առաջարկները: Նկատի ունեցեք, որ գաղտնաբառը չի պահվում բաց տեքստի տեսքով և հասանելի չէ հավելվածին:"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"ցուցադրել ծանուցումներ"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Թույլ է տալիս հավելվածին ցուցադրել ծանուցումներ"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"Էկրանի միացում"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Թույլ է տալիս հավելվածին միացնել էկրանը։"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"կենսաչափական սարքի օգտագործում"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված կենսաչափական սարքը"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"կառավարել մատնահետքերի գրանցման սարքը"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Իմանալ ավելին"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-ում ընդլայնված ծանուցումները փոխարինում են Android-ի հարմարվող ծանուցումներին։ Այս գործառույթը դասավորում է ձեր բոլոր ծանուցումները և առաջարկում գործողություններ և պատասխաններ։\n\nԸնդլայնված ծանուցումներին հասանելի է բոլոր ծանուցումների պարունակությունը, ներառյալ անձնական տվյալները, օրինակ՝ կոնտակտների անուններն ու հաղորդագրությունները։ Այս գործառույթը կարող է նաև փակել ծանուցումները կամ սեղմել դրանցում առկա կոճակները, այդ թվում՝ պատասխանել հեռախոսազանգերի և կառավարել «Չանհանգստացնել» ռեժիմը։"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ծանուցում լիցքավորման մասին"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Մարտկոցի տնտեսումը միացվել է"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Մարտկոցի օգտագործումը նվազեցվել է դրա աշխատաժամանակը երկարացնելու համար"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Հնարավոր չէ օգտագործել հեռախոսի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Հնարավոր չէ օգտագործել պլանշետի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string>
<string name="system_locale_title" msgid="711882686834677268">"Կանխադրված"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index a5fa54dad127..38861088dcd7 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Mengizinkan aplikasi mempelajari tingkat kompleksitas kunci layar (tinggi, sedang, rendah, atau tidak ada), yang menunjukkan kemungkinan rentang durasi dan jenis kunci layar. Aplikasi juga dapat menyarankan agar pengguna memperbarui kunci layar ke tingkat tertentu, namun pengguna dapat mengabaikan dan keluar dengan bebas. Perhatikan bahwa kunci layar tidak disimpan dalam teks biasa, sehingga aplikasi tidak mengetahui sandi yang sebenarnya."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"tampilkan notifikasi"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Mengizinkan aplikasi untuk menampilkan notifikasi"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"aktifkan layar"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Mengizinkan aplikasi mengaktifkan layar."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"gunakan hardware biometrik"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Mengizinkan aplikasi menggunakan hardware biometrik untuk autentikasi"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"kelola hardware sidik jari"</string>
@@ -745,7 +747,7 @@
<string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Mengizinkan pemegang memulai layar untuk meninjau keputusan izin. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
<string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"mulai lihat fitur aplikasi"</string>
<string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Memungkinkan pemegang mulai melihat info fitur untuk aplikasi."</string>
- <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi pengambilan sampel yang tinggi"</string>
+ <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"mengakses data sensor pada frekuensi sampling yang tinggi"</string>
<string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Mengizinkan aplikasi mengambil sampel data sensor pada frekuensi yang lebih besar dari 200 Hz"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"Setel aturan sandi"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pelajari lebih lanjut"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Notifikasi yang ditingkatkan menggantikan Notifikasi Adaptif Android di Android 12. Fitur ini menunjukkan tindakan dan balasan yang disarankan, serta mengatur notifikasi.\n\nNotifikasi yang ditingkatkan dapat mengakses konten notifikasi, termasuk informasi pribadi seperti nama kontak dan pesan. Fitur ini juga dapat menutup atau merespons notifikasi, seperti menjawab panggilan telepon dan mengontrol fitur Jangan Ganggu."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifikasi info Mode Rutinitas"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Penghemat Baterai diaktifkan"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Mengurangi penggunaan baterai untuk memperpanjang masa pakai baterai"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Penghemat Baterai"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Penghemat Baterai dinonaktifkan"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterai ponsel cukup terisi. Fitur tidak lagi dibatasi."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera ponsel dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Default sistem"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index ff29303cd02b..62a30c79924d 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Leyfir forritinu að læra hversu flókinn skjálásinn er (erfiður, miðlungs, léttur eða enginn), sem gefur til kynna lengd og tegund skjálássins. Forritið getur einnig lagt til að notendur geri skjálásinn flóknari upp að tilteknu marki, en notendur geta valið að hunsa það og halda áfram að vafra. Hafðu í huga að skjálásinn er ekki geymdur í ódulkóðuðum texta svo forritið veit ekki nákvæmt aðgangsorð."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"sýna tilkynningar"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Leyfir forritinu að sýna tilkynningar"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"kveikja á skjánum"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Leyfir forritinu að kveikja á skjánum."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"nota búnað fyrir líffræðileg gögn"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Leyfir forritinu að nota búnað fyrir líffræðileg gögn til auðkenningar"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"stjórna fingrafarabúnaði"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Nánar"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Auknar tilkynningar hafa leyst breytilegar tilkynningar í Android af hólmi í Android 12. Eiginleikinn birtir tillögur að aðgerðum og svörum og flokkar tilkynningar.\n\nAuknar tilkynningar hafa aðgang að efni tilkynninga, þ. á m. persónuupplýsingum á borð við nöfn tengiliða og skilaboð. Eiginleikinn getur einnig hunsað eða svarað tilkynningum, til dæmis svarað símtölum og stjórnað „Ónáðið ekki“."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Upplýsingatilkynning aðgerðastillingar"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Kveikt á rafhlöðusparnaði"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Dregur úr rafhlöðunotkun til að auka endingu rafhlöðunnar"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Rafhlöðusparnaður"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Slökkt á rafhlöðusparnaði"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Síminn er með næga hleðslu. Eiginleikar eru ekki lengur takmarkaðir."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ekki er hægt að opna myndavél símans úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ekki er hægt að opna myndavél spjaldtölvunnar úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sjálfgildi kerfis"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 89367e1ac259..bf320c9fbc36 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"Visualizzazione di notifiche"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Consente all\'app di mostrare notifiche"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"attiva lo schermo"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Consente all\'app di attivare lo schermo."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utilizzo di hardware biometrico"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gestione di hardware per il riconoscimento delle impronte"</string>
@@ -1916,13 +1918,13 @@
<string name="user_creation_adding" msgid="7305185499667958364">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"Aggiungi utente supervisionato"</string>
<string name="language_selection_title" msgid="52674936078683285">"Aggiungi una lingua"</string>
- <string name="country_selection_title" msgid="5221495687299014379">"Area geografica preferita"</string>
+ <string name="country_selection_title" msgid="5221495687299014379">"Regione preferita"</string>
<string name="search_language_hint" msgid="7004225294308793583">"Digita nome lingua"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Suggerite"</string>
<string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"Lingue suggerite"</string>
- <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"Aree geografiche consigliate"</string>
+ <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"Regioni consigliate"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"Tutte le lingue"</string>
- <string name="region_picker_section_all" msgid="756441309928774155">"Tutte le aree geografiche"</string>
+ <string name="region_picker_section_all" msgid="756441309928774155">"Tutte le regioni"</string>
<string name="locale_search_menu" msgid="6258090710176422934">"Cerca"</string>
<string name="app_suspended_title" msgid="888873445010322650">"App non disponibile"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> non è al momento disponibile. Viene gestita tramite <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossibile accedere alla fotocamera del telefono dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossibile accedere alla fotocamera del tablet dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predefinita di sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index bbc258193eae..1e12b1140488 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"מאפשרת לאפליקציה ללמוד את רמת המורכבות של נעילת המסך (גבוהה, בינונית, נמוכה או לא מורכבת). הרמה הזו מציינת את הטווח האפשרי של אורך וסוג נעילת המסך. האפליקציה יכולה גם להציע למשתמשים לעדכן את נעילת המסך לרמה מסוימת, אבל המשתמשים יכולים להתעלם מההצעה ולנווט לפריט אחר. לתשומת ליבך, נעילת המסך לא מאוחסנת כטקסט פשוט, ולכן האפליקציה לא יודעת מה הסיסמה המדויקת."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"הצגת התראות"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"מאפשרת לאפליקציה להציג התראות"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"הפעלת המסך"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ההרשאה מאפשרת לאפליקציה להפעיל את המסך."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"שימוש בחומרה ביומטרית"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"מאפשרת לאפליקציה להשתמש בחומרה ביומטרית לצורך אימות"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ניהול חומרה של טביעות אצבעות"</string>
@@ -2286,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"לא ניתן לגשת למצלמה של הטלפון מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"לא ניתן לגשת למצלמה של הטאבלט מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"ברירת המחדל של המערכת"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 60d0b91f90f7..6bbf5b48b4e9 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"このアプリに画面ロックの複雑さレベル(高、中、低、なし)を認識することを許可します。複雑さレベルは、画面ロックの文字数の範囲やタイプを示すものです。アプリから一定レベルまで画面ロックを更新するよう推奨されることもありますが、ユーザーは無視したり別の操作を行ったりできます。画面ロックは平文で保存されないため、アプリが正確なパスワードを知ることはありません。"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"通知の表示"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"通知の表示をアプリに許可"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"画面をオンにする"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"画面をオンにすることをアプリに許可します。"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"生体認証ハードウェアの使用"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"生体認証ハードウェアを認証に使用することをアプリに許可します"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"指紋認証ハードウェアの管理"</string>
@@ -1443,7 +1445,7 @@
<string name="permdesc_route_media_output" msgid="1759683269387729675">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"インストールセッションの読み取り"</string>
<string name="permdesc_readInstallSessions" msgid="4012608316610763473">"インストールセッションの読み取りをアプリに許可します。これにより、アプリはアクティブパッケージのインストールに関する詳細情報を参照できるようになります。"</string>
- <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"インストールパッケージのリクエスト"</string>
+ <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"request install packages"</string>
<string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"パッケージのインストールをリクエストすることをアプリケーションに許可します。"</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"パッケージの削除のリクエスト"</string>
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"パッケージの削除をリクエストすることをアプリに許可します。"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> からスマートフォンのカメラにアクセスできません"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> からタブレットのカメラにアクセスできません"</string>
<string name="system_locale_title" msgid="711882686834677268">"システムのデフォルト"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 997460696dcd..508cc42b21fa 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"საშუალებას აძლევს აპს, შეიტყოს ეკრანის დაბლოკვის მეთოდის სირთულე (მაღალი, საშუალო, დაბალი ან არანაირი), რისი მეშვეობითაც შესაძლებელია ეკრანის დაბლოკვის მეთოდის სიგრძის შესაძლო დიაპაზონისა და ტიპის განსაზღვრა. გარდა ამისა, აპს შეუძლია მომხმარებლებისთვის ეკრანის დაბლოკვის მეთოდის გარკვეულ დონემდე გაძლიერების შეთავაზება, თუმცა მომხმარებლებს შეეძლებათ აღნიშნული შეტყობინების უგულებელყოფა და სხვა ეკრანზე გადასვლა. გაითვალისწინეთ, რომ ეკრანის დაბლოკვის მეთოდი არ ინახება ჩვეულებრივი ტექსტის სახით, ამიტომ აპს არ ეცოდინება ზუსტი პაროლი."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"შეტყობინებების ჩვენება"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"უფლებას აძლევს აპს, აჩვენოს შეტყობინებები"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ეკრანის ჩართვა"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"უფლებას აძლევს აპს, ჩართოს ეკრანი."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ბიომეტრიული აპარატის გამოყენება"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"საშუალებას აძლევს აპს, ავტორიზაციისთვის გამოიყენოს ბიომეტრიული აპარატი"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"თითის ანაბეჭდის აპარატის მართვა"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ტელეფონის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ტაბლეტის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string>
<string name="system_locale_title" msgid="711882686834677268">"სისტემის ნაგულისხმევი"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 3545559f24f3..e43fc2e2c859 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -264,7 +264,7 @@
<string name="global_action_lockdown" msgid="2475471405907902963">"Құлыптау"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Жаңа хабарландыру"</string>
- <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуалды пернетақта"</string>
+ <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуалдық пернетақта"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Физикалық пернетақта"</string>
<string name="notification_channel_security" msgid="8516754650348238057">"Қауіпсіздік"</string>
<string name="notification_channel_car_mode" msgid="2123919247040988436">"Көлік режимі"</string>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Қолданбаға экран құлпының күрделілік деңгейін (жоғары, орташа, төмен немесе жоқ), соның ішінде ұзындығының ықтимал ауқымын және оның түрін анықтауға мүмкіндік береді. Сонымен қатар қолданба пайдаланушыларға құлыпты белгілі бір деңгейге жаңартуды ұсынады. Бірақ бұл ұсыныстарды елемеуге болады. Экран құлпы қарапайым мәтін түрінде сақталмайтындықтан, құпия сөз қолданбаға белгісіз болатынын ескеріңіз."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"хабарландыруларды көрсету"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Қолданбаға хабарландыруларды көрсетуге мүмкіндік береді."</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"экранды қосу"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Қолдабаға экранды қосуға рұқсат етеді."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"биометрикалық жабдықты пайдалану"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Аутентификациялау үшін қолданбаға биометрикалық жабдықты пайдалануға рұқсат береді"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"саусақ ізі жабдығын басқару"</string>
@@ -1134,7 +1136,7 @@
<string name="replace" msgid="7842675434546657444">"… сөзін алмастыру"</string>
<string name="delete" msgid="1514113991712129054">"Жою"</string>
<string name="copyUrl" msgid="6229645005987260230">"URL мекенжайын көшіру"</string>
- <string name="selectTextMode" msgid="3225108910999318778">"Мәтінді бөлектеу"</string>
+ <string name="selectTextMode" msgid="3225108910999318778">"Мәтінді ерекшелеу"</string>
<string name="undo" msgid="3175318090002654673">"Қайтару"</string>
<string name="redo" msgid="7231448494008532233">"Қайтару"</string>
<string name="autofill" msgid="511224882647795296">"Aвтотолтыру"</string>
@@ -1379,7 +1381,7 @@
<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="hardware" msgid="1800597768237606953">"Виртуалды пернетақтаны көрсету"</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>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1478,7 +1480,7 @@
<string name="wallpaper_binding_label" msgid="1197440498000786738">"Артқы фоны"</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"Артқы фонын өзгерту"</string>
<string name="notification_listener_binding_label" msgid="2702165274471499713">"Хабар бақылағыш"</string>
- <string name="vr_listener_binding_label" msgid="8013112996671206429">"Виртуалды шынайылық тыңдаушысы"</string>
+ <string name="vr_listener_binding_label" msgid="8013112996671206429">"Виртуалдық шынайылық тыңдаушысы"</string>
<string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Шарт провайдері"</string>
<string name="notification_ranker_binding_label" msgid="432708245635563763">"Хабарландыруларды жіктеу қызметі"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN белсенді"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде \"Бейімделетін хабарландырулар\" функциясын \"Кеңейтілген хабарландырулар\" алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарларды) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беруге және Мазаламау режимін басқаруға) болады."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Батареяны үнемдеу режимі қосулы"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Батарея шығынын азайтсаңыз, батареяның жұмысы ұзарады."</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан телефон камерасын пайдалану мүмкін емес."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан планшет камерасын пайдалану мүмкін емес."</string>
<string name="system_locale_title" msgid="711882686834677268">"Жүйенің әдепкі параметрі"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 2da5ac06a618..08ec6e8d8afb 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"អនុញ្ញាតឱ្យ​កម្មវិធី​រៀនអំពី​កម្រិតស្មុគស្មាញ​ការនៃការចាក់សោអេក្រង់ (ខ្ពស់ មធ្យម​ ទាប ឬគ្មាន) ដែល​បញ្ជាក់អំពី​​ប្រវែង និងប្រភេទ​នៃការចាក់សោអេក្រង់។ កម្មវិធី​នេះ​ក៏​អាច​ណែនាំឱ្យ​អ្នកប្រើប្រាស់​ធ្វើបច្ចុប្បន្នភាព​ការចាក់សោ​អេក្រង់​ទៅកម្រិតជាក់លាក់​ផងដែរ ប៉ុន្តែ​អ្នកប្រើប្រាស់​អាច​មិនអើពើនឹង​ការណែនាំនេះ​ដោយសេរី។ សូម​ចំណាំថា ការចាក់សោអេក្រង់​មិន​ត្រូវបាន​រក្សាទុក​ជាអត្ថបទ​ធម្មតាទេ ដូច្នេះ​កម្មវិធីនេះ​មិន​ស្គាល់​ពាក្យសម្ងាត់​ពិតប្រាកដ​ឡើយ។"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"បង្ហាញ​ការជូនដំណឹង"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"អនុញ្ញាតឱ្យ​កម្មវិធីបង្ហាញ​ការជូនដំណឹង"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"បើកអេក្រង់"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"អនុញ្ញាតឱ្យកម្មវិធីបើកអេក្រង់។"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ប្រើ​ឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​ប្រើ​ឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ​សម្រាប់​ការផ្ទៀងផ្ទាត់"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"គ្រប់គ្រងផ្នែករឹងស្នាមម្រាមដៃ"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"មិនអាច​ចូលប្រើ​កាមេរ៉ាទូរសព្ទ​ពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​បានទេ"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"មិនអាច​ចូលប្រើ​កាមេរ៉ា​ថេប្លេតពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នក​បានទេ"</string>
<string name="system_locale_title" msgid="711882686834677268">"លំនាំ​ដើម​ប្រព័ន្ធ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 4b90f4d6c3f5..e6e7f0799fb7 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ಆ್ಯಪ್‌ಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆ ಮಟ್ಟವನ್ನು (ಅಧಿಕ, ಮಧ್ಯಮ, ಕಡಿಮೆ ಅಥವಾ ಯಾವುದೂ ಅಲ್ಲ) ತಿಳಿದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ, ಅದು ಉದ್ದದ ಸಂಭವನೀಯ ಶ್ರೇಣಿ ಮತ್ತು ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನ ವಿಧವನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಬಳಕೆದಾರರು ನಿರ್ದಿಷ್ಟ ಹಂತದವರೆಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಬಹುದು, ಆದರೆ ಅವರು ಅದನ್ನು ನಿರ್ಲಕ್ಷಿಸಬಹುದು ಮತ್ತು ಅದರಿಂದ ಹೊರಬರಬಹುದು ಎಂಬುದನ್ನು ಸಹ ಆ್ಯಪ್ ಬಳಕೆದಾರರಿಗೆ ಸೂಚಿಸುತ್ತದೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಪಠ್ಯದ ರೂಪದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವುದಿಲ್ಲ, ಇದರಿಂದಾಗಿ ಆ್ಯಪ್‌ಗೆ ಸರಿಯಾದ ಪಾಸ್‌ವರ್ಡ್ ಗೊತ್ತಿರುವುದಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್ ಮಾಡಲು ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್‌ ಬಳಸಿ"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಹಾರ್ಡ್‌ವೇರ್ ನಿರ್ವಹಿಸಿ"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಫೋನ್‌ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="system_locale_title" msgid="711882686834677268">"ಸಿಸ್ಟಂ ಡೀಫಾಲ್ಟ್"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d75f3a8a175a..43d808037e9c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"앱이 화면 잠금 길이와 유형의 가능한 범위를 나타내는 잠금 화면 복잡도 수준(높음, 보통, 낮음 또는 없음)을 파악하도록 허용합니다. 앱이 사용자에게 화면 잠금을 특정 수준으로 업데이트할 것을 제안할 수도 있지만, 사용자는 자유롭게 이를 무시하고 다른 곳으로 이동할 수 있습니다. 화면 잠금은 일반 텍스트로 저장되지 않으므로 앱에서 정확한 비밀번호를 알 수 없습니다."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"알림 표시"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"앱에서 알림을 표시하도록 허용"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"화면 켜기"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"앱이 화면을 켜도록 허용합니다."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"생체 인식 하드웨어 사용"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"앱에서 생체 인식 하드웨어를 인증에 사용하도록 허용합니다."</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"지문 하드웨어 관리"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"자세히 알아보기"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12에서는 Android 적응형 알림이 개선된 알림으로 대체됩니다. 이 기능은 추천 작업과 답장을 표시하고 알림을 정리해 줍니다.\n\n개선된 알림은 연락처 이름과 메시지 등 개인 정보가 포함된 알림 내용에 액세스할 수 있습니다. 또한 전화를 받고 방해 금지 모드를 제어하는 등 알림을 닫거나 처리하는 것도 가능합니다."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"루틴 모드 정보 알림"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"절전 모드 사용 설정됨"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"배터리 사용량을 줄여서 배터리 수명을 늘립니다."</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 휴대전화 카메라에 액세스할 수 없습니다."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 태블릿 카메라에 액세스할 수 없습니다."</string>
<string name="system_locale_title" msgid="711882686834677268">"시스템 기본값"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index b9d681c4a3f0..8ce3f1311938 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Колдонмого экранды бөгөттөөнүн татаалдыгын (татаал, орточо, оңой же такыр жок) үйрөнүүгө мүмкүнчүлүк берет. Татаалдык деңгээли сырсөздүн узундугу жана экранды бөгөттөөнүн түрү боюнча айырмаланат. Колдонмо экранды бөгөттөөнү белгилүү деңгээлге тууралоону колдонуучуларга сунуштай да алат, бирок колдонуучулар ага көңүл бурбай койсо болот. Сырсөздү колдонмо билбеши үчүн, экранды бөгөттөө сырсөзүн кадимки текстте сактоого болбойт."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"билдирмелерди көрсөтүү"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Колдонмолор билдирмелерди көрсөтө алат"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"экранды күйгүзүү"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Колдонмого экранды күйгүзүүгө уруксат берет."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"биометрикалык аппаратты колдонуу"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Колдонмого аныктыгын текшерүү үчүн биометрикалык аппаратты пайдалануу мүмкүндүгүн берет"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"манжа изинин аппараттык камсыздоосун башкаруу"</string>
@@ -1229,7 +1231,7 @@
<string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> процесси өзүнүн мажбурланган StrictMode саясатын бузуп койду."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон жаңырууда…"</string>
<string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Планшет жаңыртылууда…"</string>
- <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңыртылууда…"</string>
+ <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңырууда…"</string>
<string name="android_start_title" product="default" msgid="4036708252778757652">"Телефон күйгүзүлүүдө…"</string>
<string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android жүргүзүлүүдө…"</string>
<string name="android_start_title" product="tablet" msgid="4429767260263190344">"Планшет күйгүзүлүүдө…"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн телефондун камерасына мүмкүнчүлүк жок"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн планшетиңиздин камерасына мүмкүнчүлүк жок"</string>
<string name="system_locale_title" msgid="711882686834677268">"Системанын демейки параметрлери"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index eeae8ce79b36..197b4b3d6e3d 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ອະນຸຍາດໃຫ້ແອັບສຶກສາລະດັບຄວາມຊັບຊ້ອນຂອງໜ້າຈໍລັອກ (ສູງ, ກາງ ຫຼື ບໍ່ມີ), ເຊິ່ງລະບຸຂອບເຂດຄວາມເປັນໄປໄດ້ຂອງຄວາມຍາວ ແລະ ປະເພດຂອງການລັອກໜ້າຈໍ. ແອັບນີ້ສາມາດແນະນຳຜູ້ໃຊ້ວ່າເຂົາເຈົ້າສາມາດອັບເດດໜ້າຈໍລັອກເປັນລະດັບໃດໜຶ່ງເປັນການສະເພາະໄດ້, ແຕ່ຜູ້ໃຊ້ສາມາດທີ່ຈະບໍ່ສົນໃຈ ຫຼື ເປີດໄປອັນອື່ນໄດ້. ກະລຸນາຮັບຊາບວ່າການລັອກໜ້າຈໍບໍ່ໄດ້ບັນທຶກໃນແບບຂໍ້ຄວາມທຳມະດາ, ດັ່ງນັ້ນແອັບຈະບໍ່ຮູ້ລະຫັດຜ່ານທີ່ແນ່ນອນ."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"ສະແດງການແຈ້ງເຕືອນ"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ອະນຸຍາດໃຫ້ແອັບສະແດງການແຈ້ງເຕືອນ"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ເປີດໜ້າຈໍ"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ອະນຸຍາດໃຫ້ແອັບເປີດໜ້າຈໍໄດ້."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ໃຊ້ຮາດແວຊີວະມິຕິ"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ອະນຸຍາດໃຫ້ແອັບນຳໃຊ້ຮາດແວຊີວະມິຕິສຳລັບການພິສູດຢືນຢັນ"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ຈັດ​ການ​ຮາດ​ແວ​ລາຍ​ນີ້ວ​ມື"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ສຶກສາເພີ່ມເຕີມ"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ການແຈ້ງເຕືອນແບບປັບຕົວໄດ້ຂອງ Android ຖືກແທນທີ່ດ້ວຍການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນໃນ Android 12 ແລ້ວ. ຄຸນສົມບັດນີ້ສະແດງຄຳສັ່ງ ແລະ ການຕອບກັບທີ່ແນະນຳ ແລະ ຈັດລະບຽບການແຈ້ງເຕືອນຂອງທ່ານ.\n\nການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນສາມາດເຂົ້າເຖິງເນື້ອຫາການແຈ້ງເຕືອນໄດ້, ຮວມທັງຂໍ້ມູນສ່ວນຕົວ ເຊັ່ນ: ຊື່ຜູ້ຕິດຕໍ່ ແລະ ຂໍ້ຄວາມ. ຄຸນສົມບັດນີ້ສາມາດປິດ ຫຼື ຕອບກັບຫາການແຈ້ງເຕືອນໄດ້ນຳ ເຊັ່ນ: ການຮັບສາຍໂທລະສັບ ແລະ ຄວບຄຸມໂໝດຫ້າມລົບກວນ."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ການແຈ້ງເຕືອນຂໍ້ມູນໂໝດກິດຈະວັດປະຈຳວັນ"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ເປີດໃຊ້ຕົວປະຢັດແບັດເຕີຣີແລ້ວ"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ກຳລັງຫຼຸດການໃຊ້ແບັດເຕີຣີເພື່ອຍືດອາຍຸແບັດເຕີຣີ"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງໂທລະສັບຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງແທັບເລັດຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string>
<string name="system_locale_title" msgid="711882686834677268">"ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f68b29279ac3..a6408977f618 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Leidžiama programai sužinoti ekrano užrakto sudėtingumo lygį (aukštas, vidutinis, žemas arba nėra), nurodantį galimą ekrano užrakto trukmės diapazoną ir tipą. Be to, programa gali pasiūlyti naudotojams atnaujinti ekrano užraktą į tam tikrą lygį, bet naudotojai gali laisvai nepaisyti ir išeiti. Atminkite, kad ekrano užraktas nesaugomas kaip grynasis tekstas, todėl programa nežino tikslaus slaptažodžio."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"rodyti pranešimus"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Programai leidžiama rodyti pranešimus"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"įjungti ekraną"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Programai leidžiama įjungti ekraną."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"naudoti biometrinę aparatinę įrangą"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Leidžiama programai naudoti biometrinę aparatinę įrangą tapatybei nustatyti"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"tvarkyti piršto antspaudo aparatinę įrangą"</string>
@@ -2286,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nepavyko pasiekti telefono fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nepavyko pasiekti planšetinio kompiuterio fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
<string name="system_locale_title" msgid="711882686834677268">"Numatytoji sistemos vertė"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d2bb73c476de..7612ea5f6edd 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -554,6 +554,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Atļauj lietotnei saglabāt informāciju par ekrāna bloķēšanas sarežģītības pakāpi (augsta, vidēja, zema, nav), kas apzīmē iespējamo garumu un ekrāna bloķēšanas veidus. Lietotnē lietotājiem var tikt rādīts arī ieteikums ekrāna bloķēšanai iestatīt citu līmeni, taču šo ieteikumu var ignorēt un aizvērt. Ņemiet vērā, ka ekrāna bloķēšanas parole netiek glabāta vienkārša teksta formātā, tāpēc lietotnei nav piekļuves precīzai parolei."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"Paziņojumu rādīšana"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Ļauj lietotnei rādīt paziņojumus."</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekrāna ieslēgšana"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ļauj lietotnei ieslēgt ekrānu."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"izmantot biometrisko datu aparatūru"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Atļauj lietotnei izmantot biometrisko datu aparatūru autentificēšanai"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"pārvaldīt pirkstu nospiedumu aparatūru"</string>
@@ -2076,10 +2078,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Uzzināt vairāk"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android adaptīvie paziņojumi ir aizstāti ar funkciju “Uzlabotie paziņojumi” operētājsistēmā Android 12. Šī funkcija parāda ieteiktās darbības un atbildes, kā arī kārto jūsu paziņojumus.\n\nFunkcija “Uzlabotie paziņojumi” var piekļūt paziņojumu saturam, tostarp personas informācijai, piemēram, kontaktpersonu vārdiem un ziņojumiem. Šī funkcija var arī noraidīt paziņojumus vai atbildēt uz tiem, piemēram, atbildēt uz tālruņa zvaniem vai pārvaldīt funkciju “Netraucēt”."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatīvs paziņojums par akumulatoru"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ieslēgts akumulatora enerģijas taupīšanas režīms"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Tiek samazināts akumulatora lietojums, lai paildzinātu akumulatora darbību."</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Akumulatora enerģijas taupīšanas režīms"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Akumulatora enerģijas taupīšanas režīms ir izslēgts"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Tālruņa uzlādes līmenis ir pietiekams. Funkcijas vairs netiek ierobežotas."</string>
@@ -2287,4 +2287,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nevar piekļūt tālruņa kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nevar piekļūt planšetdatora kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistēmas noklusējums"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0df431262104..15d10223f6de 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозволува апликацијата да го научи нивото на сложеност за заклучувањето на екранот (високо, средно, ниско или нема), коешто ги означува можниот опсег на должината и типот на заклучувањето на екранот. Апликацијата може да им дава предлози на корисниците да го ажурираат заклучувањето на екранот на одредено ниво, но корисниците можат да го игнорираат и да продолжат понатаму. Имајте предвид дека заклучувањето на екранот не се складира како обичен текст, па апликацијата не ја знае точната лозинка."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"да прикажува известувања"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Ѝ дозволува на апликацијата да прикажува известувања"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"да го вклучува екранот"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дозволува апликацијата да го вклучува екранот."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"користи биометриски хардвер"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Дозволува апликацијата да користи биометриски хардвер за проверка"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"управувај хардвер за отпечатоци"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се пристапи до камерата на вашиот телефон од <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се пристапи до камерата на вашиот таблет од <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Стандардно за системот"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f18fb00a86ef..8365de4ecd0f 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -43,7 +43,7 @@
<string name="invalidPin" msgid="7542498253319440408">"4 മുതൽ 8 വരെ അക്കങ്ങളുള്ള ഒരു പിൻ ടൈപ്പുചെയ്യുക."</string>
<string name="invalidPuk" msgid="8831151490931907083">"എട്ടോ അതിലധികമോ അക്കങ്ങളുള്ള ഒരു PUK ടൈപ്പുചെയ്യുക."</string>
<string name="needPuk" msgid="7321876090152422918">"നിങ്ങളുടെ സിം കാർഡ് PUK ലോക്ക് ചെയ്‌തതാണ്. ഇത് അൺലോക്ക് ചെയ്യാൻ PUK കോഡ് ടൈപ്പുചെയ്യുക."</string>
- <string name="needPuk2" msgid="7032612093451537186">"സിം കാർഡ് തടഞ്ഞത് മാറ്റാൻ PUK2 ടൈപ്പുചെയ്യുക."</string>
+ <string name="needPuk2" msgid="7032612093451537186">"സിം കാർഡ് അൺബ്ലോക്ക് ചെയ്യാൻ PUK2 ടൈപ്പ് ചെയ്യുക."</string>
<string name="enablePin" msgid="2543771964137091212">"വിജയകരമല്ല, സിം/RUIM ലോക്ക് പ്രവർത്തനക്ഷമമാക്കുക."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="other">SIM ലോക്കാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"സ്ക്രീൻ ലോക്കിന്റെ സാധ്യമായ നീളവും തരവും സൂചിപ്പിക്കുന്ന, അതിന്റെ സങ്കീർണ്ണത നില (ഉയർന്നത്, ഇടത്തരം, കുറഞ്ഞത് അല്ലെങ്കിൽ ഒന്നുമില്ല) മനസ്സിലാക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. സ്‌ക്രീൻ ലോക്ക് ഒരു പ്രത്യേക തലത്തിലേക്ക് അപ്ഡേറ്റ് ചെയ്യാൻ ഉപയോക്താക്കളെ നിർദ്ദേശിക്കാനും ആപ്പിനാവും, പക്ഷെ ഉപയോക്താക്കൾക്ക് എളുപ്പത്തിൽ അവഗണിക്കാനും മറ്റൊന്നിലേക്ക് നാവിഗേറ്റ് ചെയ്യാനുമാവും. പ്ലെയിൻടെക്‌സ്‌റ്റിൽ സ്ക്രീൻ ലോക്ക് സംഭരിക്കപ്പെട്ടിട്ടില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക, അതിനാൽ ആപ്പിന് കൃത്യമായ പാസ്‌വേഡ് അറിയില്ല."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"അറിയിപ്പുകൾ കാണിക്കുക"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"അറിയിപ്പുകൾ കാണിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"സ്ക്രീൻ ഓണാക്കുക"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"സ്ക്രീൻ ഓണാക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ബയോമെട്രിക് ഹാർ‌ഡ്‌വെയർ ഉപയോഗിക്കുക"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"പരിശോധിച്ചുറപ്പിക്കുന്നതിനായി, ബയോമെട്രിക് ഹാർഡ്‌വെയർ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ഫിംഗർപ്രിന്റ് ഹാർഡ്‌വെയർ നിയന്ത്രിക്കുക"</string>
@@ -1013,7 +1015,7 @@
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ഈ പേജിൽ തുടരുക"</string>
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nഈ പേജിൽ നിന്നും നാവിഗേറ്റുചെയ്‌തു പോകണമെന്ന് തീർച്ചയാണോ?"</string>
<string name="save_password_label" msgid="9161712335355510035">"സ്ഥിരീകരിക്കുക"</string>
- <string name="double_tap_toast" msgid="7065519579174882778">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഇരട്ട-ടാപ്പുചെയ്യുക."</string>
+ <string name="double_tap_toast" msgid="7065519579174882778">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഡബിൾ ടാപ്പ് ചെയ്യുക."</string>
<string name="autofill_this_form" msgid="3187132440451621492">"ഓട്ടോഫിൽ"</string>
<string name="setup_autofill" msgid="5431369130866618567">"ഓട്ടോഫിൽ സജ്ജീകരിക്കുക"</string>
<string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> ഉപയോഗിച്ച് സ്വമേധയാ പൂരിപ്പിക്കുക"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഫോണിന്റെ ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ടാബ്‌ലെറ്റിന്റെ ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
<string name="system_locale_title" msgid="711882686834677268">"സിസ്‌റ്റം ഡിഫോൾട്ട്"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3b679c8c1735..2826b5d6bcdb 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -284,9 +284,9 @@
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апп батарей ашиглаж байна"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Томруулах"</string>
<string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Хандалтын ашиглалт"</string>
- <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
- <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
+ <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батарей ашиглаж байна"</string>
+ <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батарей ашиглаж байна"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батарей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"Аюулгүй горим"</string>
<string name="android_system_label" msgid="5974767339591067210">"Андройд систем"</string>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Аппад дэлгэцийн түгжээний боломжтой уртын хэмжээ болон төрлийг заадаг дэлгэцийн түгжээний төвөгтэй байдлын түвшнийг (өндөр, дундаж, бага эсвэл байхгүй) мэдэж авахыг зөвшөөрдөг. Түүнчлэн, апп хэрэглэгчдэд дэлгэцийн түгжээг тодорхой түвшинд шинэчлэхийг санал болгох боломжтой хэдий ч хэрэглэгч үүнийг чөлөөтэй үл хэрэгсэж, орхих боломжтой. Дэлгэцийн түгжээг ил бичвэрээр хадгалдаггүй тул энэ апп тодорхой нууц үгийг мэддэггүй болохыг анхаарна уу."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"мэдэгдэл харуулах"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Аппад мэдэгдэл харуулахыг зөвшөөрнө"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"дэлгэцийг асаах"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Аппад дэлгэцийг асаахыг зөвшөөрнө."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"биометрийн техник хангамжийг ашиглах"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Aппад биометрийн техник хангамжийг баталгаажуулалтад ашиглахыг зөвшөөрдөг"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"хурууны хээний төхөөрөмжийг удирдах"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с утасны камерт хандах боломжгүй"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с таблетын камерт хандах боломжгүй"</string>
<string name="system_locale_title" msgid="711882686834677268">"Системийн өгөгдмөл"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 0477a06ea179..c54325c7cbaf 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -43,7 +43,7 @@
<string name="invalidPin" msgid="7542498253319440408">"4 ते 8 अंकांचा पिन टाइप करा."</string>
<string name="invalidPuk" msgid="8831151490931907083">"8 अंकांचा किंवा मोठा PUK टाइप करा."</string>
<string name="needPuk" msgid="7321876090152422918">"तुमचे सिम कार्ड PUK-लॉक केलेले आहे. ते अनलॉक करण्यासाठी PUK कोड टाइप करा."</string>
- <string name="needPuk2" msgid="7032612093451537186">"सिम कार्ड अनावरोधित करण्यासाठी PUK2 टाइप करा."</string>
+ <string name="needPuk2" msgid="7032612093451537186">"सिम कार्ड अनब्लॉक करण्यासाठी PUK2 टाइप करा."</string>
<string name="enablePin" msgid="2543771964137091212">"अयशस्वी, सिम/RUIM लॉक सुरू करा."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
<item quantity="other">सिम लॉक होण्यापूर्वी आपल्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न उर्वरित आहेत.</item>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"अ‍ॅपला स्क्रीन लॉक क्लिष्टता पातळी (उच्च, मध्यम, खालची किंवा काहीही नाही) जाणून घेऊ देते, जी लांबीची संभाव्य रेंज आणि स्क्रीन लॉकचा प्रकार सूचित करते. अ‍ॅप वापरकर्त्यांना असेदेखील सुचवू शकते की त्यांनी स्क्रीन लॉक ठरावीक पातळीपर्यंत अपडेट करावे, परंतु वापरकर्ते त्याकडे मोकळेपणाने दुर्लक्ष करू शकतात आणि तेथून नेव्हिगेट करू शकतात. स्क्रीन लॉक प्लेनटेक्स्टमध्ये स्टोअर केले जात नसल्यामुळे अ‍ॅपला नेमका पासवर्ड माहीत नसतो याची नोंद घ्या."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"सूचना दाखवा"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ॲपला सूचना दाखवू देते"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रीन सुरू करा"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"अ‍ॅपला स्क्रीन सुरू करण्याची परवानगी देते."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमेट्रिक हार्डवेअर वापरा"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ऑथेंटिकेशनसाठी बायोमेट्रिक हार्डवेअरचा वापर करण्याची ॲपला अनुमती देते"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा"</string>
@@ -693,7 +695,7 @@
<string name="permdesc_readMediaImages" msgid="5836219373138469259">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजमधून इमेज फाइल वाचण्याची अनुमती देते."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"तुमच्या शेअर केलेल्या स्टोरेजच्या आशयांमध्ये सुधारणा करा किंवा हटवा"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"ॲपला तुमच्या शेअर केलेल्या स्टोरेजचे आशय लिहिण्याची अनमती देते."</string>
- <string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/प्राप्त करा"</string>
+ <string name="permlab_use_sip" msgid="8250774565189337477">"SIP कॉल करा/मिळवा"</string>
<string name="permdesc_use_sip" msgid="3590270893253204451">"ॲपला SIP कॉल करण्‍याची आणि प्राप्त करण्‍याची अनुमती देते."</string>
<string name="permlab_register_sim_subscription" msgid="1653054249287576161">"नवीन टेलिकॉम सिम कनेक्शनची नोंदणी करा"</string>
<string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"नवीन टेलिकॉम सिम कनेक्शनची नोंदणी करण्यासाठी ॲपला अनुमती देते."</string>
@@ -729,7 +731,7 @@
<string name="permdesc_setInputCalibration" msgid="2937872391426631726">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यक नसते."</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"DRM प्रमाणपत्रे अ‍ॅक्सेस करा"</string>
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य ॲप्सकरिता कधीही आवश्यकता नसते."</string>
- <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
+ <string name="permlab_handoverStatus" msgid="7620438488137057281">"Android बीम स्थानांतरण स्थिती मिळवा"</string>
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM प्रमाणपत्रे काढा"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"DRM प्रमाणपत्रे काढण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यकता नसते."</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून फोनचा कॅमेरा अ‍ॅक्सेस करू शकत नाही"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून टॅबलेटचा कॅमेरा अ‍ॅक्सेस करू शकत नाही"</string>
<string name="system_locale_title" msgid="711882686834677268">"सिस्टीम डीफॉल्ट"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index cfb8739382a2..c3fba8c87c30 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Benarkan apl mengetahui tahap kekompleksan kunci skrin (tinggi, sederhana, rendah atau tiada) yang menunjukkan kemungkinan julat panjang dan jenis kunci skrin. Apl juga boleh mencadangkan kepada pengguna supaya mengemas kini kunci skrin pada tahap tertentu namun pengguna boleh mengabaikan dan menavigasi keluar dengan bebas. Sila ambil perhatian bahawa kunci skrin tidak disimpan dalam format teks biasa, maka apl tidak mengetahui kata laluan yang tepat."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"tunjukkan pemberitahuan"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Membenarkan apl menunjukkan pemberitahuan"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"hidupkan skrin"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Membenarkan apl untuk menghidupkan skrin."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"gunakan perkakasan biometrik"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Membenarkan apl menggunakan perkakasan biometrik untuk pengesahan"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"urus perkakasan cap jari"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera telefon daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
<string name="system_locale_title" msgid="711882686834677268">"Lalai sistem"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 07e54a6d034c..665bbce37d3d 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ဖုန်းမျက်နှာပြင်လော့ခ်၏ ရှုပ်ထွေးမှုအဆင့် (မြင့်၊ အလယ်အလတ်၊ နိမ့် သို့မဟုတ် မရှိ) အား လေ့လာရန် အက်ပ်ကို ခွင့်ပြုသည်။ ၎င်းက သတ်မှတ်ထားနိုင်သော ဖုန်းမျက်နှာပြင်လော့ခ်၏ စာလုံးရေနှင့် အမျိုးအစားကို ညွှန်ပြပေးသည်။ အသုံးပြုသူများအနေနှင့် ဖုန်းမျက်နှာပြင်လော့ခ်ကို အတိုင်းအတာတစ်ခုအထိ အဆင့်မြှင့်ရန် အက်ပ်က အကြံပြုနိုင်သည်။ သို့သော်လည်း အသုံးပြုသူများက ၎င်းကို ဂရုပြုမနေဘဲ လွတ်လပ်စွာ ကြည့်ရှုနိုင်ပါသည်။ ဖုန်းမျက်နှာပြင်လော့ခ်ကို စာသားအတိုင်း သိမ်းမထားသဖြင့် အက်ပ်သည် စကားဝှက်အစစ်ကို မသိနိုင်ကြောင်း သတိပြုပါ။"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"အကြောင်းကြားချက်များ ပြခြင်း"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"အကြောင်းကြားချက်များ ပြရန် အက်ပ်ကို ခွင့်ပြုနိုင်သည်"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ဖန်သားပြင်ဖွင့်ခြင်း"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ဖန်သားပြင်ဖွင့်ရန် အက်ပ်ကို ခွင့်ပြုနိုင်သည်။"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ဇီဝဗေဒဆိုင်ရာ အချက်အလက်သုံး ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန်"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"အထောက်အထားစိစစ်ခြင်းအတွက် ဇီဝဗေဒဆိုင်ရာ သတင်းအချက်အလက်များသုံးသည့် ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"လက်ဗွေစစ်ပစ္စည်းကို စီမံခြင်း"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ ဖုန်းကင်မရာကို သုံး၍မရပါ"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ တက်ဘလက်ကင်မရာကို သုံး၍မရပါ"</string>
<string name="system_locale_title" msgid="711882686834677268">"စနစ်မူရင်း"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d5d230b1ad2d..65b58acb678a 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -88,7 +88,7 @@
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status for mobildata"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS-meldinger"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Talepostmeldinger"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi-anrop"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Wifi-anrop"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"SIM-status"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"SIM-status er satt til høy prioritet"</string>
<string name="peerTtyModeFull" msgid="337553730440832160">"Motpart ba om TTY-modus FULL"</string>
@@ -117,25 +117,25 @@
<string name="roamingText11" msgid="5245687407203281407">"Roaming-banner på"</string>
<string name="roamingText12" msgid="673537506362152640">"Roaming-banner av"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Leter etter tjeneste"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Kunne ikke konfigurere Wi-Fi-anrop"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Kunne ikke konfigurere wifi-anrop"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"For å ringe og sende meldinger over Wi-Fi, må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på wifi-anrop igjen fra Innstillinger. (Feilkode: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="4795145070505729156">"Problem med å registrere Wi-Fi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item>
+ <item msgid="4795145070505729156">"Problem med å registrere wifi-anrop med operatøren din: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-anrop"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-anrop"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wifi-anrop"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g>-Wifi-anrop"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN-anrop"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN-anrop"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wi-Fi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wifi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wi-Fi-anrop"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wifi-anrop"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-anrop"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wifi-anrop"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Av"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ring via Wi-Fi"</string>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lar appen lære skjermlåsens kompleksitetsnivå (høy, middels, lav eller ingen), som indikerer det mulige området for lengde og type skjermlås. Appen kan foreslå at brukeren oppdaterer skjermlåsen til et bestemt nivå, men brukere kan velge å ignorere dette og navigere bort. Vær oppmerksom på at skjermlåsen ikke er lagret klartekst, så appen kan ikke se det nøyaktige passordet."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"vise varsler"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Lar appen vise varsler"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"slå på skjermen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Gir appen tillatelse til å slå på skjermen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"bruke biometrisk maskinvare"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Lar appen bruke biometrisk maskinvare til godkjenning"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"administrere fingeravtrykkmaskinvare"</string>
@@ -1036,9 +1038,9 @@
<string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"lese nettbokmerkene og nettloggen din"</string>
<string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Lar appen lese loggen for alle nettadressene nettleseren har besøkt, og alle bokmerkene i nettleseren. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
<string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"skrive nettbokmerker og nettlogg"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
- <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
<string name="permlab_setAlarm" msgid="1158001610254173567">"stille alarm"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"legge til talepost"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Finn ut mer"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Forbedrede varsler erstatter tilpassede Android-varsler i Android 12. Denne funksjonen viser foreslåtte handlinger og svar og organiserer varslene dine.\n\nForbedrede varsler har tilgang til varselinnhold, inkludert personopplysninger som kontaktnavn og meldinger. Funksjonen kan også avvise og svare på varsler, for eksempel svare på anrop og kontrollere «Ikke forstyrr»."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Varsel med informasjon om rutinemodus"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Batterisparing er slått på"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduserer batteribruken for å forlenge batterilevetiden"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparing"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Batterisparing er slått av"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonen har nok batteri. Funksjoner begrenses ikke lenger."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Det er ikke mulig å få tilgang til telefonkameraet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Det er ikke mulig å få tilgang til kameraet på nettbrettet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systemstandard"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 6f104048be99..4aa60819e53c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"यसले एपलाई स्क्रिन लकको जटिलताको स्तर (उच्च, मध्यम, न्यून वा कुनै पनि होइन) थाहा पाउने अनुमति दिन्छ जसले स्क्रिन लकको लम्बाइको सम्भावित दायरा र त्यसको प्रकारलाई जनाउँछ। यसै गरी, यो एपले प्रयोगकर्ताहरूलाई स्क्रिन लक अद्यावधिक गर्ने सुझाव पनि दिन सक्छ तर प्रयोगकर्ताहरू उक्त सुझावको बेवास्ता गरी बाहिर निस्कन सक्छन्। स्क्रिन लक सादा पाठको ढाँचामा भण्डारण नगरिने हुँदा यो एपलाई वास्तविक पासवर्ड थाहा नहुने कुराको हेक्का राख्नुहोस्।"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"सूचनाहरू देखाइयोस्"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"यो एपलाई सूचना देखाउन दिनुहोस्"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"स्क्रिन अन गर्ने"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"यो एपलाई स्क्रिन अन गर्ने अनुमति दिन्छ।"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"बायोमेट्रिक हार्डवेयर प्रयोग गर्नुहोस्‌"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"एपलाई प्रमाणीकरणका लागि बायोमेट्रिक हार्डवेयर प्रयोग गर्न अनुमति दिन्छ"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"फिंगरप्रिन्ट हार्डवेयर व्यवस्थापन गर्नुहोस्"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"थप जान्नुहोस्"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android १२ मा Android को अनुकूल पार्न मिल्ने सूचनाहरू नामक सुविधालाई परिष्कृत सूचनाहरू नामक सुविधाले प्रतिस्थापन गरेको छ। यो सुविधाले कारबाही तथा जवाफसम्बन्धी सुझाव देखाउँछ र तपाईंका सूचनाहरू व्यवस्थित गर्छ।\n\nपरिष्कृत सूचनाहरू नामक सुविधाले सूचनामा उल्लिखित सम्पर्क व्यक्तिको नाम र म्यासेज जस्ता व्यक्तिगत जानकारीलगायतका सामग्री हेर्न तथा प्रयोग गर्न सक्छ। यो सुविधाले फोन उठाउने तथा \'बाधा नपुऱ्याउनुहोस्\' मोड नियन्त्रण गर्ने कार्यसहित सूचनाहरू हटाउने वा सूचनाहरूको जवाफ दिने कार्य पनि गर्न सक्छ।"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"दिनचर्या मोडको जानकारीमूलक सूचना"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ब्याट्री सेभर अन गरिएको छ"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ब्याट्रीको आयु बढाउन ब्याट्रीको खपत कम गरिँदै छ"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत फोनको क्यामेरा प्रयोग गर्न मिल्दैन"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत ट्याब्लेटको क्यामेरा प्रयोग गर्न मिल्दैन"</string>
<string name="system_locale_title" msgid="711882686834677268">"सिस्टम डिफल्ट"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 6c4b68e8b814..974d64207e76 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Hiermee krijgt de app toestemming om het complexiteitsniveau van de schermvergrendeling te achterhalen (hoog, midden, laag of geen). Dat geeft een indicatie van het mogelijke lengtebereik en type van de schermvergrendeling. De app kan gebruikers ook voorstellen de schermvergrendeling naar een bepaald niveau te updaten, maar gebruikers kunnen dit altijd negeren en de app verlaten. De schermvergrendeling wordt niet opgeslagen als platte tekst, zodat de app het precieze wachtwoord niet weet."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"meldingen laten zien"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Hiermee kan de app meldingen laten zien"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"het scherm aanzetten"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Hiermee kan de app het scherm aanzetten."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"biometrische hardware gebruiken"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Hiermee kan de app biometrische hardware gebruiken voor verificatie"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"Vingerafdrukhardware beheren"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan geen toegang tot de camera van de telefoon krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan geen toegang tot de camera van de tablet krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systeemstandaard"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 331e300ac116..f5922b912788 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ସ୍କ୍ରିନ୍ ଲକ୍‌ର ଜଟିଳତା ସ୍ତର (ଉଚ୍ଚ, ମଧ୍ୟମ, ନିମ୍ନ କିମ୍ବା କିଛିନୁହେଁ), ଜାଣିବାକୁ ଆପ୍‌କୁ ଅନୁମତି ଦିଅନ୍ତୁ, ଯାହା ସ୍କ୍ରିନ୍ ଲକ୍‌ର ସମ୍ଭାବ୍ୟ ପରିସୀମାର ଲମ୍ବ ଏବଂ ପ୍ରକାର ସୂଚୀତ କରେ। ଆପ୍ ଏହା ମଧ୍ୟ ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରାମର୍ଶ ଦେଇପାରେ ଯେ ସେମାନେ ସ୍କ୍ରିନ୍ ଲକ୍‌କୁ ଏକ ନିର୍ଦ୍ଧିଷ୍ଟ ସ୍ତର ପର୍ଯ୍ୟନ୍ତ ଅପ୍‌ଡେଟ୍ କରିପାରନ୍ତି, କିନ୍ତୁ ଉପଯୋଗକର୍ତ୍ତାମାନେ ନିଜ ଇଚ୍ଛାରେ ଏହାକୁ ଉପେକ୍ଷା ଏବଂ ନାଭିଗେଟ୍ କରିପାରିବେ। ଧ୍ୟାନ ଦିଅନ୍ତୁ ଯେ, ସ୍କ୍ରିନ୍ ଲକ୍ ସରଳ ଟେକ୍ସଟ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇନଥାଏ ତେଣୁ ଆପ୍ ସଠିକ୍ ପାସ୍‌‍ୱର୍ଡ ଜାଣିପାରି ନଥାଏ।"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖାଇବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ସ୍କ୍ରିନ ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ସ୍କ୍ରିନ ଚାଲୁ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ସ୍ୱୀକୃତି ପାଇଁ ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ଟିପଚିହ୍ନ ହାର୍ଡୱେର୍‍ ପରିଚାଳନା କରନ୍ତୁ"</string>
@@ -1151,9 +1153,9 @@
<string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
<string name="app_running_notification_text" msgid="5120815883400228566">"ଅଧିକ ସୂଚନା ପାଇଁ କିମ୍ବା ଆପ୍‍ ବନ୍ଦ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
<string name="ok" msgid="2646370155170753815">"ଠିକ୍‍ ଅଛି"</string>
- <string name="cancel" msgid="6908697720451760115">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+ <string name="cancel" msgid="6908697720451760115">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="yes" msgid="9069828999585032361">"ଠିକ୍‍ ଅଛି"</string>
- <string name="no" msgid="5122037903299899715">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+ <string name="no" msgid="5122037903299899715">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="dialog_alert_title" msgid="651856561974090712">"ଧ୍ୟାନଦିଅନ୍ତୁ"</string>
<string name="loading" msgid="3138021523725055037">"ଲୋଡ୍ କରାଯାଉଛି…"</string>
<string name="capital_on" msgid="2770685323900821829">"ଚାଲୁ"</string>
@@ -1174,9 +1176,9 @@
<string name="whichOpenLinksWithApp" msgid="6917864367861910086">"<xliff:g id="APPLICATION">%1$s</xliff:g> ମାଧ୍ୟମରେ ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
<string name="whichOpenHostLinksWithApp" msgid="2401668560768463004">"<xliff:g id="APPLICATION">%2$s</xliff:g> ମାଧ୍ୟମରେ <xliff:g id="HOST">%1$s</xliff:g> ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
<string name="whichGiveAccessToApplicationLabel" msgid="7805857277166106236">"ଆକ୍ସେସ୍‌ ଦିଅନ୍ତୁ"</string>
- <string name="whichEditApplication" msgid="6191568491456092812">"ସହିତ ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
- <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$sରେ ସଂଶୋଧନ କରନ୍ତୁ"</string>
- <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
+ <string name="whichEditApplication" msgid="6191568491456092812">"ସହିତ ଏଡିଟ କରନ୍ତୁ"</string>
+ <string name="whichEditApplicationNamed" msgid="8096494987978521514">"%1$sରେ ଏଡିଟ କରନ୍ତୁ"</string>
+ <string name="whichEditApplicationLabel" msgid="1463288652070140285">"ଏଡିଟ କରନ୍ତୁ"</string>
<string name="whichSendApplication" msgid="4143847974460792029">"ସେୟାର୍ କରନ୍ତୁ"</string>
<string name="whichSendApplicationNamed" msgid="4470386782693183461">"%1$s ସହିତ ସେୟାର୍‌ କରନ୍ତୁ"</string>
<string name="whichSendApplicationLabel" msgid="7467813004769188515">"ସେୟାର୍‌ କରନ୍ତୁ"</string>
@@ -1318,7 +1320,7 @@
<string name="sms_short_code_details" msgid="2723725738333388351">"ଏହା ଦ୍ୱାରା "<b>" ଆପଣଙ୍କ ମୋବାଇଲ୍ ଆକାଉଣ୍ଟରୁ ପଇସା କଟିପାରେ। "</b></string>
<string name="sms_premium_short_code_details" msgid="1400296309866638111"><b>" ଆପଣଙ୍କ ମୋବାଇଲ୍ ଆକାଉଣ୍ଟରୁ ପଇସା କଟିପାରେ। "</b></string>
<string name="sms_short_code_confirm_allow" msgid="920477594325526691">"ପଠାନ୍ତୁ"</string>
- <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+ <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="sms_short_code_remember_choice" msgid="1374526438647744862">"ମୋ ପସନ୍ଦ ମନେରଖନ୍ତୁ"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"ଏହାକୁ ଆପଣ ସେଟିଙ୍ଗ ଓ ଆପ୍‍ରେ ପରବର୍ତ୍ତୀ ସମୟରେ ବଦଳାଇପାରିବେ"</string>
<string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"ସର୍ବଦା ଅନୁମତି ଦିଅନ୍ତୁ"</string>
@@ -1355,7 +1357,7 @@
<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>
+ <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="adbwifi_active_notification_title" msgid="6147343659168302473">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ସଂଯୋଗ କରାଯାଇଛି"</string>
@@ -1541,7 +1543,7 @@
<string name="date_picker_prev_month_button" msgid="3418694374017868369">"ପୂର୍ବ ମାସ"</string>
<string name="date_picker_next_month_button" msgid="4858207337779144840">"ପରବର୍ତ୍ତୀ ମାସ"</string>
<string name="keyboardview_keycode_alt" msgid="8997420058584292385">"ALT"</string>
- <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ୍‍ କରନ୍ତୁ"</string>
+ <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
<string name="keyboardview_keycode_done" msgid="2524518019001653851">"ହୋଇଗଲା"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"ମୋଡ୍‍ ପରିବର୍ତ୍ତନ"</string>
@@ -1564,7 +1566,7 @@
<string name="storage_usb_drive" msgid="448030813201444573">"USB ଡ୍ରାଇଭ୍‍"</string>
<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="extract_edit_menu_button" msgid="63954536535863040">"ଏଡିଟ କରନ୍ତୁ"</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>
@@ -1690,7 +1692,7 @@
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"ଭଲ୍ୟୁମ୍ କୀ ସର୍ଟକଟ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ବନ୍ଦ ହୋଇଯାଇଛି"</string>
- <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ"</string>
+ <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ହୋଇଗଲା"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ଶର୍ଟକଟ୍‍ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -2045,7 +2047,7 @@
<string name="log_access_confirmation_body" msgid="6581985716241928135">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ବି ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି। ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍‌କୁ ଦେଖାଇବା ପାଇଁ ଚାହେଁ"</string>
- <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ୍ କରନ୍ତୁ"</string>
+ <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ କରନ୍ତୁ"</string>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଭାଇବ୍ରେଟ୍ ହେବ"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ନିଃଶବ୍ଦ କରିଦିଆଯିବ"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"ସିଷ୍ଟମ୍‌ରେ ପରିବର୍ତ୍ତନ"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଫୋନର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଟାବଲେଟର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="system_locale_title" msgid="711882686834677268">"ସିଷ୍ଟମ ଡିଫଲ୍ଟ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2f3294e5bbf6..ce8d32330aeb 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ਐਪ ਨੂੰ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਜਟਿਲਤਾ ਦੇ ਪੱਧਰ ਬਾਰੇ ਜਾਣਨ ਦਿਓ (ਉੱਚ, ਮੱਧਮ, ਘੱਟ ਜਾਂ ਕੋਈ ਨਹੀਂ), ਜੋ ਲੰਬਾਈ ਦੀ ਸੰਭਵ ਰੇਂਜ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਕਿਸਮ ਦਾ ਸੰਕੇਤ ਦਿੰਦਾ ਹੈ। ਐਪ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਇੱਕ ਖਾਸ ਪੱਧਰ ਤੱਕ ਸਕ੍ਰੀਨ ਲਾਕ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੁਝਾਅ ਵੀ ਦੇ ਸਕਦੀ ਹੈ ਪਰ ਵਰਤੋਂਕਾਰ ਇਸਨੂੰ ਅਣਡਿੱਠ ਕਰ ਸਕਦੇ ਹਨ। ਨੋਟ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲਾਕ ਸਧਾਰਨ ਲਿਖਤ ਵਿੱਚ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਇਸ ਲਈ ਐਪ ਸਹੀ ਪਾਸਵਰਡ ਬਾਰੇ ਨਹੀਂ ਜਾਣਦੀ ਹੈ।"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਸੂਚਨਾਵਾਂ ਦਿਖਾਉਣ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ਸਕ੍ਰੀਨ ਚਾਲੂ ਕਰੋ"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ਐਪ ਨੂੰ ਸਕ੍ਰੀਨ ਚਾਲੂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ।"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦਿੰਦਾ ਹੈ"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
@@ -1267,7 +1269,7 @@
<string name="volume_ringtone" msgid="134784084629229029">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string>
<string name="volume_music" msgid="7727274216734955095">"ਮੀਡੀਆ ਦੀ ਅਵਾਜ਼"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Bluetooth ਰਾਹੀਂ ਪਲੇ ਕਰ ਰਿਹਾ ਹੈ"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"ਖਾਮੋਸ਼ ਰਿੰਗਟੋਨ ਸੈੱਟ ਕੀਤੀ"</string>
+ <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">"ਬਲੂਟੁੱਥ ਇਨ-ਕਾਲ ਅਵਾਜ਼"</string>
<string name="volume_alarm" msgid="4486241060751798448">"ਅਲਾਰਮ ਦੀ ਅਵਾਜ਼"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਫ਼ੋਨ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਟੈਬਲੈੱਟ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
<string name="system_locale_title" msgid="711882686834677268">"ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 55c4574f77a0..6fc06962e9ef 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Zezwala aplikacji na poznanie stopnia złożoności blokady ekranu (wysoki, średni, niski lub brak), który wskazuje na możliwy zakres długości oraz typ blokady ekranu. Aplikacja może też zasugerować zaktualizowanie blokady ekranu pod kątem określonego stopnia trudności, ale użytkownik może to zignorować i zamknąć komunikat. Pamiętaj, że blokada ekranu nie jest zapisywana jako tekst jawny, więc aplikacja nie pozna dokładnego hasła."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"pokazuj powiadomienia"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Zezwala aplikacji na pokazywanie powiadomień"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"włączanie ekranu"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Zezwala aplikacji na włączanie ekranu."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"używanie sprzętu biometrycznego"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Zezwala aplikacji na używanie sprzętu biometrycznego na potrzeby autoryzacji"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"zarządzanie czytnikiem linii papilarnych"</string>
@@ -2286,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nie można korzystać z aparatu telefonu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nie można korzystać z aparatu tabletu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Ustawienie domyślne systemu"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index a02c200c0f4f..caa8cd18f36d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificações"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que o app mostre notificações"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ligar a tela"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que o app ligue a tela."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"Usar hardware de biometria"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que o app use hardware de biometria para autenticação"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gerenciar hardware de impressão digital"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Padrão do sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index d804c238ac3c..3b7c16254584 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que a app aprenda o nível de complexidade do bloqueio de ecrã (elevado, médio, baixo ou nenhum), que indica o intervalo de comprimento e o tipo de bloqueio de ecrã possíveis. A app também pode sugerir aos utilizadores que atualizem o bloqueio de ecrã para um determinado nível, mas estes podem ignorar livremente a sugestão e continuar a navegação. Tenha em atenção que o bloqueio de ecrã não é armazenado em texto simples, pelo que a app desconhece a palavra-passe exata."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificações"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite à app mostrar notificações"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ativar o ecrã"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que a app ative o ecrã."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"Utilizar hardware biométrico"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que a app utilize hardware biométrico para autenticação."</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gerir o hardware de impressão digital"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível aceder à câmara do telemóvel a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível aceder à câmara do tablet a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predefinição do sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a02c200c0f4f..caa8cd18f36d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"mostrar notificações"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite que o app mostre notificações"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ligar a tela"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite que o app ligue a tela."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"Usar hardware de biometria"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite que o app use hardware de biometria para autenticação"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gerenciar hardware de impressão digital"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Padrão do sistema"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 55ba527f46f0..1b74fd8fd43e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -554,6 +554,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permite aplicației să învețe nivelul de complexitate al blocării ecranului (ridicat, mediu, scăzut sau fără), fapt ce indică intervalul posibil de lungime a parolei și tipul de blocare a ecranului. Aplicația le poate sugera utilizatorilor să își actualizeze blocarea ecranului la un anumit nivel, dar utilizatorii pot ignora sugestia și pot naviga în continuare. Rețineți că blocarea ecranului nu este stocată ca text simplu, astfel încât aplicația să nu cunoască parola exactă."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"să afișeze notificări"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Permite aplicației să afișeze notificări"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"să activeze ecranul"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Permite aplicației să activeze ecranul."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utilizați hardware biometric"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permite aplicației să folosească hardware biometric pentru autentificare"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"gestionează hardware-ul pentru amprentă"</string>
@@ -2285,4 +2287,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nu se poate accesa camera foto a telefonului de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nu se poate accesa camera foto a tabletei de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Prestabilit de sistem"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1ef3c0cf8b9e..16a8e163c83e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Приложение получит доступ к сведениям об уровне сложности блокировки экрана (высокий, средний, низкий или отсутствует), в том числе о типе блокировки и длине пароля. Кроме того, оно сможет предлагать пользователям повысить уровень сложности блокировки. Эти рекомендации необязательны. Обратите внимание, что пароль не хранится в виде открытого текста и недоступен приложению."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"показ уведомлений"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Приложение сможет показывать уведомления."</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"Включение экрана"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Приложение сможет включать экран."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"Использование биометрического оборудования"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Приложение сможет использовать биометрическое оборудование для аутентификации"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"управление сканером отпечатков пальцев"</string>
@@ -2077,10 +2079,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Подробнее"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 доступны улучшенные уведомления. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Уведомление о батарее"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Включен режим энергосбережения"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Экономия заряда продлит время работы от батареи."</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>
@@ -2288,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере телефона."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере планшета."</string>
<string name="system_locale_title" msgid="711882686834677268">"Системные настройки по умолчанию"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 3f0d0e57bdb1..4cc1370e479d 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"යෙදුමට තිර අගුලෙහි තිබිය හැකි දිගෙහි පරාසය සහ වර්ගය පිළිබිඹු කරන, තිර අඟුලු සංකීර්ණතා මට්ටම (ඉහළ, මධ්‍යම, අඩු හෝ රහිත) දැන ගැනීමට ඉඩ දෙයි. යෙදුම පරිශීලකයින්ට තිර අඟුල නිශ්චිත මට්ටමකට යාවත්කාලීන කිරීමට යෝජනා කළ හැකි නමුත් ඔවුන්ට නිදහසේ නොසලකා හැර ඉවතට සංචලන කළ හැක. තිර අඟුල සරල පෙළින් ගබඩා කර නැති බැවින් යෙදුම නිවැරදි මුරපදය නොදන්නා බව සලකන්න."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"දැනුම්දීම් පෙන්වන්න"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"දැනුම්දීම් පෙන්වීමට යෙදුමට ඉඩ දෙයි"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"තිරය ක්‍රියාත්මක කරන්න"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"තිරය ක්‍රියාත්මක කිරීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ජීවමිතික දෘඪාංග භාවිත කරන්න"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"සත්‍යාපනය සඳහා ජීවමිතික දෘඪාංග භාවිත කිරීමට යෙදුමට ඉඩ දෙයි"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ඇඟිලි සලකුණු දෘඩාංග කළමනාකරණය කිරීම."</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් දුරකථනයේ කැමරාවට ප්‍රවේශ විය නොහැකිය"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් ටැබ්ලටයේ කැමරාවට ප්‍රවේශ විය නොහැකිය"</string>
<string name="system_locale_title" msgid="711882686834677268">"පද්ධති පෙරනිමිය"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index fa4f98a3c40a..92e0d8225920 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Umožňuje aplikácii zapamätať si úroveň zložitosti zámky obrazovky (vysoká, stredná, nízka alebo žiadna), ktorá udáva pravdepodobný rozsah dĺžky a typu zámky obrazovky. Aplikácia tiež navrhuje používateľom aktualizáciu zámky obrazovky na určitú úroveň, používatelia sa však môžu na základe vlastného uváženia rozhodnúť tento návrh ignorovať a prejsť inam. Upozorňujeme, že zámka obrazovky nie je uložená vo forme obyčajného textu, takže aplikácia nepozná presné heslo."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"zobrazovať upozornenia"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Povolí aplikácii zobrazovať upozornenia"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"zapnúť obrazovku"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Umožňuje aplikácii zapnúť obrazovku."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"používať biometrický hardvér"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Umožňuje aplikácii používať na overenie totožnosti biometrický hardvér"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"spravovať hardvér na snímanie odtlačkov prstov"</string>
@@ -2062,7 +2064,7 @@
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Zavrieť"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavenia"</string>
- <string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparát"</string>
+ <string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
<string name="notification_appops_microphone_active" msgid="581333393214739332">"Mikrofón"</string>
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"sa zobrazuje cez ďalšie aplikácie na obrazovke"</string>
<string name="notification_feedback_indicator" msgid="663476517711323016">"Poskytnúť spätnú väzbu"</string>
@@ -2286,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere telefónu"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere tabletu"</string>
<string name="system_locale_title" msgid="711882686834677268">"Predvolené systémom"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 7cbd93ea4e58..aec8232628a6 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Aplikaciji dovoljuje, da pridobi raven zapletenosti zaklepanja zaslona (visoka, srednja, nizka ali brez), ki označuje možen obseg dolžine in vrsto zaklepanja zaslona. Aplikacija lahko tudi predlaga uporabnikom, da posodobijo zaklepanje zaslona na določeno raven, vendar lahko uporabniki to opozorilo prezrejo in ga zaprejo tako, da se pomaknejo stran. Upoštevajte, da zaklepanje zaslona ni shranjeno v golem besedilu, tako da aplikacija ne pozna točnega gesla."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"prikaz obvestil"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Aplikaciji dovoli prikaz obvestil."</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"vklop zaslona"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Aplikaciji dovoli vklop zaslona."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"uporaba strojne opreme za biometrične podatke"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Aplikaciji omogoča uporabo strojne opreme za biometrične podatke za preverjanje pristnosti"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"upravljanje strojne opreme za prstne odtise"</string>
@@ -2077,10 +2079,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Več o tem"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pametna obvestila so v Androidu 12 zamenjala prilagodljiva obvestila Android. Ta funkcija prikazuje predlagana dejanja in odgovore ter organizira vaša obvestila.\n\nPametna obvestila lahko preberejo vso vsebino obvestil, vključno z osebnimi podatki, kot so imena in sporočila stikov. Ta funkcija lahko tudi opusti obvestila ali se odziva nanje (npr. sprejema telefonske klice in upravlja način Ne moti)."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutinsko informativno obvestilo o načinu delovanja"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Varčevanje z energijo baterije je vklopljeno"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Manjša poraba energije baterije za podaljšanje časa delovanja baterije"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Varčevanje z energijo baterije"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Varčevanje z energijo baterije je izklopljeno"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Baterija v telefonu je dovolj napolnjena. Funkcije niso več omejene."</string>
@@ -2288,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ni mogoče dostopati do fotoaparata telefona prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ni mogoče dostopati do fotoaparata tabličnega računalnika prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistemsko privzeto"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 37092da1628f..6554eb800239 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Lejo që aplikacioni të mësojë nivelin e kompleksitetit të kyçjes së ekranit (i lartë, i mesëm, i ulët ose asnjë), që tregon gamën e mundshme të gjatësisë dhe llojin e kyçjes së ekranit. Aplikacioni mund t\'u sugjerojë gjithashtu përdoruesve që të përditësojnë kyçjen e ekranit në një nivel të caktuar, por përdoruesit mund ta shpërfillin lirshëm dhe të navigojnë më tej. Ki parasysh se kyçja e ekranit nuk ruhet në tekst të thjeshtë, prandaj aplikacioni nuk e di fjalëkalimin e saktë."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"shfaq njoftimet"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Lejon që aplikacioni të shfaqë njoftime"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"aktivizo ekranin"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Lejon që aplikacioni të aktivizojë ekranin."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"përdor harduerin biometrik"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"E lejon aplikacionin që të përdorë harduerin biometrik për vërtetimin"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"të menaxhojë harduerin e gjurmës së gishtit"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nuk mund të qasesh në kamerën e telefonit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nuk mund të qasesh në kamerën e tabletit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Parazgjedhja e sistemit"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a9cd08937afd..cb1f34da2d75 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -554,6 +554,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"приказивање обавештења"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Дозвољава апликацији да приказује обавештења"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"укључивање екрана"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дозвољава апликацији да укључи екран."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"користи биометријски хардвер"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"управљај хардвером за отиске прстију"</string>
@@ -2285,4 +2287,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се приступи камери телефона са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се приступи камери таблета са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
<string name="system_locale_title" msgid="711882686834677268">"Подразумевани системски"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c8d982dcdf81..a8d0cced54cb 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Tillåter att appen får reda på komplexitetsnivån för skärmlåset (hög, mellan, låg eller ingen). Detta ger en indikation på skärmlåsets möjliga längd och typ. Appen kan även föreslå att skärmlåset uppdateras till en viss nivå, men användare kan ignorera förslaget och fortsätta navigera. Observera att skärmlåset inte lagras i vanlig text så appen får inte reda på det exakta lösenordet."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"visa aviseringar"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Tillåter att appen visar aviseringar"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"Slå på skärmen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Tillåter att appen slår på skärmen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"använd biometrisk maskinvara"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Tillåter att appen använder biometrisk maskinvara vid autentisering"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"hantera maskinvara för fingeravtryck"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Läs mer"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Förbättrade aviseringar har ersatt Anpassade aviseringar för Android i Android 12. Den här funktionen visar förslag på åtgärder och svar och organiserar dina aviseringar.\n\nFörbättrade aviseringar har åtkomst till allt innehåll i aviseringar, inklusive personliga uppgifter som namn på kontakter och meddelanden. Funktionen kan även ignorera aviseringar eller utföra åtgärder utifrån dem, till exempel svara på telefonsamtal och styra Stör ej."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Avisering om rutinläge"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Batterisparläget har aktiverats"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Minskar batteriförbrukning för att förlänga batteritiden"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Batterisparläge"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Batterisparläget har inaktiverats"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefonen har laddats tillräckligt. Funktioner begränsas inte längre."</string>
@@ -2269,7 +2269,7 @@
<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_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Avblockera"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Telefonens kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Surfplattans kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Systemets standardinställning"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2d7ef7cb336a..9f10d910ca84 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Huruhusu programu kupata maelezo kuhusu kiwango cha uchangamano wa kufunga skrini (juu, wastani, chini au hakuna), ambacho huashiria urefu unaowezekana na aina ya kufunga skrini. Programu pia inaweza kumpendekezea mtumiaji asasishe mbinu ya kufunga skrini iwe ya kiwango fulani lakini mtumiaji anaweza kuamua kupuuza na kuendelea. Kumbuka kuwa maelezo ya kufunga skrini hayahifadhiwi kama maandishi, hivyo programu haitambui nenosiri mahususi."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"kuonyesha arifa"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Huruhusu programu kuonyesha arifa"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"washa skrini"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Huruhusu programu iwashe skrini."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"tumia maunzi ya kibiolojia"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Huruhusu programu itumie maunzi ya kibiolojia katika uthibitishaji"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"dhibiti maunzi ya alama ya kidole"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pata maelezo zaidi"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Kipengele cha Arifa Zilizoboreshwa kilichukua nafasi ya Arifa Zinazojirekebisha za Android katika Android 12. Kipengele hiki kinaonyesha majibu na vitendo vinavyopendekezwa na kupanga arifa zako.\n\nKipengele cha Arifa zilizoboreshwa kinaweza kufikia maudhui ya arifa, ikiwa ni pamoja na taarifa binafsi kama vile majina ya anwani na ujumbe. Kipengele hiki kinaweza pia kuondoa au kujibu arifa, kama vile kujibu simu na kudhibiti kipengele cha Usinisumbue."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Arifa ya maelezo ya Hali ya Kawaida"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Kiokoa Betri kimewashwa"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Inapunguza matumizi ya betri ili kuongeza muda wa matumizi ya betri"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Kiokoa betri"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Kiokoa Betri kimezimwa"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Simu ina chaji ya kutosha. Vipengele havizuiliwi tena."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Haiwezi kufikia kamera ya simu kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Haiwezi kufikia kamera ya kompyuta kibao kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
<string name="system_locale_title" msgid="711882686834677268">"Chaguomsingi la mfumo"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 5acfd9306132..fbb4884efbf4 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையை (அதிகம், நடுத்தரம், குறைவு அல்லது ஏதுமில்லை) அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கிறது. இதன் மூலம் திரைப் பூட்டின் அளவு வரம்பையும் வகையையும் தெரிந்துகொள்ளலாம். மேலும் திரைப் பூட்டைக் குறிப்பிட்ட நிலைக்கு மாற்றிக் கொள்ளலாம் என்பதையும் பயனர்களுக்கு ஆப்ஸ் பரிந்துரைக்க முடியும். ஆனால் தங்கள் விருப்பப்படி அவற்றைப் பயனர்கள் நிராகரிக்கவோ ஏற்கவோ இயலும். கவனத்திற்கு: திரைப் பூட்டு எளிய உரையிலானதாக சேமிக்கப்படுவதில்லை என்பதால் சரியான கடவுச்சொல்லை ஆப்ஸால் அறிய இயலாது."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"அறிவிப்புகளைக் காட்டுதல்"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"அறிவிப்புகளைக் காட்ட ஆப்ஸை அனுமதிக்கும்"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"திரையைக் காட்டுதல்"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"திரையைக் காட்ட ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்து"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்தி அங்கீகரிப்பதற்கு, ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"கைரேகை வன்பொருளை நிர்வகி"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"மேலும் அறிக"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 பதிப்பில் \'Android சூழலுக்கேற்ற அறிவிப்புகள்\' அம்சத்திற்குப் பதிலாக \'மேம்பட்ட அறிவிப்புகள்\' மாற்றப்பட்டுள்ளது. இந்த அம்சம், பரிந்துரைக்கப்படும் செயல்களையும் பதில்களையும் காட்டுவதுடன் உங்கள் அறிவிப்புகளையும் ஒழுங்கமைக்கும்.\n\nதொடர்புகளின் பெயர்கள், மெசேஜ்கள் போன்ற தனிப்பட்ட தகவல்கள் உட்பட அனைத்து அறிவிப்பு உள்ளடக்கத்தையும் \'மேம்பட்ட அறிவிப்புகள்\' அணுக முடியும். மேலும் இந்த அம்சத்தால் அறிவிப்புகளை நிராகரிக்கவும் அவற்றுக்குப் பதிலளிக்கவும் முடியும் (அழைப்புகளுக்குப் பதிலளிப்பது, \'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தைக் கட்டுப்படுத்துவது போன்றவை)."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"பேட்டரி சேமிப்பு இயக்கப்பட்டுள்ளது"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"பேட்டரி ஆயுளை நீட்டிக்க, பேட்டரி உபயோகத்தைக் குறைக்கிறது"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து மொபைலின் கேமராவை அணுக முடியாது"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து டேப்லெட்டின் கேமராவை அணுக முடியாது"</string>
<string name="system_locale_title" msgid="711882686834677268">"சிஸ்டத்தின் இயல்பு"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6882e3da9a41..390cdcfe812e 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -466,7 +466,7 @@
<string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS కాల్ సేవ యాక్సెస్ అనుమతి"</string>
<string name="permdesc_accessImsCallService" msgid="6328551241649687162">"మీ ప్రమేయం లేకుండా కాల్స్‌ చేయడం కోసం IMS సేవను ఉపయోగించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"ఫోన్ స్టేటస్‌ మరియు గుర్తింపుని చదవడం"</string>
- <string name="permdesc_readPhoneState" msgid="7229063553502788058">"పరికరం యొక్క ఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ సక్రియంగా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్‌ను కనుగొనడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+ <string name="permdesc_readPhoneState" msgid="7229063553502788058">"పరికరం యొక్క ఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. ఈ అనుమతి ఫోన్ నంబర్ మరియు పరికరం IDలను, కాల్ యాక్టివ్‌గా ఉందా లేదా అనే విషయాన్ని మరియు కాల్ ద్వారా కనెక్ట్ చేయబడిన రిమోట్ నంబర్‌ను కనుగొనడానికి యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"ప్రాథమిక టెలిఫోన్ స్టేటస్, గుర్తింపును చదవండి"</string>
<string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"పరికరం తాలూకు ప్రాథమిక టెలిఫోన్ ఫీచర్‌లను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_manageOwnCalls" msgid="9033349060307561370">"కాల్స్‌ను సిస్టమ్ ద్వారా వెళ్లేలా చేయి"</string>
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ఇది మీ స్క్రీన్ లాక్ పాస్‌వర్డ్‌ సంక్లిష్టత స్థాయి (తీవ్రంగా ఉండాలా, ఓ మోస్తరుగా ఉండాలా, తక్కువ తీవ్రంగా ఉండాలా లేదా అస్సలు తీవ్రత ఉండకూడదా) తెలుసుకోవడానికి యాప్‌ను అనుమతిస్తుంది, అంటే పొడుగు ఎంత ఉండాలి, ఏ రకమైన స్క్రీన్ లాక్ పధ్ధతి అనుసరించాలో సూచిస్తుంది. అలాగే, స్క్రీన్ లాక్‌ పాస్‌వర్డ్‌ సంక్లిష్టతను ఏ స్థాయికి సెట్ చేసుకుంటే బాగుంటుందో కూడా వినియోగదారులకు యాప్ సూచించగలదు, కానీ వినియోగదారులు నిరభ్యంతరంగా ఆ సూచనలను పట్టించుకోకుండా వారి ఇష్టం మేరకు చక్కగా సెట్ చేసుకోవచ్చు. ఇంకో ముఖ్య విషయం, స్క్రీన్ లాక్‌ అన్నది సాదా వచన రూపంలో నిల్వ చేయబడదు, కనుక ఖచ్చితమైన పాస్‌వర్డ్‌ ఏమిటనేది యాప్‌కు తెలియదు."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"నోటిఫికేషన్‌లను చూపండి"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"నోటిఫికేషన్‌లను చూపించడానికి యాప్‌ను అనుమతించండి"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"స్క్రీన్‌ను ఆన్ చేయండి"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"స్క్రీన్‌ను ఆన్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"బయోమెట్రిక్ హార్డ్‌వేర్‌ని ఉపయోగించు"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ప్రమాణీకరణ కోసం బయోమెట్రిక్ హార్డ్‌వేర్‌ను ఉపయోగించడానికి యాప్‌ని అనుమతిస్తుంది"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"వేలిముద్ర హార్డ్‌వేర్‌ని నిర్వహించడానికి అనుమతి"</string>
@@ -1136,7 +1138,7 @@
<string name="copyUrl" msgid="6229645005987260230">"URLని కాపీ చేయి"</string>
<string name="selectTextMode" msgid="3225108910999318778">"వచనాన్ని ఎంచుకోండి"</string>
<string name="undo" msgid="3175318090002654673">"చర్య రద్దు చేయి"</string>
- <string name="redo" msgid="7231448494008532233">"చర్యను పునరావృతం చేయి"</string>
+ <string name="redo" msgid="7231448494008532233">"చర్యను రిపీట్‌ చేయి"</string>
<string name="autofill" msgid="511224882647795296">"ఆటోఫిల్"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"వచన ఎంపిక"</string>
<string name="addToDictionary" msgid="8041821113480950096">"నిఘంటువుకు జోడించు"</string>
@@ -1329,7 +1331,7 @@
<string name="sim_added_title" msgid="7930779986759414595">"సిమ్ కార్డు జోడించబడింది"</string>
<string name="sim_added_message" msgid="6602906609509958680">"మొబైల్ నెట్‌వర్క్‌ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"రీస్టార్ట్ చేయండి"</string>
- <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను సక్రియం చేయండి"</string>
+ <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను యాక్టివేట్ చేయండి"</string>
<string name="install_carrier_app_notification_text" msgid="2781317581274192728">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్‌ను డౌన్‌లోడ్ చేయండి"</string>
<string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్‌ని డౌన్‌లోడ్ చేయండి"</string>
<string name="install_carrier_app_notification_button" msgid="6257740533102594290">"యాప్‌ని డౌన్‌లోడ్ చేయి"</string>
@@ -1378,7 +1380,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>
@@ -1642,7 +1644,7 @@
<string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"చెల్లని పిన్‌ కోడ్."</string>
<string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"4 నుండి 8 సంఖ్యలు ఉండే పిన్‌ను టైప్ చేయండి."</string>
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK కోడ్ 8 సంఖ్యలు ఉండాలి."</string>
- <string name="kg_invalid_puk" msgid="4809502818518963344">"సరైన PUK కోడ్‌ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
+ <string name="kg_invalid_puk" msgid="4809502818518963344">"సరైన PUK కోడ్‌ను మళ్లీ నమోదు చేయండి. రిపీట్ ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"పిన్‌ కోడ్‌లు సరిపోలలేదు"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"చాలా ఎక్కువ ఆకృతి ప్రయత్నాలు చేశారు"</string>
<string name="kg_login_instructions" msgid="3619844310339066827">"అన్‌లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string>
@@ -1684,7 +1686,7 @@
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్‌పై ఉండే కంటెంట్‌ మొత్తాన్ని చదవగలుగుతుంది మరియు ఇతర యాప్‌లలో కూడా ఈ కంటెంట్‌ను ప్రదర్శిస్తుంది."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయగలగడం"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్‌‌తో చేసే ఇంటరాక్షన్‌లను లేదా హార్డ్‌వేర్ సెన్సార్‌ను ట్రాక్ చేస్తూ మీ త‌ర‌ఫున యాప్‌లతో ఇంటరాక్ట్ చేయగలదు."</string>
- <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించు"</string>
+ <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించండి"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"నిరాకరించు"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ఫీచర్‌ని ఉపయోగించడం ప్రారంభించడానికి, దాన్ని ట్యాప్ చేయండి:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"యాక్సెసిబిలిటీ బటన్‌తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
@@ -1972,7 +1974,7 @@
<string name="tooltip_popup_title" msgid="7863719020269945722">"సాధనం చిట్కా"</string>
<string name="app_category_game" msgid="4534216074910244790">"గేమ్‌లు"</string>
<string name="app_category_audio" msgid="8296029904794676222">"సంగీతం &amp; ఆడియో"</string>
- <string name="app_category_video" msgid="2590183854839565814">"చలనచిత్రాలు &amp; వీడియో"</string>
+ <string name="app_category_video" msgid="2590183854839565814">"సినిమాలు &amp; వీడియో"</string>
<string name="app_category_image" msgid="7307840291864213007">"ఫోటోలు, ఇమేజ్‌లు"</string>
<string name="app_category_social" msgid="2278269325488344054">"సామాజికం &amp; కమ్యూనికేషన్"</string>
<string name="app_category_news" msgid="1172762719574964544">"వార్తలు &amp; వార్తాపత్రికలు"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి ఫోన్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి టాబ్లెట్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
<string name="system_locale_title" msgid="711882686834677268">"సిస్టమ్ ఆటోమేటిక్ సెట్టింగ్"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 34d2dbf58003..e43f84d0fe26 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"อนุญาตให้แอปเรียนรู้ระดับความซับซ้อนของการล็อกหน้าจอ (สูง ปานกลาง ต่ำ หรือไม่มี) ซึ่งแสดงให้เห็นช่วงความยาวและประเภทของการล็อกหน้าจอที่เป็นไปได้ นอกจากนี้แอปยังแนะนำให้ผู้ใช้อัปเดตการล็อกหน้าจอเป็นระดับหนึ่งๆ ได้ด้วย แต่ผู้ใช้จะปฏิเสธและไปยังส่วนต่างๆ ต่อได้ โปรดทราบว่าระบบไม่ได้จัดเก็บการล็อกหน้าจอไว้เป็นข้อความธรรมดา เพื่อให้แอปไม่รู้รหัสผ่าน"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"แสดงการแจ้งเตือน"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"อนุญาตให้แอปแสดงการแจ้งเตือน"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"เปิดหน้าจอ"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"อนุญาตให้แอปเปิดหน้าจอ"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"ใช้ฮาร์ดแวร์ชีวมิติ"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"อนุญาตให้แอปใช้ฮาร์ดแวร์ชีวมิติเพื่อตรวจสอบสิทธิ์"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"จัดการฮาร์ดแวร์ลายนิ้วมือ"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ดูข้อมูลเพิ่มเติม"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"การแจ้งเตือนที่เพิ่มประสิทธิภาพมาแทนที่การแจ้งเตือนแบบปรับอัตโนมัติของ Android ใน Android 12 ฟีเจอร์นี้จะแสดงการดำเนินการและการตอบกลับที่แนะนำ ตลอดจนจัดระเบียบการแจ้งเตือน\n\nการแจ้งเตือนที่เพิ่มประสิทธิภาพจะเข้าถึงเนื้อหาของการแจ้งเตือนได้ ซึ่งรวมถึงข้อมูลส่วนบุคคล เช่น ชื่อผู้ติดต่อและข้อความ ฟีเจอร์นี้ยังปิดหรือตอบสนองต่อการแจ้งเตือนได้ด้วย เช่น การรับสายโทรศัพท์และการควบคุมโหมดห้ามรบกวน"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"การแจ้งเตือนข้อมูลโหมดกิจวัตร"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"เปิดโหมดประหยัดแบตเตอรี่แล้ว"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ลดการใช้งานแบตเตอรี่เพื่อยืดอายุการใช้งานแบตเตอรี่"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"เข้าถึงกล้องของโทรศัพท์จาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"เข้าถึงกล้องของแท็บเล็ตจาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
<string name="system_locale_title" msgid="711882686834677268">"ค่าเริ่มต้นของระบบ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 21c18beada62..bbafd022d64e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Pinapayagan ang app na malaman ang antas ng pagiging kumplikado ng lock ng screen (mataas, katamtaman, mababa, o wala), na nagsasaad ng posibleng hanay ng haba at uri ng lock ng screen. Puwede ring imungkahi ng app sa mga user na i-update nila ang lock ng screen sa isang partikular na antas ngunit malaya ang mga user na balewalain ito at mag-navigate palayo. Tandaang hindi naka-store bilang plaintext ang lock ng screen kaya hindi alam ng app ang eksaktong password."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"magpakita ng mga notification"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Pinapayagan ang app na magpakita ng mga notification"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"i-on ang screen"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Nagpapahintulot sa app na i-on ang screen."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"gumamit ng biometric hardware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Pinapayagan ang app na gumamit ng biometric hardware para sa pag-authenticate"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"pamahalaan ang hardware ng fingerprint"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Matuto pa"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pinalitan ng Mga pinahusay na notification ang Mga Adaptive na Notification ng Android sa Android 12. Nagpapakita ng mga iminumungkahing pagkilos at sagot ang feature na ito, at isinasaayos nito ang iyong mga notification.\n\nMaa-access ng Mga pinahusay na notification ang content ng notification, kabilang ang personal na impormasyon gaya ng mga pangalan ng contact at mensahe. Magagawa rin ng feature na ito na i-dismiss o tugunan ang mga notification, gaya ng pagsagot sa mga tawag sa telepono, at kontrolin ang Huwag Istorbohin."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification ng impormasyon ng Routine Mode"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Na-on ang Pantipid ng Baterya"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Binabawasan ang paggamit sa baterya para mapatagal ang baterya"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pantipid ng Baterya"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Na-off ang Pantipid ng Baterya"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"May sapat na charge ang telepono. Hindi na pinaghihigpitan ang mga feature."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Hindi ma-access ang camera ng telepono mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Hindi ma-access ang camera ng tablet mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Default ng system"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 29e6811f8c43..349947810b20 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Uygulamanın, ekran kilidi karmaşıklık seviyesini (yüksek, orta, düşük veya yok) öğrenmesini sağlar. Ekran kilidi karmaşıklık seviyesi, ekran kilidinin olası uzunluk aralığını ve türünü gösterir. Uygulama, kullanıcılara ekran kilidini belirli bir seviyeye güncellemelerini de önerebilir, ancak kullanıcılar bunu istedikleri gibi yoksayabilir ve geçebilirler. Ekran kilidi şifrelenmemiş metin olarak saklanmadığı için uygulamanın şifreyi tam olarak bilmediğini unutmayın."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"bildirimleri göster"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Uygulamanın bildirimleri göstermesine izin verir"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekranı aç"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Uygulamaya ekranı açma izni verir."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"biyometrik donanım kullan"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Uygulamanın kimlik doğrulama için biyometrik donanım kullanmasına izin verir"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"parmak izi donanımını yönetme"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Daha fazla bilgi"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Gelişmiş bildirimler, Android 12\'de Android Uyarlanabilir Bildirimler\'in yerini aldı. Bu özellik, önerilen işlem ve yanıtları gösterir ve bildirimlerinizi organize eder.\n\nGelişmiş bildirimler, kişiler ve mesajlar gibi kişisel bilgiler dahil olmak üzere tüm bildirim içeriklerine erişebilir. Bu özellik ayrıca bildirimleri kapatabilir veya telefon aramalarını yanıtlamak ve Rahatsız Etmeyin modunu kontrol etmek gibi işlemlerle bildirimlere yanıt verebilir."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutin Modu bilgi bildirimi"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Pil Tasarrufu açıldı"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Pil ömrünü uzatmak için pil kullanımını azaltma"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Pil Tasarrufu"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Pil Tasarrufu kapatıldı"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Telefon yeterince şarj oldu. Özellikler artık kısıtlanmış değil."</string>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına erişilemiyor"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan tabletin kamerasına erişilemiyor"</string>
<string name="system_locale_title" msgid="711882686834677268">"Sistem varsayılanı"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 72b90b21072b..2b7d9cce7833 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -555,6 +555,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозволяє додатку визначати рівень складності способу блокування екрана (високий, середній, низький або нульовий). Враховуються кількість символів і тип блокування. Додаток також може пропонувати вибрати складніший тип блокування екрана, але це не обов’язково робити. Примітка: оскільки пароль зашифровано, додаток його не знає."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"показувати сповіщення"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Дозволяє додатку показувати сповіщення"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"вмикати екран"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Дозволяє додатку вмикати екран."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"використовувати біометричне апаратне забезпечення"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Додаток може використовувати біометричне апаратне забезпечення для автентифікації"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"керувати сканером відбитків пальців"</string>
@@ -2077,10 +2079,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Докладніше"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивні сповіщення замінено на покращені. Ця функція допомагає впорядковувати сповіщення й показує в них пропоновані дії та відповіді.\n\nПокращені сповіщення надають доступ до вмісту сповіщень, зокрема до такої особистої інформації, як повідомлення й імена контактів. Ця функція може автоматично закривати сповіщення чи реагувати на них, наприклад відповідати на телефонні дзвінки або керувати режимом \"Не турбувати\"."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Сповіщення про послідовнсть дій"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Режим енергозбереження ввімкнено"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Заряд використовується економно, щоб подовжити час роботи акумулятора"</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>
@@ -2288,4 +2288,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не вдається отримати доступ до камери телефона з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не вдається отримати доступ до камери планшета з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="system_locale_title" msgid="711882686834677268">"Налаштування системи за умовчанням"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 221c5b0de7d2..90f8d600238f 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"اپپ کو اسکرین لاک کی پیچیدگی (بہت زیادہ، درمیانی، کم یا کوئی بھی نہیں) کو جاننے کی اجازت دیتی ہے، جو طوالت کی ممکنہ حد اور اسکرین لاک کی قسم کو بتاتی ہے۔ اپپ صارفین کو یہ مشوره بھی دے سکتی ہے کہ وہ اسکرین لاک کو مخصوص لیول تک اپ ڈیٹ کریں لیکن صارفین آزادانہ طور پر نظر انداز اور نیویگیٹ کر سکتے ہیں۔ نوٹ کریں کہ اسکرین لاک پلین ٹیکسٹ میں اسٹور نہیں کیا جاتا ہے اس لیے اپپ کو صحیح پاس ورڈ نہیں معلوم ہوتا ہے۔"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"اطلاعات دکھائیں"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"ایپ کو اطلاعات دکھانے کی اجازت دیتا ہے"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"سکرین آن کریں"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ایپ کو اسکرین آن کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"بایومیٹرک ہارڈ ویئر استعمال کریں"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"ایپ کو توثیق کے لیے بایومیٹرک ہارڈ ویئر استعمال کرنے کی اجازت دیتا ہے"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"فنگر پرنٹ ہارڈ ویئر کا نظم کریں"</string>
@@ -2075,10 +2077,8 @@
<string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزید جانیں"</string>
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏Android 12 میں بہتر کردہ اطلاعات کو Android اڈاپٹیو کی اطلاعات سے تبدیل کیا گیا۔ یہ خصوصیت تجویز کردہ کارروائیاں اور جوابات دکھاتی ہے اور آپ کی اطلاعات کا نظم کرتی ہے۔\n\nبہتر کردہ اطلاعات رابطوں کے نام اور پیغامات جیسی ذاتی معلومات سمیت اطلاعات کے مواد تک رسائی حاصل کر سکتی ہیں۔ یہ خصوصیت اطلاعات کو برخاست کر سکتی ہے یا ان کا جواب بھی دے سکتی ہے جیسے فون کالز کا جواب دینا اور ڈسٹرب نہ کریں کو کنٹرول کرنا۔"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"روٹین موڈ معلومات کی اطلاع"</string>
- <!-- no translation found for dynamic_mode_notification_title (1388718452788985481) -->
- <skip />
- <!-- no translation found for dynamic_mode_notification_summary (1639031262484979689) -->
- <skip />
+ <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"بیٹری سیور کو آن کیا گیا"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"بیٹری لائف کو بڑھانے کے لیے بیٹری کے استعمال کو کم کیا جا رہا ہے"</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>
@@ -2286,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے فون کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے ٹیبلیٹ کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string>
<string name="system_locale_title" msgid="711882686834677268">"سسٹم ڈیفالٹ"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 8cba718f2821..fc140bb9442c 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Ilova ekran qulfining qiyinlik darajasi (yuqori, oʻrta, past yoki hech qanday), jumladan, qulf turi va parol uzunligi haqida axborotga ruxsat oladi. Bundan tashqari, foydalanuvchilarga qulflash qiyinligi darajasini oshirish taklif etiladi. Bu tavsiyalar majburiy emas. Parollar ochiq matn sifatida saqlanmaydi va ilova uni ocha olmaydi."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"bildirishnomalarni chiqarish"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Ilovaga bildirishnomalarni chiqarish uchun ruxsat beradi"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"ekranni yoqish"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ilovaga ekranni yoqish ruxsatini beradi."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"biometrik sensordan foydalanish"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Haqiqiylikni tekshirish uchun biometrik sensordan foydalanish imkonini beradi"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"barmoq izi skanerini boshqarish"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan telefonning kamerasiga kirish imkonsiz"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan planshetning kamerasiga kirish imkonsiz"</string>
<string name="system_locale_title" msgid="711882686834677268">"Tizim standarti"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ce0b715d7c99..b658c9f14a01 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Cho phép ứng dụng nắm được độ phức tạp của khóa màn hình (cao, trung bình, thấp hoặc không có). Mức độ này cho biết độ dài và loại khóa màn hình có thể có. Ngoài ra, ứng dụng có thể gợi ý người dùng cập nhật khóa màn hình lên một mức độ nhất định, nhưng người dùng có thể tùy ý bỏ qua và chuyển sang phần khác. Lưu ý rằng khóa màn hình không được lưu dưới dạng văn bản thuần túy, vì vậy, ứng dụng sẽ không biết mật khẩu chính xác."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"hiển thị thông báo"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Cho phép ứng dụng hiển thị thông báo"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"bật màn hình"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Cho phép ứng dụng bật màn hình."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"sử dụng phần cứng sinh trắc học"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Cho phép ứng dụng dùng phần cứng sinh trắc học để xác thực"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"quản lý phần cứng vân tay"</string>
@@ -2076,7 +2078,7 @@
<string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Thông báo nâng cao đã thay thế Thông báo thích ứng trên Android trong Android 12. Tính năng này hiển thị những thao tác và câu trả lời đề xuất, đồng thời sắp xếp các thông báo của bạn.\n\nThông báo nâng cao có thể đọc mọi nội dung thông báo, bao gồm cả thông tin cá nhân như tên liên hệ và tin nhắn. Tính năng này cũng có thể đóng hoặc phản hồi các thông báo, chẳng hạn như trả lời cuộc gọi điện thoại, đồng thời có thể kiểm soát chế độ Không làm phiền."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Thông báo cung cấp thông tin về chế độ sạc thông thường"</string>
<string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Đã bật Trình tiết kiệm pin"</string>
- <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Giảm mức sử dụng pin để kéo dài tuổi thọ pin"</string>
+ <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Giảm mức sử dụng pin để kéo dài thời lượng pin"</string>
<string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Trình tiết kiệm pin"</string>
<string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Trình tiết kiệm pin đã tắt"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"Điện thoại còn đủ pin. Các tính năng không bị hạn chế nữa."</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Không truy cập được vào máy ảnh trên điện thoại từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Không truy cập được vào máy ảnh trên máy tính bảng từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
<string name="system_locale_title" msgid="711882686834677268">"Theo chế độ mặc định của hệ thống"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4257f7830cf3..129c5830d1ab 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"允许应用了解屏幕锁定复杂度(高、中、低或无),即屏幕锁定的可能长度范围和类型。应用还可以建议用户将屏幕锁定更新为特定复杂度,但用户可以随意选择忽略该建议并离开应用。请注意,系统不会以纯文字形式存储屏幕锁定选项的内容,因此应用不会知道确切密码。"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"显示通知"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"允许该应用显示通知"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"唤醒屏幕"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"允许应用唤醒屏幕。"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"使用生物特征硬件"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"允许该应用使用生物特征硬件进行身份验证"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"管理指纹硬件"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问手机的摄像头"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问平板电脑的摄像头"</string>
<string name="system_locale_title" msgid="711882686834677268">"系统默认设置"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 6374db52c8a3..ef886c9ab042 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"允許應用程式瞭解螢幕鎖定的複雜程度 (高、中、低或無),這項資料說明了螢幕鎖定的可能長度範圍和類型。應用程式亦能建議使用者將螢幕鎖定更新至某個複雜程度,但使用者可以隨意忽略並離開。請注意,螢幕鎖定並非以純文字儲存,因此應用程式不知道確切的密碼。"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"顯示通知"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"允許應用程式顯示通知"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"開啟螢幕"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"允許應用程式開啟螢幕。"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"使用生物識別硬件"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"允許應用程式使用生物識別硬件驗證"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"管理指紋硬件"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string>
<string name="system_locale_title" msgid="711882686834677268">"系統預設"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index aaa05f0091d1..9dbcd4459cf9 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"允許應用程式記住螢幕鎖定的複雜度 (高、中、低或無),即螢幕鎖定的可能長度範圍和類型。這樣一來,應用程式還能建議使用者將螢幕鎖定更新為特定複雜度,但使用者可選擇忽略建議並離開應用程式。請注意,系統不會以純文字格式儲存螢幕鎖定選項的內容,因此應用程式不會知道確切密碼。"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"顯示通知"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"允許應用程式顯示通知"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"開啟螢幕"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"允許應用程式開啟螢幕。"</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"使用生物特徵硬體"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"允許應用程式使用生物特徵硬體進行驗證"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"管理指紋硬體"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string>
<string name="system_locale_title" msgid="711882686834677268">"系統預設"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 20b8b58e95b6..6a4a4485cc6a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -553,6 +553,8 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Ivumela uhlelo lokusebenza ukuthi lifunde ileveli yobunkimbinkimbi bokukhiya isikrini (okuphezulu, okuphakathi nendawo, okuphansi noma lutho), obubonisa ibanga elingaba khona lobude nohlobo lokukhiya isikrini Uhlelo lokusebenza lungaphinda luphakamise kubasebenzisi ukuthi babuyekeze ukukhiya isikrini kuleveli elithile kodwa abasebenzisi bangaziba ngokukhululekile baphinde bazulazule nje. Qaphela ukuthi ukukhiya isikrini akugcinwa kumbhalo osobala ukuze uhlelo lokusebenza lungayazi iphasiwedi enembile."</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"bonisa izaziso"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Kuvumela i-app ibonise izaziso"</string>
+ <string name="permlab_turnScreenOn" msgid="219344053664171492">"vula isikrini"</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Ivumela i-app ukuthi ivule isikrini."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"sebenzisa izingxenyekazi zekhompyutha ze-biometric"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izingxenyekazi zekhompyutha ze-biometric ukuze kuqinisekiswe"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"phatha izingxenyekazi zekhompyutha zezigxivizo zeminwe"</string>
@@ -2284,4 +2286,6 @@
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ayikwazi ukufinyelela ikhamera yefoni kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
<string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ayikwazi ukufinyelela ikhamera yethebulethi kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
<string name="system_locale_title" msgid="711882686834677268">"Okuzenzakalelayo kwesistimu"</string>
+ <!-- no translation found for default_card_name (9198284935962911468) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2876161628c8..622414e3e381 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2308,8 +2308,10 @@
it should be disabled in that locale's resources. -->
<bool name="config_actionMenuItemAllCaps">true</bool>
- <!-- Remote server that can provide NTP responses. -->
- <string translatable="false" name="config_ntpServer">time.android.com</string>
+ <!-- Remote server that can provide NTP responses.
+ Values must be in the form: "ntp://<host>[:port]"
+ This is not a registered IANA URI scheme. -->
+ <string translatable="false" name="config_ntpServer">ntp://time.android.com</string>
<!-- Normal polling frequency in milliseconds -->
<integer name="config_ntpPollingInterval">64800000</integer>
<!-- Try-again polling interval in milliseconds, in case the network request failed -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index aef71e435bc6..e77a8327c4b8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6324,4 +6324,7 @@ ul.</string>
<!-- Title for preference of the system default locale. [CHAR LIMIT=50]-->
<string name="system_locale_title">System default</string>
+
+ <!-- Display content to tell the user the sim card name and number-->
+ <string name="default_card_name">CARD <xliff:g id="cardNumber" example="1">%d</xliff:g></string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b7c3839318f8..872da620e649 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4814,4 +4814,5 @@
<java-symbol type="dimen" name="status_bar_height_default" />
<java-symbol type="bool" name="system_server_plays_face_haptics" />
+ <java-symbol type="string" name="default_card_name"/>
</resources>
diff --git a/core/tests/coretests/src/android/text/TextLineTest.java b/core/tests/coretests/src/android/text/TextLineTest.java
index 412d6ec975ac..e3bcc8d2c200 100644
--- a/core/tests/coretests/src/android/text/TextLineTest.java
+++ b/core/tests/coretests/src/android/text/TextLineTest.java
@@ -26,6 +26,7 @@ import android.graphics.Paint;
import android.graphics.Typeface;
import android.platform.test.annotations.Presubmit;
import android.text.Layout.TabStops;
+import android.text.style.AbsoluteSizeSpan;
import android.text.style.ReplacementSpan;
import android.text.style.TabStopSpan;
@@ -97,7 +98,7 @@ public class TextLineTest {
InstrumentationRegistry.getInstrumentation().getTargetContext().getAssets(),
"fonts/StaticLayoutLineBreakingTestFont.ttf");
- private TextLine getTextLine(String str, TextPaint paint, TabStops tabStops) {
+ private TextLine getTextLine(CharSequence str, TextPaint paint, TabStops tabStops) {
Layout layout =
StaticLayout.Builder.obtain(str, 0, str.length(), paint, Integer.MAX_VALUE)
.build();
@@ -109,7 +110,7 @@ public class TextLineTest {
return tl;
}
- private TextLine getTextLine(String str, TextPaint paint) {
+ private TextLine getTextLine(CharSequence str, TextPaint paint) {
return getTextLine(str, paint, null);
}
@@ -316,14 +317,275 @@ public class TextLineTest {
assertTrue(span.mIsUsed);
}
+ @Test
+ public void testMeasureAllBounds_LTR() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("IIIIIV", paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 20.0f, 30.0f, 30.0f, 40.0f,
+ 40.0f, 50.0f, 50.0f, 100.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_LTR_StyledText() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+ SpannableString text = new SpannableString("IIIIIV");
+ text.setSpan(new AbsoluteSizeSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextLine tl = getTextLine(text, paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 15.0f, 20.0f, 20.0f, 30.0f,
+ 30.0f, 40.0f, 40.0f, 90.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 5.0f, 5.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_RTL() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("\u05D0\u05D0\u05D0\u05D0\u05D0\u05D1", paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {-10.0f, 0.0f, -20.0f, -10.0f, -30.0f, -20.0f, -40.0f, -30.0f,
+ -50.0f, -40.0f, -100.0f, -50.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+ }
+
+
+ @Test
+ public void testMeasureAllBounds_RTL_StyledText() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+ SpannableString text = new SpannableString("\u05D0\u05D0\u05D0\u05D0\u05D0\u05D1");
+ text.setSpan(new AbsoluteSizeSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextLine tl = getTextLine(text, paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {-10.0f, 0.0f, -15.0f, -10.0f, -20.0f, -15.0f,
+ -30.0f, -20.0f, -40.0f, -30.0f, -90.0f, -40.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 5.0f, 5.0f, 10.0f, 10.0f, 50.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_BiDi() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("II\u05D0\u05D0II", paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 30.0f, 40.0f, 20.0f, 30.0f,
+ 40.0f, 50.0f, 50.0f, 60.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_BiDi2() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("I" + RLI + "I\u05D0\u05D0" + PDI + "I", paint);
+ float[] bounds = new float[14];
+ float[] advances = new float[7];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 10.0f, 30.0f, 40.0f, 20.0f, 30.0f,
+ 10.0f, 20.0f, 40.0f, 40.0f, 40.0f, 50.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 0.0f, 10.0f, 10.0f, 10.0f, 0.0f, 10.0f}, advances,
+ 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_BiDi3() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("\u05D0" + LRI + "\u05D0II" + PDI + "\u05D0", paint);
+ float[] bounds = new float[14];
+ float[] advances = new float[7];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {-10.0f, 0.0f, -10.0f, -10.0f, -40.0f, -30.0f,
+ -30.0f, -20.0f, -20.0f, -10.0f, -40.0f, -40.0f, -50.0f, -40.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 0.0f, 10.0f, 10.0f, 10.0f, 0.0f, 10.0f}, advances,
+ 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_styled_BiDi() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ SpannableString text = new SpannableString("II\u05D0\u05D0II");
+ text.setSpan(new AbsoluteSizeSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextLine tl = getTextLine(text, paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 25.0f, 30.0f,
+ 15.0f, 25.0f, 30.0f, 40.0f, 40.0f, 50.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 5.0f, 5.0f, 10.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_Tab_LTR() {
+ final Object[] spans = { new TabStopSpan.Standard(100) };
+ final TabStops stops = new TabStops(100, spans);
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("II\tII", paint, stops);
+ float[] bounds = new float[10];
+ float[] advances = new float[5];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 20.0f, 100.0f, 100.0f, 110.0f,
+ 110.0f, 120.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_Tab_RTL() {
+ final Object[] spans = { new TabStopSpan.Standard(100) };
+ final TabStops stops = new TabStops(100, spans);
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("\u05D0\u05D0\t\u05D0\u05D0", paint, stops);
+ float[] bounds = new float[10];
+ float[] advances = new float[5];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {-10.0f, 0.0f, -20.0f, -10.0f, -100.0f, -20.0f,
+ -110.0f, -100.0f, -120.0f, -110.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_Tab_BiDi() {
+ final Object[] spans = { new TabStopSpan.Standard(100) };
+ final TabStops stops = new TabStops(100, spans);
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("I\u05D0\tI\u05D0", paint, stops);
+ float[] bounds = new float[10];
+ float[] advances = new float[5];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 20.0f, 20.0f, 100.0f,
+ 100.0f, 110.0f, 110.0f, 120.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_Tab_BiDi2() {
+ final Object[] spans = { new TabStopSpan.Standard(100) };
+ final TabStops stops = new TabStops(100, spans);
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ TextLine tl = getTextLine("\u05D0I\t\u05D0I", paint, stops);
+ float[] bounds = new float[10];
+ float[] advances = new float[5];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {-10.0f, 0.0f, -20.0f, -10.0f, -100.0f, -20.0f,
+ -110.0f, -100.0f, -120.0f, -110.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 10.0f, 80.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_replacement_LTR() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ SpannableString text = new SpannableString("IIIII");
+ text.setSpan(new TestReplacementSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextLine tl = getTextLine(text, paint);
+ float[] bounds = new float[10];
+ float[] advances = new float[5];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 15.0f, 15.0f,
+ 15.0f, 25.0f, 25.0f, 35.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 5.0f, 0.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_replacement_RTL() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ SpannableString text = new SpannableString("\u05D0\u05D0\u05D0\u05D0\u05D0");
+ text.setSpan(new TestReplacementSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextLine tl = getTextLine(text, paint);
+ float[] bounds = new float[10];
+ float[] advances = new float[5];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {-10.0f, 0.0f, -15.0f, -10.0f, -15.0f, -15.0f,
+ -25.0f, -15.0f, -35.0f, -25.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 5.0f, 0.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
+ @Test
+ public void testMeasureAllBounds_replacement_BiDi() {
+ final TextPaint paint = new TextPaint();
+ paint.setTypeface(TYPEFACE);
+ paint.setTextSize(10.0f); // make 1em = 10px
+
+ SpannableString text = new SpannableString("II\u05D0\u05D0II");
+ text.setSpan(new TestReplacementSpan(5), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextLine tl = getTextLine(text, paint);
+ float[] bounds = new float[12];
+ float[] advances = new float[6];
+ tl.measureAllBounds(bounds, advances);
+ assertArrayEquals(new float[] {0.0f, 10.0f, 10.0f, 15.0f, 15.0f, 15.0f,
+ 15.0f, 25.0f, 25.0f, 35.0f, 35.0f, 45.0f}, bounds, 0.0f);
+ assertArrayEquals(new float[] {10.0f, 5.0f, 0.0f, 10.0f, 10.0f, 10.0f}, advances, 0.0f);
+ }
+
private static class TestReplacementSpan extends ReplacementSpan {
boolean mIsUsed;
+ private final int mWidth;
+
+ TestReplacementSpan() {
+ mWidth = 0;
+ }
+
+ TestReplacementSpan(int width) {
+ mWidth = width;
+ }
@Override
public int getSize(Paint paint, CharSequence text, int start, int end,
Paint.FontMetricsInt fm) {
mIsUsed = true;
- return 0;
+ return mWidth;
}
@Override
diff --git a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
new file mode 100644
index 000000000000..67a4f44a9863
--- /dev/null
+++ b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.net.Network;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NtpTrustedTimeTest {
+
+ // Valid absolute URIs, but not ones that will be accepted as NTP server URIs.
+ private static final List<String> BAD_ABSOLUTE_NTP_URIS = Arrays.asList(
+ "ntp://:123/",
+ "ntp://:123",
+ "ntp://:/",
+ "ntp://:",
+ "ntp://foobar:abc/",
+ "ntp://foobar:abc",
+ "ntp://foobar:456:789/",
+ "ntp://foobar:456:789",
+ "ntp://foobar:456:abc/",
+ "ntp://foobar:456:abc"
+ );
+
+ // Valid relative URIs, but not ones that will be accepted as NTP server URIs.
+ private static final List<String> BAD_RELATIVE_NTP_URIS = Arrays.asList(
+ "foobar",
+ "/foobar",
+ "foobar:456"
+ );
+
+ // Valid NTP server URIs: input value -> expected URI.toString() value.
+ private static final Map<String, String> GOOD_NTP_URIS = Map.of(
+ "ntp://foobar", "ntp://foobar",
+ "ntp://foobar/", "ntp://foobar/",
+ "ntp://foobar:456/", "ntp://foobar:456/",
+ "ntp://foobar:456", "ntp://foobar:456"
+ );
+
+ private static final URI VALID_SERVER_URI = URI.create("ntp://foobar/");
+
+ @Test
+ public void testParseNtpServerSetting() {
+ assertEquals(URI.create("ntp://foobar"), NtpTrustedTime.parseNtpServerSetting("foobar"));
+
+ // Legacy settings values which could easily be confused with relative URIs. Parsing of this
+ // legacy form doesn't have to be robust / treated as errors: Android has never supported
+ // string like these, and so they won't work properly.
+ assertNull(NtpTrustedTime.parseNtpServerSetting("foobar:123"));
+ assertNull(NtpTrustedTime.parseNtpServerSetting("/foobar"));
+
+ // NTP URI cases that must not be accepted.
+ for (String badNtpUri : BAD_ABSOLUTE_NTP_URIS) {
+ assertNull("Input: \"" + badNtpUri + "\"",
+ NtpTrustedTime.parseNtpServerSetting(badNtpUri));
+ }
+
+ // Valid URIs
+ for (Map.Entry<String, String> goodNtpUri : GOOD_NTP_URIS.entrySet()) {
+ URI uri = NtpTrustedTime.parseNtpServerSetting(goodNtpUri.getKey());
+ assertNotNull(goodNtpUri.getKey(), uri);
+ assertEquals(goodNtpUri.getValue(), uri.toString());
+ }
+ }
+
+ @Test
+ public void testParseNtpUriStrict() throws Exception {
+ // ntp: URI cases that must not be accepted.
+ for (String badNtpUri : BAD_ABSOLUTE_NTP_URIS) {
+ assertParseNtpUriStrictThrows(badNtpUri);
+ }
+
+ for (String badNtpUri : BAD_RELATIVE_NTP_URIS) {
+ assertParseNtpUriStrictThrows(badNtpUri);
+ }
+
+ // Bad scheme.
+ assertParseNtpUriStrictThrows("notntp://foobar:123");
+
+ // Valid NTP URIs
+ for (Map.Entry<String, String> goodNtpUri : GOOD_NTP_URIS.entrySet()) {
+ URI uri = NtpTrustedTime.parseNtpUriStrict(goodNtpUri.getKey());
+ assertNotNull(goodNtpUri.getKey(), uri);
+ assertEquals(goodNtpUri.getValue(), uri.toString());
+ }
+ }
+
+ private void assertParseNtpUriStrictThrows(String badNtpUri) throws Exception {
+ assertThrows("Input: \"" + badNtpUri, URISyntaxException.class,
+ () -> NtpTrustedTime.parseNtpUriStrict(badNtpUri));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNtpConfig_nullConstructorServerInfo() {
+ new NtpTrustedTime.NtpConfig(null, Duration.ofSeconds(5));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNtpConfig_nullConstructorTimeout() {
+ new NtpTrustedTime.NtpConfig(VALID_SERVER_URI, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNtpConfig_zeroTimeout() {
+ new NtpTrustedTime.NtpConfig(VALID_SERVER_URI, Duration.ofMillis(0));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNtpConfig_negativeTimeout() {
+ new NtpTrustedTime.NtpConfig(VALID_SERVER_URI, Duration.ofMillis(-1));
+ }
+
+ @Test
+ public void testForceRefresh_nullConfig() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(null);
+
+ assertFalse(ntpTrustedTime.forceRefresh());
+
+ assertFalse(ntpTrustedTime.hasCache());
+ assertEquals(0, ntpTrustedTime.getCachedNtpTime());
+ assertEquals(0, ntpTrustedTime.getCachedNtpTimeReference());
+ assertEquals(Long.MAX_VALUE, ntpTrustedTime.getCacheAge());
+ assertNull(ntpTrustedTime.getCachedTimeResult());
+
+ verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+ verify(ntpTrustedTime, never()).getNetwork();
+ verify(ntpTrustedTime, never()).queryNtpServer(any(), any(), any());
+ }
+
+ @Test
+ public void testForceRefresh_noConnectivity() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+ URI serverUri = URI.create("ntp://ntpserver.name");
+ Duration timeout = Duration.ofSeconds(5);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+ new NtpTrustedTime.NtpConfig(serverUri, timeout));
+
+ when(ntpTrustedTime.getNetwork()).thenReturn(null);
+
+ assertFalse(ntpTrustedTime.forceRefresh());
+
+ assertFalse(ntpTrustedTime.hasCache());
+ assertEquals(0, ntpTrustedTime.getCachedNtpTime());
+ assertEquals(0, ntpTrustedTime.getCachedNtpTimeReference());
+ assertEquals(Long.MAX_VALUE, ntpTrustedTime.getCacheAge());
+ assertNull(ntpTrustedTime.getCachedTimeResult());
+
+ verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+ verify(ntpTrustedTime, times(1)).getNetwork();
+ verify(ntpTrustedTime, never()).queryNtpServer(any(), any(), any());
+ }
+
+ @Test
+ public void testForceRefresh_queryFailed() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+ URI serverUri = URI.create("ntp://ntpserver.name");
+ Duration timeout = Duration.ofSeconds(5);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+ new NtpTrustedTime.NtpConfig(serverUri, timeout));
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.getNetwork()).thenReturn(network);
+
+ when(ntpTrustedTime.queryNtpServer(network, serverUri, timeout)).thenReturn(null);
+
+ assertFalse(ntpTrustedTime.forceRefresh());
+
+ assertFalse(ntpTrustedTime.hasCache());
+ assertEquals(0, ntpTrustedTime.getCachedNtpTime());
+ assertEquals(0, ntpTrustedTime.getCachedNtpTimeReference());
+ assertEquals(Long.MAX_VALUE, ntpTrustedTime.getCacheAge());
+ assertNull(ntpTrustedTime.getCachedTimeResult());
+
+ verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+ verify(ntpTrustedTime, times(1)).getNetwork();
+ verify(ntpTrustedTime, times(1)).queryNtpServer(network, serverUri, timeout);
+ }
+
+ @Test
+ public void testForceRefresh_querySucceeded() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+ URI serverUri = URI.create("ntp://ntpserver.name");
+ Duration timeout = Duration.ofSeconds(5);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+ new NtpTrustedTime.NtpConfig(serverUri, timeout));
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.getNetwork()).thenReturn(network);
+
+ NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+ InetSocketAddress.createUnresolved("placeholder", 123));
+ when(ntpTrustedTime.queryNtpServer(network, serverUri, timeout)).thenReturn(successResult);
+
+ assertTrue(ntpTrustedTime.forceRefresh());
+
+ assertTrue(ntpTrustedTime.hasCache());
+ assertEquals(successResult.getTimeMillis(), ntpTrustedTime.getCachedNtpTime());
+ assertEquals(successResult.getElapsedRealtimeMillis(),
+ ntpTrustedTime.getCachedNtpTimeReference());
+ assertTrue(ntpTrustedTime.getCacheAge() != Long.MAX_VALUE);
+ assertEquals(successResult, ntpTrustedTime.getCachedTimeResult());
+
+ verify(ntpTrustedTime, times(1)).getNtpConfigInternal();
+ verify(ntpTrustedTime, times(1)).getNetwork();
+ verify(ntpTrustedTime, times(1)).queryNtpServer(network, serverUri, timeout);
+ }
+
+ @Test
+ public void testForceRefresh_keepsOldValueOnFailure() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+ URI serverUri = URI.create("ntp://ntpserver.name");
+ Duration timeout = Duration.ofSeconds(5);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+ new NtpTrustedTime.NtpConfig(serverUri, timeout));
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.getNetwork()).thenReturn(network);
+
+ NtpTrustedTime.TimeResult successResult = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+ InetSocketAddress.createUnresolved("placeholder", 123));
+ when(ntpTrustedTime.queryNtpServer(network, serverUri, timeout)).thenReturn(successResult);
+
+ assertTrue(ntpTrustedTime.forceRefresh());
+
+ assertTrue(ntpTrustedTime.hasCache());
+ assertEquals(successResult, ntpTrustedTime.getCachedTimeResult());
+
+ when(ntpTrustedTime.queryNtpServer(network, serverUri, timeout)).thenReturn(null);
+
+ assertFalse(ntpTrustedTime.forceRefresh());
+
+ assertTrue(ntpTrustedTime.hasCache());
+ assertEquals(successResult, ntpTrustedTime.getCachedTimeResult());
+ }
+
+ @Test
+ public void testForceRefresh_keepsNewValueOnSuccess() {
+ NtpTrustedTime ntpTrustedTime = spy(NtpTrustedTime.class);
+ URI serverUri = URI.create("ntp://ntpserver.name");
+ Duration timeout = Duration.ofSeconds(5);
+ when(ntpTrustedTime.getNtpConfigInternal()).thenReturn(
+ new NtpTrustedTime.NtpConfig(serverUri, timeout));
+
+ Network network = mock(Network.class);
+ when(ntpTrustedTime.getNetwork()).thenReturn(network);
+
+ NtpTrustedTime.TimeResult successResult1 = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+ InetSocketAddress.createUnresolved("placeholder", 123));
+ when(ntpTrustedTime.queryNtpServer(network, serverUri, timeout)).thenReturn(successResult1);
+
+ assertTrue(ntpTrustedTime.forceRefresh());
+
+ assertTrue(ntpTrustedTime.hasCache());
+ assertEquals(successResult1, ntpTrustedTime.getCachedTimeResult());
+
+ NtpTrustedTime.TimeResult successResult2 = new NtpTrustedTime.TimeResult(123L, 456L, 789,
+ InetSocketAddress.createUnresolved("placeholder", 123));
+ when(ntpTrustedTime.queryNtpServer(network, serverUri, timeout)).thenReturn(successResult2);
+
+ assertTrue(ntpTrustedTime.forceRefresh());
+
+ assertTrue(ntpTrustedTime.hasCache());
+ assertEquals(successResult2, ntpTrustedTime.getCachedTimeResult());
+ }
+}
diff --git a/core/tests/coretests/src/android/util/OWNERS b/core/tests/coretests/src/android/util/OWNERS
new file mode 100644
index 000000000000..460e8c073782
--- /dev/null
+++ b/core/tests/coretests/src/android/util/OWNERS
@@ -0,0 +1,2 @@
+per-file NtpTrustedTimeTest.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
+per-file TypedValueTest.kt = file:/core/java/android/content/res/OWNERS
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
new file mode 100644
index 000000000000..a6abee5f7550
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+import android.view.WindowManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Class for testing {@link AccessibilityWindowAttributes}.
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityWindowAttributesTest {
+ private static final String TEST_WINDOW_TITLE = "test window title";
+
+ @SmallTest
+ @Test
+ public void testParceling() {
+ final AccessibilityWindowAttributes windowAttributes = createInstance(TEST_WINDOW_TITLE);
+ Parcel parcel = Parcel.obtain();
+ windowAttributes.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ final AccessibilityWindowAttributes attributes2 =
+ AccessibilityWindowAttributes.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+
+ assertNotSame(windowAttributes, attributes2);
+ assertEquals(windowAttributes, attributes2);
+ }
+
+ @SmallTest
+ @Test
+ public void testNonequality() {
+ final AccessibilityWindowAttributes windowAttributes = createInstance(null);
+ final AccessibilityWindowAttributes windowAttributes2 = createInstance(TEST_WINDOW_TITLE);
+ assertNotEquals(windowAttributes, windowAttributes2);
+ }
+
+ private static AccessibilityWindowAttributes createInstance(String windowTitle) {
+ final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+ layoutParams.accessibilityTitle = windowTitle;
+ return new AccessibilityWindowAttributes(layoutParams);
+ }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 47ce2d87e69f..cc4fbab1f190 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -304,6 +304,23 @@ public class TextViewTest {
assertFalse(mTextView.isCursorVisible());
}
+ @Test(expected = NullPointerException.class)
+ @UiThreadTest
+ public void setTextCharArrayNullThrows() {
+ mTextView = new TextView(mActivity);
+ mTextView.setText((char[]) null, 0, 0);
+ }
+
+ @Test
+ @UiThreadTest
+ public void setTextCharArrayValidAfterSetTextString() {
+ mTextView = new TextView(mActivity);
+ mTextView.setText(new char[] { 'h', 'i'}, 0, 2);
+ CharSequence charWrapper = mTextView.getText();
+ mTextView.setText("null out char wrapper");
+ assertEquals("hi", charWrapper.toString());
+ }
+
private String createLongText() {
int size = 600 * 1000;
final StringBuilder builder = new StringBuilder(size);
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 09fc7ea6fffd..e068730e9bda 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -83,6 +84,7 @@ public class FrameTrackerTest {
private StatsLogWrapper mStatsLog;
private ArgumentCaptor<OnJankDataListener> mListenerCapture;
private SurfaceControl mSurfaceControl;
+ private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
@Before
public void setup() {
@@ -99,6 +101,8 @@ public class FrameTrackerTest {
mSurfaceControl = new SurfaceControl.Builder().setName("Surface").build();
mViewRootWrapper = mock(ViewRootWrapper.class);
when(mViewRootWrapper.getSurfaceControl()).thenReturn(mSurfaceControl);
+ doNothing().when(mViewRootWrapper).addSurfaceChangedCallback(any());
+ doNothing().when(mViewRootWrapper).removeSurfaceChangedCallback(any());
mSurfaceControlWrapper = mock(SurfaceControlWrapper.class);
mListenerCapture = ArgumentCaptor.forClass(OnJankDataListener.class);
@@ -109,23 +113,29 @@ public class FrameTrackerTest {
mChoreographer = mock(ChoreographerWrapper.class);
mStatsLog = mock(StatsLogWrapper.class);
+ mRunnableArgumentCaptor = ArgumentCaptor.forClass(Runnable.class);
}
private FrameTracker spyFrameTracker(int cuj, String postfix, boolean surfaceOnly) {
+ InteractionJankMonitor monitor = mock(InteractionJankMonitor.class);
Handler handler = mRule.getActivity().getMainThreadHandler();
Session session = new Session(cuj, postfix);
Configuration config = mock(Configuration.class);
when(config.isSurfaceOnly()).thenReturn(surfaceOnly);
when(config.getSurfaceControl()).thenReturn(mSurfaceControl);
when(config.shouldDeferMonitor()).thenReturn(true);
+ View view = mRule.getActivity().getWindow().getDecorView();
+ Handler spyHandler = spy(new Handler(handler.getLooper()));
+ when(config.getView()).thenReturn(surfaceOnly ? null : view);
+ when(config.getHandler()).thenReturn(spyHandler);
FrameTracker frameTracker = Mockito.spy(
- new FrameTracker(session, handler, mRenderer, mViewRootWrapper,
+ new FrameTracker(monitor, session, spyHandler, mRenderer, mViewRootWrapper,
mSurfaceControlWrapper, mChoreographer, mWrapper, mStatsLog,
/* traceThresholdMissedFrames= */ 1,
/* traceThresholdFrameTimeMillis= */ -1,
/* FrameTrackerListener= */ null, config));
doNothing().when(frameTracker).triggerPerfetto();
- doNothing().when(frameTracker).postTraceStartMarker();
+ doNothing().when(frameTracker).postTraceStartMarker(mRunnableArgumentCaptor.capture());
return frameTracker;
}
@@ -140,6 +150,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// send first frame with a long duration - should not be taken into account
@@ -173,6 +184,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// send first frame - not janky
@@ -208,6 +220,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// send first frame - janky
@@ -243,6 +256,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// send first frame - not janky
@@ -278,6 +292,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// send first frame - not janky
@@ -319,6 +334,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// send first frame - not janky
@@ -332,7 +348,7 @@ public class FrameTrackerTest {
tracker.end(FrameTracker.REASON_END_NORMAL);
// Send incomplete callback for 102L
- sendSfFrame(102L, JANK_NONE);
+ sendSfFrame(tracker, 102L, JANK_NONE);
// Send janky but complete callbck fo 103L
sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L);
@@ -356,6 +372,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer).addObserver(any());
// First frame - not janky
@@ -380,6 +397,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// end the trace session
@@ -403,6 +421,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mRenderer, only()).addObserver(any());
// end the trace session at the same vsync id, end vsync id will less than the begin one.
@@ -444,6 +463,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
// First frame - not janky
@@ -479,6 +499,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
// First frame - janky
@@ -514,6 +535,7 @@ public class FrameTrackerTest {
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
// First frame - not janky
@@ -548,6 +570,7 @@ public class FrameTrackerTest {
CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
when(mChoreographer.getVsyncId()).thenReturn(100L);
tracker.begin();
+ mRunnableArgumentCaptor.getValue().run();
verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 100L);
sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
@@ -594,7 +617,7 @@ public class FrameTrackerTest {
if (!tracker.mSurfaceOnly) {
sendHwuiFrame(tracker, durationMillis, vsyncId, firstWindowFrame);
}
- sendSfFrame(vsyncId, jankType);
+ sendSfFrame(tracker, vsyncId, jankType);
}
private void sendHwuiFrame(FrameTracker tracker, long durationMillis, long vsyncId,
@@ -604,12 +627,18 @@ public class FrameTrackerTest {
.getMetric(FrameMetrics.FIRST_DRAW_FRAME);
doReturn(TimeUnit.MILLISECONDS.toNanos(durationMillis))
.when(mWrapper).getMetric(FrameMetrics.TOTAL_DURATION);
+ final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
+ doNothing().when(tracker).postCallback(captor.capture());
tracker.onFrameMetricsAvailable(0);
+ captor.getValue().run();
}
- private void sendSfFrame(long vsyncId, @JankType int jankType) {
+ private void sendSfFrame(FrameTracker tracker, long vsyncId, @JankType int jankType) {
+ final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
+ doNothing().when(tracker).postCallback(captor.capture());
mListenerCapture.getValue().onJankDataAvailable(new JankData[] {
new JankData(vsyncId, jankType)
});
+ captor.getValue().run();
}
}
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index 5a6fd5317bbc..d96f041c13f8 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -93,7 +93,7 @@ public class InteractionJankMonitorTest {
@Test
public void testBeginEnd() {
InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
- FrameTracker tracker = createMockedFrameTracker(null);
+ FrameTracker tracker = createMockedFrameTracker(monitor, null);
doReturn(tracker).when(monitor).createFrameTracker(any(), any());
doNothing().when(tracker).begin();
doReturn(true).when(tracker).end(anyInt());
@@ -134,7 +134,7 @@ public class InteractionJankMonitorTest {
public void testBeginTimeout() {
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
- FrameTracker tracker = createMockedFrameTracker(null);
+ FrameTracker tracker = createMockedFrameTracker(monitor, null);
doReturn(tracker).when(monitor).createFrameTracker(any(), any());
doNothing().when(tracker).begin();
doReturn(true).when(tracker).cancel(anyInt());
@@ -180,7 +180,8 @@ public class InteractionJankMonitorTest {
return monitor;
}
- private FrameTracker createMockedFrameTracker(FrameTracker.FrameTrackerListener listener) {
+ private FrameTracker createMockedFrameTracker(InteractionJankMonitor monitor,
+ FrameTracker.FrameTrackerListener listener) {
Session session = spy(new Session(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX));
doReturn(false).when(session).logToStatsd();
@@ -190,6 +191,7 @@ public class InteractionJankMonitorTest {
ViewRootWrapper viewRoot = spy(new ViewRootWrapper(mView.getViewRootImpl()));
doNothing().when(viewRoot).addSurfaceChangedCallback(any());
+ doNothing().when(viewRoot).removeSurfaceChangedCallback(any());
SurfaceControlWrapper surfaceControl = mock(SurfaceControlWrapper.class);
doNothing().when(surfaceControl).addJankStatsListener(any(), any());
@@ -200,15 +202,18 @@ public class InteractionJankMonitorTest {
Configuration configuration = mock(Configuration.class);
when(configuration.isSurfaceOnly()).thenReturn(false);
+ when(configuration.getView()).thenReturn(mView);
+ when(configuration.getHandler()).thenReturn(mView.getHandler());
- FrameTracker tracker = spy(new FrameTracker(session, mWorker.getThreadHandler(),
+ FrameTracker tracker = spy(new FrameTracker(monitor, session, mWorker.getThreadHandler(),
threadedRenderer, viewRoot, surfaceControl, choreographer,
new FrameMetricsWrapper(), new StatsLogWrapper(),
/* traceThresholdMissedFrames= */ 1,
/* traceThresholdFrameTimeMillis= */ -1, listener, configuration));
- doNothing().when(tracker).postTraceStartMarker();
+ doNothing().when(tracker).postTraceStartMarker(any());
doNothing().when(tracker).triggerPerfetto();
+ doReturn(configuration.getHandler()).when(tracker).getHandler();
return tracker;
}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 2ce8fac6d520..d52c70becf75 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -577,12 +577,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1521427940": {
- "message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
- "level": "VERBOSE",
- "group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"-1517908912": {
"message": "requestScrollCapture: caught exception dispatching to window.token=%s",
"level": "WARN",
@@ -1519,6 +1513,12 @@
"group": "WM_DEBUG_FOCUS_LIGHT",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-636553602": {
+ "message": "commitVisibility: %s: visible=%b visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-635082269": {
"message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b",
"level": "INFO",
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 451b99ea7550..1a80ab308bb5 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -3136,6 +3136,128 @@ public class Paint {
return result;
}
+
+ /**
+ * Measure the advance of each character within a run of text and also return the cursor
+ * position within the run.
+ *
+ * @see #getRunAdvance(char[], int, int, int, int, boolean, int) for more details.
+ *
+ * @param text the text to measure. Cannot be null.
+ * @param start the index of the start of the range to measure
+ * @param end the index + 1 of the end of the range to measure
+ * @param contextStart the index of the start of the shaping context
+ * @param contextEnd the index + 1 of the end of the shaping context
+ * @param isRtl whether the run is in RTL direction
+ * @param offset index of caret position
+ * @param advances the array that receives the computed character advances
+ * @param advancesIndex the start index from which the advances array is filled
+ * @return width measurement between start and offset
+ * @throws IndexOutOfBoundsException if a) contextStart or contextEnd is out of array's range
+ * or contextStart is larger than contextEnd,
+ * b) start or end is not within the range [contextStart, contextEnd), or start is larger than
+ * end,
+ * c) offset is not within the range [start, end),
+ * d) advances.length - advanceIndex is smaller than the length of the run, which equals to
+ * end - start.
+ *
+ */
+ public float getRunCharacterAdvance(@NonNull char[] text, int start, int end, int contextStart,
+ int contextEnd, boolean isRtl, int offset,
+ @Nullable float[] advances, int advancesIndex) {
+ if (text == null) {
+ throw new IllegalArgumentException("text cannot be null");
+ }
+ if (contextStart < 0 || contextEnd > text.length) {
+ throw new IndexOutOfBoundsException("Invalid Context Range: " + contextStart + ", "
+ + contextEnd + " must be in 0, " + text.length);
+ }
+
+ if (start < contextStart || contextEnd < end) {
+ throw new IndexOutOfBoundsException("Invalid start/end range: " + start + ", " + end
+ + " must be in " + contextStart + ", " + contextEnd);
+ }
+
+ if (offset < start || end < offset) {
+ throw new IndexOutOfBoundsException("Invalid offset position: " + offset
+ + " must be in " + start + ", " + end);
+ }
+
+ if (advances != null && advances.length < advancesIndex - start + end) {
+ throw new IndexOutOfBoundsException("Given array doesn't have enough space to receive "
+ + "the result, advances.length: " + advances.length + " advanceIndex: "
+ + advancesIndex + " needed space: " + (offset - start));
+ }
+
+ if (end == start) {
+ return 0.0f;
+ }
+
+ return nGetRunCharacterAdvance(mNativePaint, text, start, end, contextStart, contextEnd,
+ isRtl, offset, advances, advancesIndex);
+ }
+
+ /**
+ * @see #getRunCharacterAdvance(char[], int, int, int, int, boolean, int, float[], int)
+ *
+ * @param text the text to measure. Cannot be null.
+ * @param start the index of the start of the range to measure
+ * @param end the index + 1 of the end of the range to measure
+ * @param contextStart the index of the start of the shaping context
+ * @param contextEnd the index + 1 of the end of the shaping context
+ * @param isRtl whether the run is in RTL direction
+ * @param offset index of caret position
+ * @param advances the array that receives the computed character advances
+ * @param advancesIndex the start index from which the advances array is filled
+ * @return width measurement between start and offset
+ * @throws IndexOutOfBoundsException if a) contextStart or contextEnd is out of array's range
+ * or contextStart is larger than contextEnd,
+ * b) start or end is not within the range [contextStart, contextEnd), or end is larger than
+ * start,
+ * c) offset is not within the range [start, end),
+ * d) advances.length - advanceIndex is smaller than the run length, which equals to
+ * end - start.
+ */
+ public float getRunCharacterAdvance(@NonNull CharSequence text, int start, int end,
+ int contextStart, int contextEnd, boolean isRtl, int offset,
+ @Nullable float[] advances, int advancesIndex) {
+ if (text == null) {
+ throw new IllegalArgumentException("text cannot be null");
+ }
+ if (contextStart < 0 || contextEnd > text.length()) {
+ throw new IndexOutOfBoundsException("Invalid Context Range: " + contextStart + ", "
+ + contextEnd + " must be in 0, " + text.length());
+ }
+
+ if (start < contextStart || contextEnd < end) {
+ throw new IndexOutOfBoundsException("Invalid start/end range: " + start + ", " + end
+ + " must be in " + contextStart + ", " + contextEnd);
+ }
+
+ if (offset < start || end < offset) {
+ throw new IndexOutOfBoundsException("Invalid offset position: " + offset
+ + " must be in " + start + ", " + end);
+ }
+
+ if (advances != null && advances.length < advancesIndex - start + end) {
+ throw new IndexOutOfBoundsException("Given array doesn't have enough space to receive "
+ + "the result, advances.length: " + advances.length + " advanceIndex: "
+ + advancesIndex + " needed space: " + (offset - start));
+ }
+
+ if (end == start) {
+ return 0.0f;
+ }
+
+ char[] buf = TemporaryBuffer.obtain(contextEnd - contextStart);
+ TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
+ final float result = getRunCharacterAdvance(buf, start - contextStart, end - contextStart,
+ 0, contextEnd - contextStart, isRtl, offset - contextStart,
+ advances, advancesIndex);
+ TemporaryBuffer.recycle(buf);
+ return result;
+ }
+
/**
* Get the character offset within the string whose position is closest to the specified
* horizontal position.
@@ -3247,6 +3369,9 @@ public class Paint {
private static native boolean nHasGlyph(long paintPtr, int bidiFlags, String string);
private static native float nGetRunAdvance(long paintPtr, char[] text, int start, int end,
int contextStart, int contextEnd, boolean isRtl, int offset);
+ private static native float nGetRunCharacterAdvance(long paintPtr, char[] text, int start,
+ int end, int contextStart, int contextEnd, boolean isRtl, int offset, float[] advances,
+ int advancesIndex);
private static native int nGetOffsetForAdvance(long paintPtr, char[] text, int start, int end,
int contextStart, int contextEnd, boolean isRtl, float advance);
private static native void nGetFontMetricsIntForText(long paintPtr, char[] text,
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index a2f5301e353f..8e3acb8570f0 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -1176,6 +1176,17 @@ public class Typeface {
mWeight = nativeGetWeight(ni);
}
+ /**
+ * Releases the underlying native object.
+ *
+ * <p>For testing only. Do not use the instance after this method is called.
+ * It is safe to call this method twice or more on the same instance.
+ * @hide
+ */
+ public void releaseNativeObjectForTest() {
+ mCleaner.run();
+ }
+
private static Typeface getSystemDefaultTypeface(@NonNull String familyName) {
Typeface tf = sSystemFontMap.get(familyName);
return tf == null ? Typeface.DEFAULT : tf;
@@ -1425,7 +1436,7 @@ public class Typeface {
public static void destroySystemFontMap() {
synchronized (SYSTEM_FONT_MAP_LOCK) {
for (Typeface typeface : sSystemFontMap.values()) {
- typeface.mCleaner.run();
+ typeface.releaseNativeObjectForTest();
}
sSystemFontMap.clear();
if (sSystemFontMapBuffer != null) {
@@ -1433,7 +1444,23 @@ public class Typeface {
}
sSystemFontMapBuffer = null;
sSystemFontMapSharedMemory = null;
+ synchronized (sStyledCacheLock) {
+ destroyTypefaceCacheLocked(sStyledTypefaceCache);
+ }
+ synchronized (sWeightCacheLock) {
+ destroyTypefaceCacheLocked(sWeightTypefaceCache);
+ }
+ }
+ }
+
+ private static void destroyTypefaceCacheLocked(LongSparseArray<SparseArray<Typeface>> cache) {
+ for (int i = 0; i < cache.size(); i++) {
+ SparseArray<Typeface> array = cache.valueAt(i);
+ for (int j = 0; j < array.size(); j++) {
+ array.valueAt(j).releaseNativeObjectForTest();
+ }
}
+ cache.clear();
}
/** @hide */
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index e7bc74a1744f..6959a591338c 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Bestuur"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Borrel is toegemaak."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tik om hierdie program te herbegin en maak volskerm oop."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tik om hierdie program te herbegin vir ’n beter aansig."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerakwessies?\nTik om aan te pas"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 8b2a89238584..fe22b2ce3278 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ለተሻለ ዕይታ ይህን መተግበሪያ ዳግም ለማስነሳት መታ ያድርጉ።"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"የካሜራ ችግሮች አሉ?\nዳግም ለማበጀት መታ ያድርጉ"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 2afce7fa3c43..2be6f39f9475 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"انقر لإعادة تشغيل هذا التطبيق للحصول على عرض أفضل."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"هل هناك مشاكل في الكاميرا؟\nانقر لإعادة الضبط."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ألم يتم حل المشكلة؟\nانقر للعودة"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"أليس هناك مشاكل في الكاميرا؟ انقر للإغلاق."</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index df975751ee31..098ee84de018 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"এপ্‌টো ৰিষ্টাৰ্ট কৰিবলৈ আৰু পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ টিপক।"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"উন্নত ভিউৰ বাবে এপ্‌টো ৰিষ্টাৰ্ট কৰিবলৈ টিপক।"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"কেমেৰাৰ কোনো সমস্যা হৈছে নেকি?\nপুনৰ খাপ খোৱাবলৈ টিপক"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 892be9345e3a..2f49ae6fdafc 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün toxunun."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toxunaraq bu tətbiqi yenidən başladın ki, daha görüntü əldə edəsiniz."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera problemi var?\nBərpa etmək üçün toxunun"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index b34920e0568f..0656fe185013 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 525e46ff371e..702f0abc07ae 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Націсніце, каб перазапусціць гэту праграму для лепшага прагляду."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Праблемы з камерай?\nНацісніце, каб пераабсталяваць"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не ўдалося выправіць?\nНацісніце, каб аднавіць"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ніякіх праблем з камерай? Націсніце, каб адхіліць."</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index e27ec8ee11bb..0de16d37cd69 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Докоснете, за да рестартирате това приложение с цел по-добър изглед."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблеми с камерата?\nДокоснете за ремонтиране"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нямате проблеми с камерата? Докоснете, за да отхвърлите."</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 0a8b0b746231..9a48d186b231 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও \'ফুল-স্ক্রিন\' মোড ব্যবহার করুন।"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"আরও ভাল ভিউয়ের জন্য এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন।"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ক্যামেরা সংক্রান্ত সমস্যা?\nরিফিট করতে ট্যাপ করুন"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এখনও সমাধান হয়নি?\nরিভার্ট করার জন্য ট্যাপ করুন"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ক্যামেরা সংক্রান্ত সমস্যা নেই? বাতিল করতে ট্যাপ করুন।"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index aadbfa434cf4..31e906de7f51 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da ponovo pokrenete ovu aplikaciju radi boljeg prikaza."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s kamerom?\nDodirnite da ponovo namjestite"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index ab672460ce1d..ca0a4211c435 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Toca per reiniciar aquesta aplicació i passar a pantalla completa."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toca per reiniciar aquesta aplicació i obtenir una millor visualització."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tens problemes amb la càmera?\nToca per resoldre\'ls"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index d7b1a3889806..e8772fe269b6 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Klepnutím tuto aplikaci kvůli lepšímu zobrazení restartujete."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s fotoaparátem?\nKlepnutím vyřešíte"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index c0acc08cde19..2b55d4d688ac 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tryk for at genstarte denne app, og gå til fuld skærm."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tryk for at genstarte denne app, så visningen forbedres."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du problemer med dit kamera?\nTryk for at gendanne det oprindelige format"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index e06bebda8bdf..03eee024f3be 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tippe, um die App im Vollbildmodus neu zu starten."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tippe, um diese App neu zu starten und die Ansicht zu verbessern."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Probleme mit der Kamera?\nZum Anpassen tippen."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 0d9d3eab591b..49bfdf18b1e6 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Πατήστε για επανεκκίνηση αυτής της εφαρμογής και ενεργοποίηση πλήρους οθόνης."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Πατήστε για να επανεκκινήσετε αυτή την εφαρμογή για καλύτερη προβολή."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Προβλήματα με την κάμερα;\nΠατήστε για επιδιόρθωση."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Δεν διορθώθηκε;\nΠατήστε για επαναφορά."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 48525cd10749..081a01a49249 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 48525cd10749..081a01a49249 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 48525cd10749..081a01a49249 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 48525cd10749..081a01a49249 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tap to restart this app and go full screen."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tap to restart this app for a better view."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index fb6db5f91a25..afc14b821d62 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎Bubble‎‏‎‎‏‎"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎Manage‎‏‎‎‏‎"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎Bubble dismissed.‎‏‎‎‏‎"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎Tap to restart this app and go full screen.‎‏‎‎‏‎"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎Tap to restart this app for a better view.‎‏‎‎‏‎"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎Camera issues?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap to refit‎‏‎‎‏‎"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎Didn’t fix it?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Tap to revert‎‏‎‎‏‎"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎No camera issues? Tap to dismiss.‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 3db353a0b4ea..b376b7881333 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Presiona para reiniciar esta app y tener una mejor vista."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Tienes problemas con la cámara?\nPresiona para reajustarla"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se resolvió?\nPresiona para revertir los cambios"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No tienes problemas con la cámara? Presionar para descartar."</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index c2493287bcb8..79c1f90a4b8d 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y obtener una mejor vista."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Problemas con la cámara?\nToca para reajustar"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 0133336e58b8..a7fead6af9aa 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Puudutage, et see rakendus parema vaate jaoks taaskäivitada."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kas teil on kaameraprobleeme?\nPuudutage ümberpaigutamiseks."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 71ccad59e71a..e7530c9690a7 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Saka ezazu aplikazioa berrabiarazteko, eta ezarri pantaila osoko modua."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Hobeto ikusteko, sakatu hau aplikazioa berrabiarazteko."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Arazoak dauzkazu kamerarekin?\nBerriro doitzeko, sakatu hau."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ez al da konpondu?\nLeheneratzeko, sakatu hau."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau."</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 20045eff330c..66a657e36c13 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"برای بازراه‌اندازی این برنامه و تغییر به حالت تمام‌صفحه، ضربه بزنید."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"برای داشتن نمایی بهتر، ضربه بزنید تا این برنامه بازراه‌اندازی شود."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه ضربه بزنید"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن ضربه بزنید"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن ضربه بزنید."</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 2cd265ea82f0..eaf369ad0486 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Napauta, niin sovellus käynnistyy uudelleen paremmin näytölle sopivana."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Onko kameran kanssa ongelmia?\nKorjaa napauttamalla"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index eb25a8d16434..8f614c56db14 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Touchez pour redémarrer cette application et passer en plein écran."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 53358b7a23b7..ec3e1b33a4fa 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Appuyez pour redémarrer cette appli et avoir une meilleure vue."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo ?\nAppuyez pour réajuster"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 09977a194fea..651353d89319 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toca o botón para reiniciar esta aplicación e gozar dunha mellor visualización."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tes problemas coa cámara?\nToca para reaxustala"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 8e9f086daa97..3543be0bda07 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"વધુ સારા વ્યૂ માટે, આ ઍપને ફરી શરૂ કરવા ટૅપ કરો."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"કૅમેરામાં સમસ્યાઓ છે?\nફરીથી ફિટ કરવા માટે ટૅપ કરો"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો."</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 3d83005ba30b..87ac5d64ff85 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन पर देखने के लिए टैप करें."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"टैप करके ऐप्लिकेशन को रीस्टार्ट करें और बेहतर व्यू पाएं."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 1c4116d6cc8a..cb4f424cf317 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Dodirnite da biste ponovo pokrenuli tu aplikaciju i prikazali je na cijelom zaslonu."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s fotoaparatom?\nDodirnite za popravak"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index d749775a2160..635f4dad8f89 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"A jobb nézet érdekében koppintson az alkalmazás újraindításához."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerával kapcsolatos problémába ütközött?\nKoppintson a megoldáshoz."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 160651ca67ad..da382c113797 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Հպեք՝ հավելվածը վերագործարկելու և ավելի հարմար տեսք ընտրելու համար։"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Տեսախցիկի հետ կապված խնդիրնե՞ր կան։\nՀպեք՝ վերակարգավորելու համար։"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index fab34868009e..cd795390128b 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Ketuk untuk memulai ulang aplikasi ini agar mendapatkan tampilan yang lebih baik."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Masalah kamera?\nKetuk untuk memperbaiki"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index c22b88138714..37141b74005c 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Ýta til að endurræsa forritið og fá betri sýn."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Myndavélavesen?\nÝttu til að breyta stærð"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 7ec13c4248e0..b63e76466b6e 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -72,7 +72,8 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tocca per riavviare l\'app e passare alla modalità a schermo intero."</string>
+ <!-- no translation found for restart_button_description (6712141648865547958) -->
+ <skip />
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi con la fotocamera?\nTocca per risolverli"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 8625a2a079da..0e500eafd805 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"כדי לראות טוב יותר יש להקיש ולהפעיל את האפליקציה הזו מחדש."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"בעיות במצלמה?\nאפשר להקיש כדי לבצע התאמה מחדש"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר להקיש כדי לחזור לגרסה הקודמת"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר להקיש כדי לסגור."</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 4d09b202ca06..34ed9c72da0e 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"タップしてこのアプリを再起動すると、全画面表示になります。"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"タップしてこのアプリを再起動すると、表示が適切になります。"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"カメラに関する問題の場合は、\nタップすると修正できます"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 8cbc3d893bd8..14b26c1932cc 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"შეეხეთ ამ აპის გადასატვირთად და გადადით სრულ ეკრანზე."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"შეეხეთ, რომ გადატვირთოთ ეს აპი უკეთესი ხედისთვის."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"კამერად პრობლემები აქვს?\nშეეხეთ გამოსასწორებლად"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის."</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 22cf08b92082..c42efdc4cf25 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Ыңғайлы көріністі реттеу үшін қолданбаны түртіп, өшіріп қосыңыз."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада қателер шықты ма?\nЖөндеу үшін түртіңіз."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 1e72d4fe145f..302b25e5bad2 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោល​សារលេចឡើង។"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញ រួចចូលប្រើ​ពេញអេក្រង់។"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញសម្រាប់ទិដ្ឋភាពកាន់តែប្រសើរ។"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"មានបញ្ហា​ពាក់ព័ន្ធនឹង​កាមេរ៉ាឬ?\nចុចដើម្បី​ដោះស្រាយ"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"មិនបាន​ដោះស្រាយ​បញ្ហានេះទេឬ?\nចុចដើម្បី​ត្រឡប់"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"មិនមាន​បញ្ហាពាក់ព័ន្ធនឹង​កាមេរ៉ាទេឬ? ចុចដើម្បី​ច្រានចោល។"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 24d0c8257b7b..2b3aa0791336 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ಉತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿವೆಯೇ?\nಮರುಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 15e8a9041202..5505955db71a 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"보기를 개선하려면 탭하여 앱을 다시 시작합니다."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"카메라 문제가 있나요?\n해결하려면 탭하세요."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 94ea9fb9f950..d45a9848abc4 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн таптап коюңуз."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Жакшыраак көрүү үчүн бул колдонмону өчүрүп күйгүзүңүз. Ал үчүн таптап коюңуз."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада маселелер келип чыктыбы?\nОңдоо үчүн таптаңыз"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз."</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index be72d8e2a22f..0eeee906070b 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ ແລະ ໃຊ້ແບບເຕັມຈໍ."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ເພື່ອມຸມມອງທີ່ດີຂຶ້ນ."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ?\nແຕະເພື່ອປັບໃໝ່"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອ​ປິດ​ໄວ້."</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 3fa163bb35c2..fc118e217481 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Palieskite, kad paleistumėte iš naujo šią programą ir įjungtumėte viso ekrano režimą."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Palieskite, kad iš naujo paleistumėte šią programą ir matytumėte aiškiau."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Iškilo problemų dėl kameros?\nPalieskite, kad pritaikytumėte iš naujo"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 90cd4bed63f8..cd2af07beb7e 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Pieskarieties, lai restartētu šo lietotni un uzlabotu attēlojumu."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Vai ir problēmas ar kameru?\nPieskarieties, lai tās novērstu."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 56e9b406fe8d..c0dff00e6a7c 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Допрете за да ја рестартирате апликацијава за подобар приказ."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми со камерата?\nДопрете за да се совпадне повторно"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 88e49e78d925..52ea1c7c3150 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബിൾ ഡിസ്മിസ് ചെയ്തു."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്‌ത് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"മികച്ച കാഴ്‌ചയ്‌ക്കായി ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ക്യാമറ പ്രശ്നങ്ങളുണ്ടോ?\nശരിയാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 7a6f62577e63..fd4c4aab1832 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Харагдах байдлыг сайжруулахын тулд энэ аппыг товшиж, дахин эхлүүлнэ үү."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерын асуудал гарсан уу?\nДахин тааруулахын тулд товшино уу"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерын асуудал байхгүй юу? Хаахын тулд товшино уу."</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index c2a947542f0a..b9a165eb6b11 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"हे अ‍ॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"अधिक चांगल्या व्ह्यूसाठी हे अ‍ॅप रीस्टार्ट करण्याकरिता टॅप करा."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"कॅमेराशी संबंधित काही समस्या आहेत का?\nपुन्हा फिट करण्यासाठी टॅप करा"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्‍यासाठी टॅप करा."</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 35512c1c75bb..3d81c9a551fa 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Ketik untuk memulakan semula apl ini untuk mendapatkan paparan yang lebih baik."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Isu kamera?\nKetik untuk memuatkan semula"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 5aea49f59e2f..50adfe98d8f9 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ဤအက်ပ်ကို ပြန်စပြီး ဖန်သားပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ပိုကောင်းသောမြင်ကွင်းအတွက် ဤအက်ပ်ပြန်စရန် တို့နိုင်သည်။"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ကင်မရာပြဿနာလား။\nပြင်ဆင်ရန် တို့ပါ"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 8e87bc10c470..74e066ec11fd 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Trykk for å starte denne appen på nytt for bedre visning."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du kameraproblemer?\nTrykk for å tilpasse"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 831f6e2ef829..b257f9e6d0d3 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"यो एप अझ राम्रो हेर्न मिल्ने बनाउनका लागि यसलाई रिस्टार्ट गर्न ट्याप गर्नुहोस्।"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्यामेरासम्बन्धी समस्या देखियो?\nसमस्या हल गर्न ट्याप गर्नुहोस्"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index affdd0e2a223..6ea24a8b3808 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tik om deze app opnieuw te starten en te openen op het volledige scherm."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tik om deze app opnieuw op te starten voor een betere weergave."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Cameraproblemen?\nTik om opnieuw passend te maken."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index f150cb9a9160..f8c924828d50 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ଏହି ଆପକୁ ରିଷ୍ଟାର୍ଟ କରି ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ଏକ ଆହୁରି ଭଲ ଭ୍ୟୁ ପାଇଁ ଏହି ଆପ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"କ୍ୟାମେରାରେ ସମସ୍ୟା ଅଛି?\nପୁଣି ଫିଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ଏହାର ସମାଧାନ ହୋଇନାହିଁ?\nଫେରିଯିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"କ୍ୟାମେରାରେ କିଛି ସମସ୍ୟା ନାହିଁ? ଖାରଜ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 62587e58edc9..b80da0ba4e57 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਲਈ ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ?\nਮੁੜ-ਫਿੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 363c851ca4cd..bdd44dd8a743 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Kliknij, aby zrestartować aplikację i zyskać lepszą widoczność."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemy z aparatem?\nKliknij, aby dopasować"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Naprawa się nie udała?\nKliknij, aby cofnąć"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Brak problemów z aparatem? Kliknij, aby zamknąć"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index f328b6c3a781..b9e41eae5de9 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 67369b8b0175..c1e57d8c9c97 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar esta app e ficar em ecrã inteiro."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ficar com uma melhor visão."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmara?\nToque aqui para reajustar"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index f328b6c3a781..b9e41eae5de9 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Toque para reiniciar o app e usar tela cheia."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar o app e atualizar a visualização."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 8da1d67f9841..c49bf9dc231c 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionați"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Atingeți ca să reporniți aplicația pentru o vizualizare mai bună."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Aveți probleme cu camera foto?\nAtingeți pentru a reîncadra"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ați remediat problema?\nAtingeți pentru a reveni"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu aveți probleme cu camera foto? Atingeți pentru a închide."</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 49efac67ceb0..ffe031d86725 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Нажмите, чтобы перезапустить приложение и настроить удобный для просмотра вид"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблемы с камерой?\nНажмите, чтобы исправить."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не помогло?\nНажмите, чтобы отменить изменения."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нет проблем с камерой? Нажмите, чтобы закрыть."</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 1f8cba85c9eb..b27e1b9bc94a 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"වඩා හොඳ දසුනක් ලබා ගැනීම සඳහා මෙම යෙදුම යළි ඇරඹීමට තට්ටු කරන්න."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"කැමරා ගැටලුද?\nයළි සවි කිරීමට තට්ටු කරන්න"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"එය විසඳුවේ නැතිද?\nප්‍රතිවර්තනය කිරීමට තට්ටු කරන්න"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index ca14dd78aaa5..b5bedf79f3ba 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Ak chcete zlepšiť zobrazenie, klepnutím túto aplikáciu reštartujte."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s kamerou?\nKlepnutím znova upravte."</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 626be8beb04d..ac926b9ee8db 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Dotaknite se za vnovični zagon te aplikacije in preklop v celozaslonski način."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Če želite boljši prikaz, se dotaknite za vnovični zagon te aplikacije."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Težave s fotoaparatom?\nDotaknite se za vnovično prilagoditev"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 591f4b71b00c..07c52fe4251a 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Trokit për të rifilluar këtë aplikacion për një pamje më të mirë."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Ka probleme me kamerën?\nTrokit për ta ripërshtatur"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index fdd49b5542c7..0289dd105ee5 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Додирните да бисте рестартовали ову апликацију ради бољег приказа."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблема са камером?\nДодирните да бисте поново уклопили"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 54384ca14db9..cfdb1ddcf377 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Tryck för att starta om appen i helskärmsläge."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Tryck för att starta om appen och få en bättre vy."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problem med kameran?\nTryck för att anpassa på nytt"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 2f7d2246f939..383e9bb6bbfa 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Gusa ili uzime na uwashe programu hii, kisha nenda kwenye skrini nzima."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Gusa ili uzime kisha uwashe programu hii, ili upate mwonekano bora."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Je, kuna hitilafu za kamera?\nGusa ili urekebishe"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index b6269946ab32..cc512f3c48aa 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"இங்கு தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்டப்படும் விதத்தை இன்னும் சிறப்பாக்கலாம்."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"கேமரா தொடர்பான சிக்கல்களா?\nமீண்டும் பொருத்த தட்டவும்"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index f0803507b5fc..cdbe021add47 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"ఈ యాప్‌ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేసి, ఆపై పూర్తి స్క్రీన్‌లోకి వెళ్లండి."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"మెరుగైన వీక్షణ కోసం ఈ యాప్‌ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేయండి."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"కెమెరా సమస్యలు ఉన్నాయా?\nరీఫిట్ చేయడానికి ట్యాప్ చేయండి"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి."</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 0d1f23b1d350..136a81c06c4f 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"แตะเพื่อรีสตาร์ทแอปนี้และรับมุมมองที่ดียิ่งขึ้น"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"หากพบปัญหากับกล้อง\nแตะเพื่อแก้ไข"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"หากไม่ได้แก้ไข\nแตะเพื่อเปลี่ยนกลับ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"หากไม่พบปัญหากับกล้อง แตะเพื่อปิด"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index bfae45afeb5d..4d32af36cabe 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"I-tap para i-restart ang app na ito at mag-full screen."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"I-tap para i-restart ang app na ito para sa mas magandang view."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"May mga isyu sa camera?\nI-tap para i-refit"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 6a9be8048505..f3ab37065270 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Bu uygulamayı yeniden başlatarak daha iyi bir görünüm elde etmek için dokunun."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kameranızda sorun mu var?\nDüzeltmek için dokunun"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 52f6d1145245..d7d82cb56ac5 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Натисніть, щоб перезапустити цей додаток для зручнішого перегляду."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми з камерою?\nНатисніть, щоб пристосувати"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблему не вирішено?\nНатисніть, щоб скасувати зміни"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немає проблем із камерою? Торкніться, щоб закрити."</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 3abfb0d4fa65..4a8476aebe18 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"بہتر منظر کے لیے اس ایپ کو ری اسٹارٹ کرنے کی خاطر تھپتھپائیں۔"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"کیمرے کے مسائل؟\nدوبارہ فٹ کرنے کیلئے تھپتھپائیں"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 0c0771f870dd..8a4eac3bb657 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Bu ilovani qaytadan ishga tushirish va butun ekranda ochish uchun bosing."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Yaxshiroq koʻrish maqsadida bu ilovani qayta ishga tushirish uchun bosing."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera nosozmi?\nQayta moslash uchun bosing"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 8b692a71dd27..2f8fe6076c68 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Nhấn để khởi động lại ứng dụng này để xem tốt hơn."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Có vấn đề với máy ảnh?\nHãy nhấn để sửa lỗi"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 8fed6bfb3eed..ab44fb1d2488 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭对话泡。"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"点按即可重启此应用并进入全屏模式。"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"点按即可重启此应用,获得更好的视图体验。"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相机有问题?\n点按即可整修"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"没有解决此问题?\n点按即可恢复"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相机没有问题?点按即可忽略。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index add329188515..8fb7adebe930 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"輕按並重新啟動此應用程式,以取得更佳的觀看體驗。"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題?\n輕按即可修正"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index f2c2a2970d8b..45de4156084b 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string>
- <string name="restart_button_description" msgid="5887656107651190519">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"請輕觸並重新啟動此應用程式,取得更良好的觀看體驗。"</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題嗎?\n輕觸即可修正"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 94e5b9bf4529..7c31a166e825 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -72,7 +72,7 @@
<string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string>
- <string name="restart_button_description" msgid="5887656107651190519">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string>
+ <string name="restart_button_description" msgid="6712141648865547958">"Thepha ukuze uqale kabusha le app ukuze ibonakale kangcono."</string>
<string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Izinkinga zekhamera?\nThepha ukuze uyilinganise kabusha"</string>
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 68a08513e7f5..2a38766f409e 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -30,6 +30,9 @@
<!-- Title of menu shown over picture-in-picture. Used for accessibility. -->
<string name="pip_menu_title">Menu</string>
+ <!-- accessibility Title of menu shown over picture-in-picture [CHAR LIMIT=NONE] -->
+ <string name="pip_menu_accessibility_title">Picture-in-Picture Menu</string>
+
<!-- PiP BTW notification title. [CHAR LIMIT=50] -->
<string name="pip_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is in picture-in-picture</string>
@@ -73,8 +76,10 @@
<!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. -->
<string name="activity_launch_on_secondary_display_failed_text">App does not support launch on secondary displays.</string>
- <!-- Accessibility label for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
+ <!-- Accessibility label and window tile for the divider that separates the windows in split-screen mode [CHAR LIMIT=NONE] -->
<string name="accessibility_divider">Split-screen divider</string>
+ <!-- Accessibility window title for the split-screen divider window [CHAR LIMIT=NONE] -->
+ <string name="divider_title">Split-screen divider</string>
<!-- Accessibility action for moving docked stack divider to make the left screen full screen [CHAR LIMIT=NONE] -->
<string name="accessibility_action_divider_left_full">Left full screen</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
index 992f31562145..5a94a0d6f6a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
@@ -17,7 +17,15 @@
package com.android.wm.shell;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
+import android.os.Build;
+import android.os.SystemClock;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
@@ -37,10 +45,12 @@ import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.unfold.UnfoldAnimationController;
import com.android.wm.shell.unfold.UnfoldTransitionHandler;
+import java.util.ArrayList;
import java.util.Optional;
/**
- * The entry point implementation into the shell for initializing shell internal state.
+ * The entry point implementation into the shell for initializing shell internal state. Classes
+ * which need to setup on start should inject an instance of this class and add an init callback.
*/
public class ShellInitImpl {
private static final String TAG = ShellInitImpl.class.getSimpleName();
@@ -64,6 +74,9 @@ public class ShellInitImpl {
private final Optional<RecentTasksController> mRecentTasks;
private final InitImpl mImpl = new InitImpl();
+ // An ordered list of init callbacks to be made once shell is first started
+ private final ArrayList<Pair<String, Runnable>> mInitCallbacks = new ArrayList<>();
+ private boolean mHasInitialized;
public ShellInitImpl(
DisplayController displayController,
@@ -106,7 +119,7 @@ public class ShellInitImpl {
return mImpl;
}
- private void init() {
+ private void legacyInit() {
// Start listening for display and insets changes
mDisplayController.initialize();
mDisplayInsetsController.initialize();
@@ -153,12 +166,52 @@ public class ShellInitImpl {
mKidsModeTaskOrganizer.initialize(mStartingWindow);
}
+ /**
+ * Adds a callback to the ordered list of callbacks be made when Shell is first started. This
+ * can be used in class constructors when dagger is used to ensure that the initialization order
+ * matches the dependency order.
+ */
+ public <T extends Object> void addInitCallback(Runnable r, T instance) {
+ if (mHasInitialized) {
+ if (Build.isDebuggable()) {
+ // All callbacks must be added prior to the Shell being initialized
+ throw new IllegalArgumentException("Can not add callback after init");
+ }
+ return;
+ }
+ final String className = instance.getClass().getSimpleName();
+ mInitCallbacks.add(new Pair<>(className, r));
+ ProtoLog.v(WM_SHELL_INIT, "Adding init callback for %s", className);
+ }
+
+ /**
+ * Calls all the init callbacks when the Shell is first starting.
+ */
+ @VisibleForTesting
+ public void init() {
+ ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
+ // Init in order of registration
+ for (int i = 0; i < mInitCallbacks.size(); i++) {
+ final Pair<String, Runnable> info = mInitCallbacks.get(i);
+ final long t1 = SystemClock.uptimeMillis();
+ info.second.run();
+ final long t2 = SystemClock.uptimeMillis();
+ ProtoLog.v(WM_SHELL_INIT, "\t%s took %dms", info.first, (t2 - t1));
+ }
+ mInitCallbacks.clear();
+
+ // TODO: To be removed
+ legacyInit();
+
+ mHasInitialized = true;
+ }
+
@ExternalThread
private class InitImpl implements ShellInit {
@Override
public void init() {
try {
- mMainExecutor.executeBlocking(() -> ShellInitImpl.this.init());
+ mMainExecutor.executeBlocking(ShellInitImpl.this::init);
} catch (InterruptedException e) {
throw new RuntimeException("Failed to initialize the Shell in 2s", e);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 9df82514a4e2..4080b99d30cf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -500,7 +501,9 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
|| (taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME
&& taskInfo.isVisible);
final boolean focusTaskChanged = (mLastFocusedTaskInfo == null
- || mLastFocusedTaskInfo.taskId != taskInfo.taskId) && isFocusedOrHome;
+ || mLastFocusedTaskInfo.taskId != taskInfo.taskId
+ || mLastFocusedTaskInfo.getWindowingMode() != taskInfo.getWindowingMode())
+ && isFocusedOrHome;
if (focusTaskChanged) {
for (int i = 0; i < mFocusListeners.size(); i++) {
mFocusListeners.valueAt(i).onFocusTaskChanged(taskInfo);
@@ -542,7 +545,8 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
// Notify the recent tasks that a task has been removed
mRecentTasks.ifPresent(recentTasks -> recentTasks.onTaskRemoved(taskInfo));
- if (appearedInfo.getLeash() != null) {
+ if (!ENABLE_SHELL_TRANSITIONS && (appearedInfo.getLeash() != null)) {
+ // Preemptively clean up the leash only if shell transitions are not enabled
appearedInfo.getLeash().release();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
index b483fe03e80f..312af4ff7bc2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
@@ -829,8 +829,12 @@ class PhysicsAnimator<T> private constructor (target: T) {
/** Cancels all in progress animations on all properties. */
fun cancel() {
- cancelAction(flingAnimations.keys)
- cancelAction(springAnimations.keys)
+ if (flingAnimations.size > 0) {
+ cancelAction(flingAnimations.keys)
+ }
+ if (springAnimations.size > 0) {
+ cancelAction(springAnimations.keys)
+ }
}
/** Cancels in progress animations on the provided properties only. */
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 a2c40550b583..62aa7fe28728 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
@@ -85,7 +85,6 @@ import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.UiEventLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.TaskViewTransitions;
@@ -223,44 +222,8 @@ public class BubbleController {
/** Drag and drop controller to register listener for onDragStarted. */
private DragAndDropController mDragAndDropController;
- /**
- * Creates an instance of the BubbleController.
- */
- public static BubbleController create(Context context,
- @Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
- FloatingContentCoordinator floatingContentCoordinator,
- @Nullable IStatusBarService statusBarService,
- WindowManager windowManager,
- WindowManagerShellWrapper windowManagerShellWrapper,
- UserManager userManager,
- LauncherApps launcherApps,
- TaskStackListenerImpl taskStackListener,
- UiEventLogger uiEventLogger,
- ShellTaskOrganizer organizer,
- DisplayController displayController,
- Optional<OneHandedController> oneHandedOptional,
- DragAndDropController dragAndDropController,
- @ShellMainThread ShellExecutor mainExecutor,
- @ShellMainThread Handler mainHandler,
- @ShellBackgroundThread ShellExecutor bgExecutor,
- TaskViewTransitions taskViewTransitions,
- SyncTransactionQueue syncQueue) {
- BubbleLogger logger = new BubbleLogger(uiEventLogger);
- BubblePositioner positioner = new BubblePositioner(context, windowManager);
- BubbleData data = new BubbleData(context, logger, positioner, mainExecutor);
- return new BubbleController(context, data, synchronizer, floatingContentCoordinator,
- new BubbleDataRepository(context, launcherApps, mainExecutor),
- statusBarService, windowManager, windowManagerShellWrapper, userManager,
- launcherApps, logger, taskStackListener, organizer, positioner, displayController,
- oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
- taskViewTransitions, syncQueue);
- }
-
- /**
- * Testing constructor.
- */
- @VisibleForTesting
- protected BubbleController(Context context,
+
+ public BubbleController(Context context,
BubbleData data,
@Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
FloatingContentCoordinator floatingContentCoordinator,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
index 6fb021ea5e2f..74f8bf9ac863 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java
@@ -50,6 +50,8 @@ import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.common.SurfaceUtils;
+import java.util.function.Consumer;
+
/**
* Handles split decor like showing resizing hint for a specific split.
*/
@@ -212,7 +214,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
newBounds.height() / 2 - mIconSize / 2);
if (animate) {
- startFadeAnimation(show, false /* isResized */);
+ startFadeAnimation(show, null /* finishedConsumer */);
mShown = show;
}
}
@@ -243,15 +245,29 @@ public class SplitDecorManager extends WindowlessWindowManager {
mFadeAnimator.cancel();
}
if (mShown) {
- startFadeAnimation(false /* show */, true /* isResized */);
- mShown = false;
+ fadeOutDecor(null /* finishedCallback */);
} else {
// Decor surface is hidden so release it directly.
releaseDecor(t);
}
}
- private void startFadeAnimation(boolean show, boolean isResized) {
+ /** Fade-out decor surface with animation end callback, if decor is hidden, run the callback
+ * directly. */
+ public void fadeOutDecor(Runnable finishedCallback) {
+ if (mShown) {
+ startFadeAnimation(false /* show */, transaction -> {
+ releaseDecor(transaction);
+ if (finishedCallback != null) finishedCallback.run();
+ });
+ mShown = false;
+ } else {
+ if (finishedCallback != null) finishedCallback.run();
+ }
+ }
+
+ private void startFadeAnimation(boolean show,
+ Consumer<SurfaceControl.Transaction> finishedConsumer) {
final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
mFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
mFadeAnimator.setDuration(FADE_DURATION);
@@ -285,8 +301,8 @@ public class SplitDecorManager extends WindowlessWindowManager {
animT.hide(mIconLeash);
}
}
- if (isResized) {
- releaseDecor(animT);
+ if (finishedConsumer != null) {
+ finishedConsumer.accept(animT);
}
animT.apply();
animT.close();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 2e64c945ca25..b69cbfa83d7c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -32,6 +32,7 @@ import static com.android.wm.shell.animation.Interpolators.SLOWDOWN_INTERPOLATOR
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -449,11 +450,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
switch (snapTarget.flag) {
case FLAG_DISMISS_START:
flingDividePosition(currentPosition, snapTarget.position,
- () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */));
+ () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */,
+ EXIT_REASON_DRAG_DIVIDER));
break;
case FLAG_DISMISS_END:
flingDividePosition(currentPosition, snapTarget.position,
- () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */));
+ () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */,
+ EXIT_REASON_DRAG_DIVIDER));
break;
default:
flingDividePosition(currentPosition, snapTarget.position,
@@ -509,6 +512,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
}
+ /** Fling divider from current position to end or start position then exit */
+ public void flingDividerToDismiss(boolean toEnd, int reason) {
+ final int target = toEnd ? mDividerSnapAlgorithm.getDismissEndTarget().position
+ : mDividerSnapAlgorithm.getDismissStartTarget().position;
+ flingDividePosition(getDividePosition(), target,
+ () -> mSplitLayoutHandler.onSnappedToDismiss(toEnd, reason));
+ }
+
@VisibleForTesting
void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) {
if (from == to) {
@@ -758,7 +769,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
public interface SplitLayoutHandler {
/** Calls when dismissing split. */
- void onSnappedToDismiss(boolean snappedToEnd);
+ void onSnappedToDismiss(boolean snappedToEnd, int reason);
/**
* Calls when resizing the split bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index 864b9a7528b0..7fea23797e67 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -126,6 +126,7 @@ public final class SplitWindowManager extends WindowlessWindowManager {
lp.token = new Binder();
lp.setTitle(mWindowName);
lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
+ lp.accessibilityTitle = mContext.getResources().getString(R.string.accessibility_divider);
mViewHost.setView(mDividerView, lp);
mDividerView.setup(splitLayout, this, mViewHost, insetsState);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt
deleted file mode 100644
index 1cd69edf7cd2..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-The dagger modules in this directory can be included by the host SysUI using the Shell library for
-explicity injection of Shell components. Apps using this library are not required to use these
-dagger modules for setup, but it is recommended for them to include them as needed.
-
-The modules are currently inherited as such:
-
-+- WMShellBaseModule (common shell features across SysUI)
- |
- +- WMShellModule (handheld)
- |
- +- TvPipModule (tv pip)
- |
- +- TvWMShellModule (tv) \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index a8c1071eb69e..189743728840 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -31,6 +31,10 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.TaskViewTransitions;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.BubbleData;
+import com.android.wm.shell.bubbles.BubbleDataRepository;
+import com.android.wm.shell.bubbles.BubbleLogger;
+import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
@@ -104,10 +108,33 @@ public abstract class WMShellModule {
// Bubbles
//
+ @WMSingleton
+ @Provides
+ static BubbleLogger provideBubbleLogger(UiEventLogger uiEventLogger) {
+ return new BubbleLogger(uiEventLogger);
+ }
+
+ @WMSingleton
+ @Provides
+ static BubblePositioner provideBubblePositioner(Context context,
+ WindowManager windowManager) {
+ return new BubblePositioner(context, windowManager);
+ }
+
+ @WMSingleton
+ @Provides
+ static BubbleData provideBubbleData(Context context,
+ BubbleLogger logger,
+ BubblePositioner positioner,
+ @ShellMainThread ShellExecutor mainExecutor) {
+ return new BubbleData(context, logger, positioner, mainExecutor);
+ }
+
// Note: Handler needed for LauncherApps.register
@WMSingleton
@Provides
static BubbleController provideBubbleController(Context context,
+ BubbleData data,
FloatingContentCoordinator floatingContentCoordinator,
IStatusBarService statusBarService,
WindowManager windowManager,
@@ -115,8 +142,9 @@ public abstract class WMShellModule {
UserManager userManager,
LauncherApps launcherApps,
TaskStackListenerImpl taskStackListener,
- UiEventLogger uiEventLogger,
+ BubbleLogger logger,
ShellTaskOrganizer organizer,
+ BubblePositioner positioner,
DisplayController displayController,
@DynamicOverride Optional<OneHandedController> oneHandedOptional,
DragAndDropController dragAndDropController,
@@ -125,11 +153,12 @@ public abstract class WMShellModule {
@ShellBackgroundThread ShellExecutor bgExecutor,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue) {
- return BubbleController.create(context, null /* synchronizer */,
- floatingContentCoordinator, statusBarService, windowManager,
- windowManagerShellWrapper, userManager, launcherApps, taskStackListener,
- uiEventLogger, organizer, displayController, oneHandedOptional,
- dragAndDropController, mainExecutor, mainHandler, bgExecutor,
+ return new BubbleController(context, data, null /* synchronizer */,
+ floatingContentCoordinator,
+ new BubbleDataRepository(context, launcherApps, mainExecutor),
+ statusBarService, windowManager, windowManagerShellWrapper, userManager,
+ launcherApps, logger, taskStackListener, organizer, positioner, displayController,
+ oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
taskViewTransitions, syncQueue);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md
new file mode 100644
index 000000000000..73a7348d5aca
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/README.md
@@ -0,0 +1,18 @@
+# Window Manager Shell Readme
+
+The following docs present more detail about the implementation of the WMShell library (in no
+particular order):
+
+1) [What is the Shell](overview.md)
+2) [Integration with SystemUI & Launcher](sysui.md)
+3) [Usage of Dagger](dagger.md)
+4) [Threading model in the Shell](threading.md)
+5) [Making changes in the Shell](changes.md)
+6) [Extending the Shell for Products/OEMs](extending.md)
+7) [Debugging in the Shell](debugging.md)
+8) [Testing in the Shell](testing.md)
+
+Todo
+- Per-feature docs
+- Feature flagging
+- Best practices \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
new file mode 100644
index 000000000000..f4e2f20f4637
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
@@ -0,0 +1,73 @@
+# Making changes in the Shell
+
+---
+
+## Code reviews
+
+In addition to the individual reviewers who are most familiar with the changes you are making,
+please also add [wm-code-reviewers@google.com](http://g/wm-code-reviewers) to keep other WM folks
+in the loop.
+
+## Adding new code
+
+### Internal Shell utility classes
+If the new component is used only within the WMShell library, then there are no special
+considerations, go ahead and add it (in the `com.android.wm.shell.common` package for example)
+and make sure the appropriate [unit tests](testing.md) are added.
+
+### Internal Shell components
+If the new component is to be used by other components/features within the Shell library, then
+you can create an appropriate package for this component to add your new code. The current
+pattern is to have a single `<Component name>Controller` that handles the initialization of the
+component.
+
+As mentioned in the [Dagger usage](dagger.md) docs, you need to determine whether it should go into:
+- `WMShellBaseModule` for components that other base & product components will depend on
+- or `WMShellModule`, `TvWmShellModule`, etc. for product specific components that no base
+ components depend on
+
+### SysUI accessible components
+In addition to doing the above, you will also need to provide an interface for calling to SysUI
+from the Shell and vice versa. The current pattern is to have a parallel `Optional<Component name>`
+interface that the `<Component name>Controller` implements and handles on the main Shell thread.
+
+In addition, because components accessible to SysUI injection are explicitly listed, you'll have to
+add an appropriate method in `WMComponent` to get the interface and update the `Builder` in
+`SysUIComponent` to take the interface so it can be injected in SysUI code. The binding between
+the two is done in `SystemUIFactory#init()` which will need to be updated as well.
+
+### Launcher accessible components
+Because Launcher is not a part of SystemUI and is a separate process, exposing controllers to
+Launcher requires a new AIDL interface to be created and implemented by the controller. The
+implementation of the stub interface in the controller otherwise behaves similar to the interface
+to SysUI where it posts the work to the main Shell thread.
+
+### Component initialization
+To initialize the component:
+- On the Shell side, update `ShellInitImpl` to get a signal to initialize when the SysUI is started
+- On the SysUI side, update `WMShell` to setup any bindings for the component that depend on
+ SysUI code
+
+### General Do's & Dont's
+Do:
+- Do add unit tests for all new components
+- Do keep controllers simple and break them down as needed
+
+Don't:
+- **Don't** do initialization in the constructor, only do initialization in the init callbacks.
+ Otherwise it complicates the building of the dependency graph.
+- **Don't** create dependencies from base-module components on specific features (the base module
+ is intended for use with all products)
+ - Try adding a mechanism to register and listen for changes from the base module component instead
+- **Don't** add blocking synchronous calls in the SysUI interface between Shell & SysUI
+ - Try adding a push-mechanism to share data, or an async callback to request data
+
+### Exposing shared code for use in Launcher
+Launcher doesn't currently build against the Shell library, but needs to have access to some shared
+AIDL interfaces and constants. Currently, all AIDL files, and classes under the
+`com.android.wm.shell.util` package are automatically built into the `SystemUISharedLib` that
+Launcher uses.
+
+If the new code doesn't fall into those categories, they can be added explicitly in the Shell's
+[Android.bp](frameworks/base/libs/WindowManager/Shell/Android.bp) file under the
+`wm_shell_util-sources` filegroup. \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
new file mode 100644
index 000000000000..6c01d962adc9
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
@@ -0,0 +1,50 @@
+# Usage of Dagger in the Shell library
+
+---
+
+## Dependencies
+
+Dagger is not required to use the Shell library, but it has a lot of obvious benefits:
+
+- Not having to worry about how to instantiate all the dependencies of a class, especially as
+ dependencies evolve (ie. product controller depends on base controller)
+- Can create boundaries within the same app to encourage better code modularity
+
+As such, the Shell also tries to provide some reasonable out-of-the-box modules for use with Dagger.
+
+## Modules
+
+All the Dagger related code in the Shell can be found in the `com.android.wm.shell.dagger` package,
+this is intentional as it keeps the "magic" in a single location. The explicit nature of how
+components in the shell are provided is as a result a bit more verbose, but it makes it easy for
+developers to jump into a few select files and understand how different components are provided
+(especially as products override components).
+
+The module dependency tree looks a bit like:
+- [WMShellConcurrencyModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java)
+ (provides threading-related components)
+ - [WMShellBaseModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java)
+ (provides components that are likely common to all products, ie. DisplayController,
+ Transactions, etc.)
+ - [WMShellModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java)
+ (phone/tablet specific components only)
+ - [TvPipModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java)
+ (PIP specific components for TV)
+ - [TvWMShellModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java)
+ (TV specific components only)
+ - etc.
+
+Ideally features could be abstracted out into their own modules and included as needed by each
+product.
+
+## Overriding base components
+
+In some rare cases, there are base components that can change behavior depending on which
+product it runs on. If there are hooks that can be added to the component, that is the
+preferable approach.
+
+The alternative is to use the [@DynamicOverride](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/DynamicOverride.java)
+annotation to allow the product module to provide an implementation that the base module can
+reference. This is most useful if the existence of the entire component is controlled by the
+product and the override implementation is optional (there is a default implementation). More
+details can be found in the class's javadoc. \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
new file mode 100644
index 000000000000..52f0c4222b64
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
@@ -0,0 +1,69 @@
+# Debugging in the Shell
+
+---
+
+## Logging & ProtoLogs
+
+The interactions in the Shell can be pretty complicated, so having good logging is crucial to
+debugging problems that arise (especially in dogfood). The Shell uses the same efficient Protolog
+mechanism as WM Core, which can be enabled at runtime on debug devices.
+
+**TLDR**&nbsp; Don’t use Logs or Slogs except for error cases, Protologs are much more flexible,
+easy to add and easy to use
+
+### Adding a new ProtoLog
+Update `ShellProtoLogGroup` to include a new log group (ie. NEW_FEATURE) for the content you want to
+log. ProtoLog log calls mirror Log.v/d/e(), and take a format message and arguments:
+```java
+ProtoLog.v(NEW_FEATURE, "Test log w/ params: %d %s", 1, “a”)
+```
+This code itself will not compile by itself, but the `protologtool` will preprocess the file when
+building to check the log state (is enabled) before printing the print format style log.
+
+**Notes**
+- ProtoLogs currently only work from soong builds (ie. via make/mp). We need to reimplement the
+ tool for use with SysUI-studio
+- Non-text ProtoLogs are not currently supported with the Shell library (you can't view them with
+ traces in Winscope)
+
+### Enabling ProtoLog command line logging
+Run these commands to enable protologs for both WM Core and WM Shell to print to logcat.
+```shell
+adb shell wm logging enable-text NEW_FEATURE
+adb shell wm logging disable-text NEW_FEATURE
+```
+
+## Winscope Tracing
+
+The Winscope tool is extremely useful in determining what is happening on-screen in both
+WindowManager and SurfaceFlinger. Follow [go/winscope](http://go/winscope-help) to learn how to
+use the tool.
+
+In addition, there is limited preliminary support for Winscope tracing componetns in the Shell,
+which involves adding trace fields to [wm_shell_trace.proto](frameworks/base/libs/WindowManager/Shell/proto/wm_shell_trace.proto)
+file and ensure it is updated as a part of `WMShell#writeToProto`.
+
+Tracing can be started via the shell command (to be added to the Winscope tool as needed):
+```shell
+adb shell cmd statusbar tracing start
+adb shell cmd statusbar tracing stop
+```
+
+## Dumps
+
+Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a
+part of dumping the SystemUI service. Dumping the Shell specific data can be done by specifying the
+WMShell SysUI service:
+
+```shell
+adb shell dumpsys activity service SystemUIService WMShell
+```
+
+If information should be added to the dump, make updates to:
+- `WMShell` if you are dumping SysUI state
+- `ShellCommandHandler` if you are dumping Shell state
+
+## Debugging in Android Studio
+
+If you are using the [go/sysui-studio](http://go/sysui-studio) project, then you can debug Shell
+code directly from Android Studio like any other app.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
new file mode 100644
index 000000000000..061ae00e2b25
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
@@ -0,0 +1,13 @@
+# Extending the Shell for Products/OEMs
+
+---
+
+## General Do's & Dont's
+
+Do:
+- &nbsp;
+
+Don't
+- **Don't** override classes provided by WMShellBaseModule, it makes it difficult to make
+ simple changes to the Shell library base modules which are shared by all products
+ - If possible add mechanisms to modify the base class behavior \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
new file mode 100644
index 000000000000..a88ef6aea2ec
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
@@ -0,0 +1,58 @@
+# What is the WindowManager Shell
+
+---
+
+## Motivation
+
+The primary motivation for the WindowManager Shell (WMShell) library is to effectively scale
+WindowManager by making it easy&trade; and safe to create windowing features to fit the needs of
+various Android products and form factors.
+
+To achieve this, WindowManager separates the policy of managing windows (WMCore) from the
+presentation of surfaces (WMShell) and provides a minimal interface boundary for the two to
+communicate.
+
+## Who is using the library?
+
+Currently, the WMShell library is used to drive the windowing experience on handheld
+(phones & tablets), TV, Auto, Arc++, and Wear to varying degrees.
+
+## Where does the code live
+
+The core WMShell library code is currently located in the [frameworks/base/libs/WindowManager/Shell](frameworks/base/libs/WindowManager/Shell)
+directory and is included as a part dependency of the host SystemUI apk.
+
+## How do I build the Shell library
+
+The library can be built directly by running (using [go/makepush](http://go/makepush)):
+```shell
+mp :WindowManager-Shell
+```
+But this is mainly useful for inspecting the contents of the library or verifying it builds. The
+various targets can be found in the Shell library's [Android.bp](frameworks/base/libs/WindowManager/Shell/Android.bp)
+file.
+
+Normally, you would build it as a part of the host SystemUI, for example via commandline:
+```shell
+# Phone SystemUI variant
+mp sysuig
+# Building Shell & SysUI changes along w/ framework changes
+mp core services sysuig
+```
+
+Or preferably, if you are making WMShell/SysUI only changes (no other framework changes), then
+building via [go/sysui-studio](http://go/sysui-studio) allows for very quick iteration (one click
+build and push of SysUI in < 30s).
+
+If you are making framework changes and are using `aidegen` to set up your platform IDE, make sure
+to include the appropriate directories to build, for example:
+```shell
+# frameworks/base will include base/libs/WindowManager/Shell and base/packages/SystemUI
+aidegen frameworks/base \
+ vendor/<oem>/packages/SystemUI \
+ ...
+```
+
+## Other useful links
+- [go/o-o-summit-20](go/o-o-summit-20) (Video presentations from the WM team)
+- [go/o-o-summit-21](go/o-o-summit-21) \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
new file mode 100644
index 000000000000..68f970ff48df
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
@@ -0,0 +1,55 @@
+# Shell & SystemUI
+
+---
+
+## Setup
+
+The SystemUI of various products depend on and build against the WM Shell library. To ensure
+that we don't inadvertently build dependencies between the Shell library and one particular
+product (ie. handheld SysUI), we deliberately separate the initialization of the WM Shell
+component from the SysUI component when set up through Dagger.
+
+**TLDR**&nbsp; Initialize everything as needed in the WM component scope and export only well
+defined interfaces to SysUI.
+
+## Initialization
+
+There are more details in the Dagger docs, but the general overview of the SysUI/Shell
+initialization flow is such:
+
+1) SysUI Global scope is initialize (see `GlobalModule` and its included modules)
+2) WM Shell scope is initialized, for example
+ 1) On phones: `WMComponent` includes `WMShellModule` which includes `WMShellBaseModule`
+ (common to all SysUI)
+ 2) On TVs: `TvWMComponent` includes `TvWMShellModule` which includes `WMShellBaseModule`
+ 3) etc.
+3) SysUI explicitly passes interfaces provided from the `WMComponent` to `SysUIComponent` via
+ the `SysUIComponent#Builder`, then builds the SysUI scoped components
+4) `WMShell` is the SystemUI “service” (in the SysUI scope) that initializes with the app after the
+SystemUI part of the dependency graph has been created. It contains the binding code between the
+interfaces provided by the Shell and the rest of SystemUI.
+5) SysUI can inject the interfaces into its own components
+
+More detail can be found in [go/wm-sysui-dagger](http://go/wm-sysui-dagger).
+
+## Interfaces to Shell components
+
+Within the same process, the WM Shell components can be running on a different thread than the main
+SysUI thread (disabled on certain products). This introduces challenges where we have to be
+careful about how SysUI calls into the Shell and vice versa.
+
+As a result, we enforce explicit interfaces between SysUI and Shell components, and the
+implementations of the interfaces on each side need to post to the right thread before it calls
+into other code.
+
+For example, you might have:
+1) (Shell) ShellFeature interface to be used from SysUI
+2) (Shell) ShellFeatureController handles logic, implements ShellFeature interface and posts to
+ main Shell thread
+3) SysUI application init injects Optional<ShellFeature> as an interface to SysUI to call
+4) (SysUI) SysUIFeature depends on ShellFeature interface
+5) (SysUI) SysUIFeature injects Optional<ShellFeature>, and sets up a callback for the Shell to
+ call, and the callback posts to the main SysUI thread
+
+Adding an interface to a Shell component may seem like a lot of boiler plate, but is currently
+necessary to maintain proper threading and logic isolation. \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
new file mode 100644
index 000000000000..8a80333facc4
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
@@ -0,0 +1,49 @@
+# Testing
+
+---
+
+## Unit tests
+
+New WM Shell unit tests can be added to the
+[Shell/tests/unittest](frameworks/base/libs/WindowManager/Shell/tests/unittest) directory, and can
+be run via command line using `atest`:
+```shell
+atest WMShellUnitTests
+```
+
+If you use the SysUI Studio project, you can run and debug tests directly in the source files
+(click on the little arrows next to the test class or test method).
+
+These unit tests are run as a part of WindowManager presubmit, and the dashboards for these unit
+tests tests can be found at [go/wm-tests](http://go/wm-tests).
+
+This [GCL file](http://go/wm-unit-tests-gcl) configures the tests being run on the server.
+
+## Flicker tests
+
+Flicker tests are tests that perform actions and make assertions on the state in Window Manager
+and SurfaceFlinger traces captured during the run.
+
+New WM Shell Flicker tests can be added to the
+[Shell/tests/flicker](frameworks/base/libs/WindowManager/Shell/tests/flicker) directory, and can
+be run via command line using `atest`:
+```shell
+atest WMShellFlickerTests
+```
+
+**Note**: Currently Flicker tests can only be run from the commandline and not via SysUI Studio
+
+A subset of the flicker tests tests are run as a part of WindowManager presubmit, and the
+dashboards for these tests tests can be found at [go/wm-tests-flicker](http://go/wm-tests-flicker).
+
+## CTS tests
+
+Some windowing features also have CTS tests to ensure consistent behavior across OEMs. For example:
+- Picture-in-Picture:
+ [PinnedStackTests](cts/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java)
+- etc.
+
+These can also be run via commandline only using `atest`, for example:
+```shell
+atest PinnedStackTests
+``` \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
new file mode 100644
index 000000000000..eac748894432
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
@@ -0,0 +1,83 @@
+# Threading
+
+---
+
+## Boundaries
+
+```text
+ Thread boundary
+ |
+ WM Shell | SystemUI
+ |
+ |
+FeatureController <-> FeatureInterface <--|--> WMShell <-> SysUI
+ | (^post to shell thread) | (^post to main thread)
+ ... |
+ | |
+ OtherControllers |
+```
+
+## Threads
+
+We currently have multiple threads in use in the Shell library depending on the configuration by
+the product.
+- SysUI main thread (standard main thread)
+- `ShellMainThread` (only used if the resource `config_enableShellMainThread` is set true
+ (ie. phones))
+ - This falls back to the SysUI main thread otherwise
+ - **Note**:
+ - This thread runs with `THREAD_PRIORITY_DISPLAY` priority since so many windowing-critical
+ components depend on it
+ - This is also the UI thread for almost all UI created by the Shell
+ - The Shell main thread Handler (and the Executor that wraps it) is async, so
+ messages/runnables used via this Handler are handled immediately if there is no sync
+ messages prior to it in the queue.
+- `ShellBackgroundThread` (for longer running tasks where we don't want to block the shell main
+ thread)
+ - This is always another thread even if config_enableShellMainThread is not set true
+ - **Note**:
+ - This thread runs with `THREAD_PRIORITY_BACKGROUND` priority
+- `ShellAnimationThread` (currently only used for Transitions and Splitscreen, but potentially all
+ animations could be offloaded here)
+- `ShellSplashScreenThread` (only for use with splashscreens)
+
+## Dagger setup
+
+The threading-related components are provided by the [WMShellConcurrencyModule](frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java),
+for example, the Executors and Handlers for the various threads that are used. You can request
+an executor of the necessary type by using the appropriate annotation for each of the threads (ie.
+`@ShellMainThread Executor`) when injecting into your Shell component.
+
+To get the SysUI main thread, you can use the `@Main` annotation.
+
+## Best practices
+
+### Components
+- Don't do initialization in the Shell component constructors
+ - If the host SysUI is not careful, it may construct the WMComponent dependencies on the main
+ thread, and this reduces the likelihood that components will intiailize on the wrong thread
+ in such cases
+- Be careful of using CountDownLatch and other blocking synchronization mechanisms in Shell code
+ - If the Shell main thread is not a separate thread, this will cause a deadlock
+- Callbacks, Observers, Listeners to any non-shell component should post onto main Shell thread
+ - This includes Binder calls, SysUI calls, BroadcastReceivers, etc. Basically any API that
+ takes a runnable should either be registered with the right Executor/Handler or posted to
+ the main Shell thread manually
+- Since everything in the Shell runs on the main Shell thread, you do **not** need to explicitly
+ `synchronize` your code (unless you are trying to prevent reentrantcy, but that can also be
+ done in other ways)
+
+### Handlers/Executors
+- You generally **never** need to create Handlers explicitly, instead inject `@ShellMainThread
+ ShellExecutor` instead
+ - This is a common pattern to defer logic in UI code, but the Handler created wraps the Looper
+ that is currently running, which can be wrong (see above for initialization vs construction)
+- That said, sometimes Handlers are necessary because Framework API only takes Handlers or you
+ want to dedupe multiple messages
+ - In such cases inject `@ShellMainThread Handler` or use view.getHandler() which should be OK
+ assuming that the view root was initialized on the main Shell thread
+- **Never use Looper.getMainLooper()**
+ - It's likely going to be wrong, you can inject `@Main ShellExecutor` to get the SysUI main thread
+
+### Testing
+- You can use a `TestShellExecutor` to control the processing of messages \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
index 16f1d1c2944c..000624499f79 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
@@ -26,11 +26,14 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.RemoteAction;
+import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.view.SurfaceControl;
import android.view.WindowManager;
+import com.android.wm.shell.R;
+
import java.util.List;
/**
@@ -97,16 +100,20 @@ public interface PipMenuController {
/**
* Returns a default LayoutParams for the PIP Menu.
+ * @param context the context.
* @param width the PIP stack width.
* @param height the PIP stack height.
*/
- default WindowManager.LayoutParams getPipMenuLayoutParams(String title, int width, int height) {
+ default WindowManager.LayoutParams getPipMenuLayoutParams(Context context, String title,
+ int width, int height) {
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
TYPE_APPLICATION_OVERLAY,
FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY | FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
lp.setTitle(title);
+ lp.accessibilityTitle = context.getResources().getString(
+ R.string.pip_menu_accessibility_title);
return lp;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 05a890fc65ed..51be2a534dd7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -315,7 +315,7 @@ public class PipTransition extends PipTransitionController {
}
@Override
- public void onTransitionMerged(@NonNull IBinder transition) {
+ public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
if (transition != mExitTransition) {
return;
}
@@ -328,7 +328,7 @@ public class PipTransition extends PipTransitionController {
}
// Unset exitTransition AFTER cancel so that finishResize knows we are merging.
mExitTransition = null;
- if (!cancelled) return;
+ if (!cancelled || aborted) return;
final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo();
if (taskInfo != null) {
startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 4942987742a0..504dc02eb570 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -181,7 +181,7 @@ public class PhonePipMenuController implements PipMenuController {
mPipMenuView = new PipMenuView(mContext, this, mMainExecutor, mMainHandler,
mSplitScreenController, mPipUiEventLogger);
mSystemWindows.addView(mPipMenuView,
- getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
+ getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
0, SHELL_ROOT_LAYER_PIP);
setShellRootAccessibilityWindow();
@@ -206,7 +206,7 @@ public class PhonePipMenuController implements PipMenuController {
@Override
public void updateMenuBounds(Rect destinationBounds) {
mSystemWindows.updateViewLayout(mPipMenuView,
- getPipMenuLayoutParams(MENU_WINDOW_TITLE, destinationBounds.width(),
+ getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, destinationBounds.width(),
destinationBounds.height()));
updateMenuLayout(destinationBounds);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index c6f7974e43bc..a4e9062436da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -193,8 +193,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
}
private void addPipMenuViewToSystemWindows(View v, String title) {
- mSystemWindows.addView(v, getPipMenuLayoutParams(title, 0 /* width */, 0 /* height */),
- 0 /* displayId */, SHELL_ROOT_LAYER_PIP);
+ mSystemWindows.addView(v, getPipMenuLayoutParams(mContext, title, 0 /* width */,
+ 0 /* height */), 0 /* displayId */, SHELL_ROOT_LAYER_PIP);
}
void notifyPipAnimating(boolean animating) {
@@ -572,10 +572,10 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
"%s: updateMenuBounds: %s", TAG, menuBounds.toShortString());
}
mSystemWindows.updateViewLayout(mPipBackgroundView,
- getPipMenuLayoutParams(BACKGROUND_WINDOW_TITLE, menuBounds.width(),
+ getPipMenuLayoutParams(mContext, BACKGROUND_WINDOW_TITLE, menuBounds.width(),
menuBounds.height()));
mSystemWindows.updateViewLayout(mPipMenuView,
- getPipMenuLayoutParams(MENU_WINDOW_TITLE, menuBounds.width(),
+ getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, menuBounds.width(),
menuBounds.height()));
if (mPipMenuView != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index d04c34916256..e31e0d674bec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -26,6 +26,8 @@ import com.android.internal.protolog.common.IProtoLogGroup;
public enum ShellProtoLogGroup implements IProtoLogGroup {
// NOTE: Since we enable these from the same WM ShellCommand, these names should not conflict
// with those in the framework ProtoLogGroup
+ WM_SHELL_INIT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
+ Consts.TAG_WM_SHELL),
WM_SHELL_TASK_ORG(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM_SHELL),
WM_SHELL_TRANSITIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
@@ -38,8 +40,8 @@ public enum ShellProtoLogGroup implements IProtoLogGroup {
"ShellBackPreview"),
WM_SHELL_RECENT_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM_SHELL),
- WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG,
- false, Consts.TAG_WM_SHELL),
+ WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM_SHELL),
WM_SHELL_SPLIT_SCREEN(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM_SHELL),
TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest");
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 e7ec15e70c11..b0080b24c609 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
@@ -45,6 +45,11 @@ class MainStage extends StageTaskListener {
iconProvider);
}
+ @Override
+ void dismiss(WindowContainerTransaction wct, boolean toTop) {
+ deactivate(wct, toTop);
+ }
+
boolean isActive() {
return mIsActive;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index 8639b36faf4c..86efbe0af79c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -42,6 +42,11 @@ class SideStage extends StageTaskListener {
iconProvider);
}
+ @Override
+ void dismiss(WindowContainerTransaction wct, boolean toTop) {
+ removeAllTasks(wct, toTop);
+ }
+
boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
if (mChildrenTaskInfo.size() == 0) return false;
wct.reparentTasks(
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 47bfaa64c831..21bea4674805 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
@@ -18,16 +18,12 @@ package com.android.wm.shell.splitscreen;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
-import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
-import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -66,7 +62,6 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -104,18 +99,18 @@ import java.util.concurrent.Executor;
*/
// TODO(b/198577848): Implement split screen flicker test to consolidate CUJ of split screen.
public class SplitScreenController implements DragAndDropPolicy.Starter,
- RemoteCallable<SplitScreenController>, ShellTaskOrganizer.FocusListener {
+ RemoteCallable<SplitScreenController> {
private static final String TAG = SplitScreenController.class.getSimpleName();
- static final int EXIT_REASON_UNKNOWN = 0;
- static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1;
- static final int EXIT_REASON_APP_FINISHED = 2;
- static final int EXIT_REASON_DEVICE_FOLDED = 3;
- static final int EXIT_REASON_DRAG_DIVIDER = 4;
- static final int EXIT_REASON_RETURN_HOME = 5;
- static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
- static final int EXIT_REASON_SCREEN_LOCKED = 7;
- static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
+ public static final int EXIT_REASON_UNKNOWN = 0;
+ public static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1;
+ public static final int EXIT_REASON_APP_FINISHED = 2;
+ public static final int EXIT_REASON_DEVICE_FOLDED = 3;
+ public static final int EXIT_REASON_DRAG_DIVIDER = 4;
+ public static final int EXIT_REASON_RETURN_HOME = 5;
+ public static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
+ public static final int EXIT_REASON_SCREEN_LOCKED = 7;
+ public static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9;
@IntDef(value = {
EXIT_REASON_UNKNOWN,
@@ -152,8 +147,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
// outside the bounds of the roots by being reparented into a higher level fullscreen container
private SurfaceControl mSplitTasksContainerLayer;
- private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
-
public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
SyncTransactionQueue syncQueue, Context context,
RootTaskDisplayAreaOrganizer rootTDAOrganizer,
@@ -175,7 +168,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
mLogger = new SplitscreenEventLogger();
mIconProvider = iconProvider;
mRecentTasksOptional = recentTasks;
- mTaskOrganizer.addFocusListener(this);
}
public SplitScreen asSplitScreen() {
@@ -192,11 +184,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return mMainExecutor;
}
- @Override
- public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
- mFocusingTaskInfo = taskInfo;
- }
-
public void onOrganizerRegistered() {
if (mStageCoordinator == null) {
// TODO: Multi-display
@@ -215,6 +202,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return mStageCoordinator;
}
+ public ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
+ return mStageCoordinator.getFocusingTaskInfo();
+ }
+
+ public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+ return mStageCoordinator.isValidToEnterSplitScreen(taskInfo);
+ }
+
@Nullable
public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
@@ -230,12 +225,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
&& mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
}
- public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
- return taskInfo.supportsMultiWindow
- && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
- && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
- }
-
public @SplitPosition int getSplitPosition(int taskId) {
return mStageCoordinator.getSplitPosition(taskId);
}
@@ -472,8 +461,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
return Objects.equals(launchingActivity, pairedActivity);
}
- if (mFocusingTaskInfo != null && isValidToEnterSplitScreen(mFocusingTaskInfo)) {
- return Objects.equals(mFocusingTaskInfo.baseIntent.getComponent(), launchingActivity);
+ final ActivityManager.RunningTaskInfo taskInfo = getFocusingTaskInfo();
+ if (taskInfo != null && isValidToEnterSplitScreen(taskInfo)) {
+ return Objects.equals(taskInfo.baseIntent.getComponent(), launchingActivity);
}
return false;
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
index e55729a883e0..056cd5813861 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -246,7 +246,9 @@ class SplitScreenTransitions {
return true;
}
- void onTransitionMerged(@NonNull IBinder transition) {
+ void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
+ if (aborted) return;
+
// Once a pending enter transition got merged, make sure to append the reset of finishing
// operations to the finish transition.
if (transition == mPendingEnter) {
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 e19c572c4850..2229e26b9343 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
@@ -35,6 +35,8 @@ import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -98,6 +100,7 @@ import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.InstanceId;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -138,7 +141,7 @@ import java.util.Optional;
*/
public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler,
- ShellTaskOrganizer.TaskListener {
+ ShellTaskOrganizer.TaskListener, ShellTaskOrganizer.FocusListener {
private static final String TAG = StageCoordinator.class.getSimpleName();
@@ -176,6 +179,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private final Rect mTempRect1 = new Rect();
private final Rect mTempRect2 = new Rect();
+ private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
+
/**
* A single-top root task which the split divider attached to.
*/
@@ -189,6 +194,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private boolean mShouldUpdateRecents;
private boolean mExitSplitScreenOnHide;
private boolean mIsDividerRemoteAnimating;
+ private boolean mIsExiting;
private boolean mResizingSplits;
/** The target stage to dismiss to when unlock after folded. */
@@ -254,6 +260,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mDisplayController.addDisplayWindowListener(this);
mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
transitions.addHandler(this);
+ mTaskOrganizer.addFocusListener(this);
}
@VisibleForTesting
@@ -442,7 +449,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
new IRemoteAnimationFinishedCallback.Stub() {
@Override
public void onAnimationFinished() throws RemoteException {
- onRemoteAnimationFinishedOrCancelled(evictWct);
+ onRemoteAnimationFinishedOrCancelled(false /* cancel */, evictWct);
finishedCallback.onAnimationFinished();
}
};
@@ -463,7 +470,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public void onAnimationCancelled(boolean isKeyguardOccluded) {
- onRemoteAnimationFinishedOrCancelled(evictWct);
+ onRemoteAnimationFinishedOrCancelled(true /* cancel */, evictWct);
try {
adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
} catch (RemoteException e) {
@@ -513,13 +520,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
});
}
- private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
+ private void onRemoteAnimationFinishedOrCancelled(boolean cancel,
+ WindowContainerTransaction evictWct) {
mIsDividerRemoteAnimating = false;
mShouldUpdateRecents = true;
// If any stage has no child after animation finished, it means that split will display
// nothing, such status will happen if task and intent is same app but not support
// multi-instagce, we should exit split and expand that app as full screen.
- if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
+ if (!cancel && (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
mMainExecutor.execute(() ->
exitSplitScreen(mMainStage.getChildCount() == 0
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
@@ -733,7 +741,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void applyExitSplitScreen(@Nullable StageTaskListener childrenToTop,
WindowContainerTransaction wct, @ExitReason int exitReason) {
- if (!mMainStage.isActive()) return;
+ if (!mMainStage.isActive() || mIsExiting) return;
mRecentTasks.ifPresent(recentTasks -> {
// Notify recents if we are exiting in a way that breaks the pair, and disable further
@@ -745,21 +753,45 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
});
mShouldUpdateRecents = false;
- // When the exit split-screen is caused by one of the task enters auto pip,
- // we want the tasks to be put to bottom instead of top, otherwise it will end up
- // a fullscreen plus a pinned task instead of pinned only at the end of the transition.
- final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP;
- mSideStage.removeAllTasks(wct, !fromEnteringPip && mSideStage == childrenToTop);
- mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop);
- wct.reorder(mRootTaskInfo.token, false /* onTop */);
- mTaskOrganizer.applyTransaction(wct);
+ if (childrenToTop == null) {
+ mSideStage.removeAllTasks(wct, false /* toTop */);
+ mMainStage.deactivate(wct, false /* toTop */);
+ wct.reorder(mRootTaskInfo.token, false /* onTop */);
+ onTransitionAnimationComplete();
+ } else {
+ // Expand to top side split as full screen for fading out decor animation and dismiss
+ // another side split(Moving its children to bottom).
+ mIsExiting = true;
+ final StageTaskListener tempFullStage = childrenToTop;
+ final StageTaskListener dismissStage = mMainStage == childrenToTop
+ ? mSideStage : mMainStage;
+ tempFullStage.resetBounds(wct);
+ wct.setSmallestScreenWidthDp(tempFullStage.mRootTaskInfo.token,
+ mRootTaskInfo.configuration.smallestScreenWidthDp);
+ dismissStage.dismiss(wct, false /* toTop */);
+ }
+ mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
t.setWindowCrop(mMainStage.mRootLeash, null)
.setWindowCrop(mSideStage.mRootLeash, null);
+ t.setPosition(mMainStage.mRootLeash, 0, 0)
+ .setPosition(mSideStage.mRootLeash, 0, 0);
setDividerVisibility(false, t);
+
+ // In this case, exit still under progress, fade out the split decor after first WCT
+ // done and do remaining WCT after animation finished.
+ if (childrenToTop != null) {
+ childrenToTop.fadeOutDecor(() -> {
+ WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
+ mIsExiting = false;
+ childrenToTop.dismiss(finishedWCT, true /* toTop */);
+ wct.reorder(mRootTaskInfo.token, false /* toTop */);
+ mTaskOrganizer.applyTransaction(finishedWCT);
+ onTransitionAnimationComplete();
+ });
+ }
});
- onTransitionAnimationComplete();
Slog.i(TAG, "applyExitSplitScreen, reason = " + exitReasonToString(exitReason));
// Log the exit
if (childrenToTop != null) {
@@ -929,9 +961,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
- private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) {
- exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage,
- EXIT_REASON_CHILD_TASK_ENTER_PIP);
+ private void onStageChildTaskEnterPip() {
+ // When the exit split-screen is caused by one of the task enters auto pip,
+ // we want both tasks to be put to bottom instead of top, otherwise it will end up
+ // a fullscreen plus a pinned task instead of pinned only at the end of the transition.
+ exitSplitScreen(null, EXIT_REASON_CHILD_TASK_ENTER_PIP);
}
private void updateRecentTasksSplitPair() {
@@ -1177,21 +1211,42 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
final boolean hasChildren = stageListener.mHasChildren;
final boolean isSideStage = stageListener == mSideStageListener;
- if (!hasChildren) {
+ if (!hasChildren && !mIsExiting) {
if (isSideStage && mMainStageListener.mVisible) {
// Exit to main stage if side stage no longer has children.
- exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
+ if (ENABLE_SHELL_TRANSITIONS) {
+ exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
+ } else {
+ mSplitLayout.flingDividerToDismiss(
+ mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ EXIT_REASON_APP_FINISHED);
+ }
} else if (!isSideStage && mSideStageListener.mVisible) {
// Exit to side stage if main stage no longer has children.
- exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
+ if (ENABLE_SHELL_TRANSITIONS) {
+ exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
+ } else {
+ mSplitLayout.flingDividerToDismiss(
+ mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ EXIT_REASON_APP_FINISHED);
+ }
}
} else if (isSideStage && !mMainStage.isActive()) {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- mSplitLayout.init();
- prepareEnterSplitScreen(wct);
- mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t ->
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
+ if (mFocusingTaskInfo != null && !isValidToEnterSplitScreen(mFocusingTaskInfo)) {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ mSideStage.removeAllTasks(wct, true);
+ wct.reorder(mRootTaskInfo.token, false /* onTop */);
+ mTaskOrganizer.applyTransaction(wct);
+ Slog.i(TAG, "cancel entering split screen, reason = "
+ + exitReasonToString(EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW));
+ } else {
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ mSplitLayout.init();
+ prepareEnterSplitScreen(wct);
+ mSyncQueue.queue(wct);
+ mSyncQueue.runInSync(t ->
+ updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
+ }
}
if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) {
mShouldUpdateRecents = true;
@@ -1206,13 +1261,28 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
+ boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+ return taskInfo.supportsMultiWindow
+ && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+ && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
+ }
+
+ ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
+ return mFocusingTaskInfo;
+ }
+
@Override
- public void onSnappedToDismiss(boolean bottomOrRight) {
+ public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ mFocusingTaskInfo = taskInfo;
+ }
+
+ @Override
+ public void onSnappedToDismiss(boolean bottomOrRight, int reason) {
final boolean mainStageToTop =
bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
: mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
if (!ENABLE_SHELL_TRANSITIONS) {
- exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, EXIT_REASON_DRAG_DIVIDER);
+ exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, reason);
return;
}
@@ -1534,8 +1604,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
@Override
- public void onTransitionMerged(@NonNull IBinder transition) {
- mSplitTransitions.onTransitionMerged(transition);
+ public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
+ mSplitTransitions.onTransitionConsumed(transition, aborted);
}
@Override
@@ -1614,7 +1684,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
/** Called to clean-up state and do house-keeping after the animation is done. */
public void onTransitionAnimationComplete() {
// If still playing, let it finish.
- if (!mMainStage.isActive()) {
+ if (!mMainStage.isActive() && !mIsExiting) {
// Update divider state after animation so that it is still around and positioned
// properly for the animation itself.
mSplitLayout.release();
@@ -1910,8 +1980,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
@Override
- public void onChildTaskEnterPip(int taskId) {
- StageCoordinator.this.onStageChildTaskEnterPip(this, taskId);
+ public void onChildTaskEnterPip() {
+ StageCoordinator.this.onStageChildTaskEnterPip();
}
@Override
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 d17ff7aff667..f6dc68be946a 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
@@ -71,7 +71,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
- void onChildTaskEnterPip(int taskId);
+ void onChildTaskEnterPip();
void onRootTaskVanished();
@@ -103,6 +103,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
}
+ /**
+ * General function for dismiss this stage.
+ */
+ void dismiss(WindowContainerTransaction wct, boolean toTop) {}
+
int getChildCount() {
return mChildrenTaskInfo.size();
}
@@ -255,7 +260,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
return;
}
if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
- mCallbacks.onChildTaskEnterPip(taskId);
+ mCallbacks.onChildTaskEnterPip();
}
sendStatusChanged();
} else {
@@ -297,6 +302,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
}
+ void fadeOutDecor(Runnable finishedCallback) {
+ if (mSplitDecorManager != null) {
+ mSplitDecorManager.fadeOutDecor(finishedCallback);
+ } else {
+ finishedCallback.run();
+ }
+ }
+
void addTask(ActivityManager.RunningTaskInfo task, WindowContainerTransaction wct) {
// Clear overridden bounds and windowing mode to make sure the child task can inherit
// windowing mode and bounds from split root.
@@ -330,6 +343,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
}
+ void resetBounds(WindowContainerTransaction wct) {
+ wct.setBounds(mRootTaskInfo.token, null);
+ wct.setAppBounds(mRootTaskInfo.token, null);
+ }
+
void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
@StageType int stage) {
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 7234d559e153..11b453cb24a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -274,7 +274,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
}
@Override
- public void onTransitionMerged(@NonNull IBinder transition) {
+ public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
MixedTransition mixed = null;
for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
if (mActiveTransitions.get(i).mTransition != transition) continue;
@@ -283,7 +283,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
}
if (mixed == null) return;
if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
- mPipHandler.onTransitionMerged(transition);
+ mPipHandler.onTransitionConsumed(transition, aborted);
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
index 3e2a0e635a75..ebaece2189aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
@@ -99,6 +99,8 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
+ " during unit tests");
}
mRemote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
+ // assume that remote will apply the start transaction.
+ startTransaction.clear();
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);
if (mRemote.asBinder() != null) {
@@ -120,6 +122,11 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
@Override
public void onTransitionFinished(WindowContainerTransaction wct,
SurfaceControl.Transaction sct) {
+ // We have merged, since we sent the transaction over binder, the one in this
+ // process won't be cleared if the remote applied it. We don't actually know if the
+ // remote applied the transaction, but applying twice will break surfaceflinger
+ // so just assume the worst-case and clear the local transaction.
+ t.clear();
mMainExecutor.execute(
() -> finishCallback.onTransitionFinished(wct, null /* wctCB */));
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
index ece9f47e8788..b15c48cb5889 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -83,7 +83,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
}
@Override
- public void onTransitionMerged(@NonNull IBinder transition) {
+ public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) {
mRequestedRemotes.remove(transition);
}
@@ -139,6 +139,8 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
+ " during unit tests");
}
remote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
+ // assume that remote will apply the start transaction.
+ startTransaction.clear();
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);
unhandleDeath(remote.asBinder(), finishCallback);
@@ -162,6 +164,11 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
@Override
public void onTransitionFinished(WindowContainerTransaction wct,
SurfaceControl.Transaction sct) {
+ // We have merged, since we sent the transaction over binder, the one in this
+ // process won't be cleared if the remote applied it. We don't actually know if the
+ // remote applied the transaction, but applying twice will break surfaceflinger
+ // so just assume the worst-case and clear the local transaction.
+ t.clear();
mMainExecutor.execute(() -> {
if (!mRequestedRemotes.containsKey(mergeTarget)) {
Log.e(TAG, "Merged transition finished after it's mergeTarget (the "
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 de0f47fa0a6b..fa22c7ca94d2 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
@@ -516,15 +516,20 @@ public class Transitions implements RemoteCallable<Transitions> {
active.mMerged = true;
active.mAborted = abort;
if (active.mHandler != null) {
- active.mHandler.onTransitionMerged(active.mToken);
+ active.mHandler.onTransitionConsumed(active.mToken, abort);
}
return;
}
- mActiveTransitions.get(activeIdx).mAborted = abort;
+ final ActiveTransition active = mActiveTransitions.get(activeIdx);
+ active.mAborted = abort;
+ if (active.mAborted && active.mHandler != null) {
+ // Notifies to clean-up the aborted transition.
+ active.mHandler.onTransitionConsumed(transition, true /* aborted */);
+ }
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
"Transition animation finished (abort=%b), notifying core %s", abort, transition);
// Merge all relevant transactions together
- SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT;
+ SurfaceControl.Transaction fullFinish = active.mFinishT;
for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) {
final ActiveTransition toMerge = mActiveTransitions.get(iA);
if (!toMerge.mMerged) break;
@@ -553,6 +558,10 @@ public class Transitions implements RemoteCallable<Transitions> {
while (mActiveTransitions.size() > activeIdx
&& mActiveTransitions.get(activeIdx).mAborted) {
ActiveTransition aborted = mActiveTransitions.remove(activeIdx);
+ // Notifies to clean-up the aborted transition.
+ if (aborted.mHandler != null) {
+ aborted.mHandler.onTransitionConsumed(transition, true /* aborted */);
+ }
mOrganizer.finishTransition(aborted.mToken, null /* wct */, null /* wctCB */);
}
if (mActiveTransitions.size() <= activeIdx) {
@@ -735,9 +744,10 @@ public class Transitions implements RemoteCallable<Transitions> {
/**
* Called when a transition which was already "claimed" by this handler has been merged
- * into another animation. Gives this handler a chance to clean-up any expectations.
+ * into another animation or has been aborted. Gives this handler a chance to clean-up any
+ * expectations.
*/
- default void onTransitionMerged(@NonNull IBinder transition) { }
+ default void onTransitionConsumed(@NonNull IBinder transition, boolean aborted) { }
/**
* Sets transition animation scale settings value to handler.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
new file mode 100644
index 000000000000..1c587a2078cf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Presubmit
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.entireScreenCovered
+import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtStartAndEnd
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import org.junit.Assume
+import org.junit.Test
+
+/**
+ * Base test class containing common assertions for [ComponentMatcher.NAV_BAR],
+ * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions
+ * (layers visible in consecutive states, entire screen covered, etc.)
+ */
+abstract class BaseTest @JvmOverloads constructor(
+ protected val testSpec: FlickerTestParameter,
+ protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
+ protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
+) {
+ init {
+ testSpec.setIsTablet(
+ WindowManagerStateHelper(instrumentation).currentState.wmState.isTablet
+ )
+ }
+
+ /**
+ * Specification of the test transition to execute
+ */
+ abstract val transition: FlickerBuilder.() -> Unit
+
+ /**
+ * Entry point for the test runner. It will use this method to initialize and cache
+ * flicker executions
+ */
+ @FlickerBuilderProvider
+ fun buildFlicker(): FlickerBuilder {
+ return FlickerBuilder(instrumentation).apply {
+ setup {
+ test {
+ testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet)
+ }
+ }
+ transition()
+ }
+ }
+
+ /**
+ * Checks that all parts of the screen are covered during the transition
+ */
+ open fun entireScreenCovered() = testSpec.entireScreenCovered()
+
+ /**
+ * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition
+ */
+ @Presubmit
+ @Test
+ open fun navBarLayerIsVisibleAtStartAndEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerIsVisibleAtStartAndEnd()
+ }
+
+ /**
+ * Checks the position of the [ComponentMatcher.NAV_BAR] at the start and end of the transition
+ */
+ @Presubmit
+ @Test
+ open fun navBarLayerPositionAtStartAndEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerPositionAtStartAndEnd()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.NAV_BAR] window is visible during the whole transition
+ *
+ * Note: Phones only
+ */
+ @Presubmit
+ @Test
+ open fun navBarWindowIsAlwaysVisible() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarWindowIsAlwaysVisible()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition
+ */
+ @Presubmit
+ @Test
+ open fun taskBarLayerIsVisibleAtStartAndEnd() {
+ Assume.assumeTrue(testSpec.isTablet)
+ testSpec.taskBarLayerIsVisibleAtStartAndEnd()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.TASK_BAR] window is visible during the whole transition
+ *
+ * Note: Large screen only
+ */
+ @Presubmit
+ @Test
+ open fun taskBarWindowIsAlwaysVisible() {
+ Assume.assumeTrue(testSpec.isTablet)
+ testSpec.taskBarWindowIsAlwaysVisible()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible during the whole transition
+ */
+ @Presubmit
+ @Test
+ open fun statusBarLayerIsVisibleAtStartAndEnd() =
+ testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /**
+ * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the transition
+ */
+ @Presubmit
+ @Test
+ open fun statusBarLayerPositionAtStartAndEnd() = testSpec.statusBarLayerPositionAtStartAndEnd()
+
+ /**
+ * Checks that the [ComponentMatcher.STATUS_BAR] window is visible during the whole transition
+ */
+ @Presubmit
+ @Test
+ open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
+
+ /**
+ * Checks that all layers that are visible on the trace, are visible for at least 2
+ * consecutive entries.
+ */
+ @Presubmit
+ @Test
+ open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ testSpec.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry()
+ }
+ }
+
+ /**
+ * Checks that all windows that are visible on the trace, are visible for at least 2
+ * consecutive entries.
+ */
+ @Presubmit
+ @Test
+ open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ testSpec.assertWm {
+ this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index cba396a82a87..c1d743b4e9e8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -20,7 +20,7 @@ package com.android.wm.shell.flicker
import android.view.Surface
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.common.region.Region
fun FlickerTestParameter.appPairsDividerIsVisibleAtEnd() {
@@ -48,7 +48,7 @@ fun FlickerTestParameter.splitScreenDividerBecomesVisible() {
}
fun FlickerTestParameter.layerBecomesVisible(
- component: FlickerComponentName
+ component: IComponentMatcher
) {
assertLayers {
this.isInvisible(component)
@@ -58,7 +58,7 @@ fun FlickerTestParameter.layerBecomesVisible(
}
fun FlickerTestParameter.layerIsVisibleAtEnd(
- component: FlickerComponentName
+ component: IComponentMatcher
) {
assertLayersEnd {
this.isVisible(component)
@@ -67,7 +67,7 @@ fun FlickerTestParameter.layerIsVisibleAtEnd(
fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible(
rotation: Int,
- component: FlickerComponentName,
+ component: IComponentMatcher,
splitLeftTop: Boolean
) {
assertLayers {
@@ -88,7 +88,7 @@ fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible(
fun FlickerTestParameter.splitAppLayerBoundsIsVisibleAtEnd(
rotation: Int,
- component: FlickerComponentName,
+ component: IComponentMatcher,
splitLeftTop: Boolean
) {
assertLayersEnd {
@@ -104,7 +104,7 @@ fun FlickerTestParameter.splitAppLayerBoundsIsVisibleAtEnd(
}
fun FlickerTestParameter.appWindowBecomesVisible(
- component: FlickerComponentName
+ component: IComponentMatcher
) {
assertWm {
this.isAppWindowInvisible(component)
@@ -114,7 +114,7 @@ fun FlickerTestParameter.appWindowBecomesVisible(
}
fun FlickerTestParameter.appWindowIsVisibleAtEnd(
- component: FlickerComponentName
+ component: IComponentMatcher
) {
assertWmEnd {
this.isAppWindowVisible(component)
@@ -151,7 +151,7 @@ fun FlickerTestParameter.dockedStackDividerNotExistsAtEnd() {
fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd(
rotation: Int,
- primaryComponent: FlickerComponentName
+ primaryComponent: IComponentMatcher
) {
assertLayersEnd {
val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region
@@ -162,7 +162,7 @@ fun FlickerTestParameter.appPairsPrimaryBoundsIsVisibleAtEnd(
fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd(
rotation: Int,
- primaryComponent: FlickerComponentName
+ primaryComponent: IComponentMatcher
) {
assertLayersEnd {
val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region
@@ -173,7 +173,7 @@ fun FlickerTestParameter.dockedStackPrimaryBoundsIsVisibleAtEnd(
fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd(
rotation: Int,
- secondaryComponent: FlickerComponentName
+ secondaryComponent: IComponentMatcher
) {
assertLayersEnd {
val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region
@@ -184,7 +184,7 @@ fun FlickerTestParameter.appPairsSecondaryBoundsIsVisibleAtEnd(
fun FlickerTestParameter.dockedStackSecondaryBoundsIsVisibleAtEnd(
rotation: Int,
- secondaryComponent: FlickerComponentName
+ secondaryComponent: IComponentMatcher
) {
assertLayersEnd {
val dividerRegion = layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index f56eb6e783aa..3708e5f65485 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -17,9 +17,9 @@
@file:JvmName("CommonConstants")
package com.android.wm.shell.flicker
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
-val APP_PAIR_SPLIT_DIVIDER_COMPONENT = FlickerComponentName("", "AppPairSplitDivider#")
-val DOCKED_STACK_DIVIDER_COMPONENT = FlickerComponentName("", "DockedStackDivider#")
-val SPLIT_SCREEN_DIVIDER_COMPONENT = FlickerComponentName("", "StageCoordinatorSplitDivider#")
+val APP_PAIR_SPLIT_DIVIDER_COMPONENT = ComponentMatcher("", "AppPairSplitDivider#")
+val DOCKED_STACK_DIVIDER_COMPONENT = ComponentMatcher("", "DockedStackDivider#")
+val SPLIT_SCREEN_DIVIDER_COMPONENT = ComponentMatcher("", "StageCoordinatorSplitDivider#")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
index 5b073038059c..67d7aca8db8c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
@@ -17,41 +17,38 @@
package com.android.wm.shell.flicker.bubble
import android.app.INotificationManager
-import android.app.Instrumentation
import android.app.NotificationManager
import android.content.Context
import android.os.ServiceManager
import android.view.Surface
-import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.Flicker
-import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SYSTEMUI_PACKAGE
+import com.android.wm.shell.flicker.BaseTest
import com.android.wm.shell.flicker.helpers.LaunchBubbleHelper
import org.junit.runners.Parameterized
/**
* Base configurations for Bubble flicker tests
*/
-abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) {
+abstract class BaseBubbleScreen(
+ testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
- protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
protected val context: Context = instrumentation.context
protected val testApp = LaunchBubbleHelper(instrumentation)
- protected val notifyManager = INotificationManager.Stub.asInterface(
+ private val notifyManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE))
- protected val uid = context.packageManager.getApplicationInfo(
+ private val uid = context.packageManager.getApplicationInfo(
testApp.`package`, 0).uid
- protected abstract val transition: FlickerBuilder.() -> Unit
-
@JvmOverloads
protected open fun buildTransition(
extraSpec: FlickerBuilder.() -> Unit = {}
@@ -60,7 +57,7 @@ abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) {
setup {
test {
notifyManager.setBubblesAllowed(testApp.`package`,
- uid, NotificationManager.BUBBLE_PREFERENCE_ALL)
+ uid, NotificationManager.BUBBLE_PREFERENCE_ALL)
testApp.launchViaIntent(wmHelper)
waitAndGetAddBubbleBtn()
waitAndGetCancelAllBtn()
@@ -84,13 +81,6 @@ abstract class BaseBubbleScreen(protected val testSpec: FlickerTestParameter) {
protected fun Flicker.waitAndGetCancelAllBtn(): UiObject2? = device.wait(Until.findObject(
By.text("Cancel All Bubble")), FIND_OBJECT_TIMEOUT)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- transition(this)
- }
- }
-
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
index b137e92881a5..c44e250901f5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
@@ -18,6 +18,7 @@ package com.android.wm.shell.flicker.bubble
import android.content.Context
import android.graphics.Point
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.util.DisplayMetrics
import android.view.WindowManager
@@ -28,8 +29,8 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import org.junit.runner.RunWith
import org.junit.Test
+import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
@@ -49,6 +50,7 @@ open class DismissBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScree
private val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val displaySize = DisplayMetrics()
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition {
setup {
@@ -58,10 +60,13 @@ open class DismissBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScree
}
}
transitions {
- wm.run { wm.getDefaultDisplay().getMetrics(displaySize) }
+ wm.run { wm.defaultDisplay.getMetrics(displaySize) }
val dist = Point((displaySize.widthPixels / 2), displaySize.heightPixels)
- val showBubble = device.wait(Until.findObject(
- By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
+ val showBubble = device.wait(
+ Until.findObject(
+ By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)
+ ), FIND_OBJECT_TIMEOUT
+ )
showBubble?.run { drag(dist, 1000) } ?: error("Show bubble not found")
}
}
@@ -70,7 +75,25 @@ open class DismissBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScree
@Test
open fun testAppIsAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
}
}
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() =
+ super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
index f288b0a24d9d..bab0112fa68f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
@@ -24,8 +24,8 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import org.junit.runner.RunWith
import org.junit.Test
+import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
@@ -44,6 +44,7 @@ import org.junit.runners.Parameterized
@Group4
open class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition {
setup {
@@ -53,8 +54,11 @@ open class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen
}
}
transitions {
- val showBubble = device.wait(Until.findObject(
- By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT)
+ val showBubble = device.wait(
+ Until.findObject(
+ By.res("com.android.systemui", "bubble_view")
+ ), FIND_OBJECT_TIMEOUT
+ )
showBubble?.run { showBubble.click() } ?: error("Bubble notify not found")
}
}
@@ -63,7 +67,7 @@ open class ExpandBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen
@Test
open fun testAppIsAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index e2b19ea22b3b..319de8e4e310 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.bubble
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.WindowInsets
import android.view.WindowManager
@@ -27,8 +28,6 @@ import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -47,6 +46,7 @@ import org.junit.runners.Parameterized
@Group4
class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition {
setup {
@@ -66,18 +66,25 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr
?: error("Unable to obtain WM service")
val metricInsets = wm.currentWindowMetrics.windowInsets
val insets = metricInsets.getInsetsIgnoringVisibility(
- WindowInsets.Type.statusBars()
- or WindowInsets.Type.displayCutout())
+ WindowInsets.Type.statusBars()
+ or WindowInsets.Type.displayCutout()
+ )
device.swipe(100, insets.top + 100, 100, device.displayHeight / 2, 4)
device.waitForIdle(2000)
instrumentation.uiAutomation.syncInputTransactions()
- val notification = device.wait(Until.findObject(
- By.text("BubbleChat")), FIND_OBJECT_TIMEOUT)
+ val notification = device.wait(
+ Until.findObject(
+ By.text("BubbleChat")
+ ), FIND_OBJECT_TIMEOUT
+ )
notification?.click() ?: error("Notification not found")
instrumentation.uiAutomation.syncInputTransactions()
- val showBubble = device.wait(Until.findObject(
- By.res("com.android.systemui", "bubble_view")), FIND_OBJECT_TIMEOUT)
+ val showBubble = device.wait(
+ Until.findObject(
+ By.res("com.android.systemui", "bubble_view")
+ ), FIND_OBJECT_TIMEOUT
+ )
showBubble?.click() ?: error("Bubble notify not found")
instrumentation.uiAutomation.syncInputTransactions()
val cancelAllBtn = waitAndGetCancelAllBtn()
@@ -88,18 +95,38 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr
@Presubmit
@Test
fun testAppIsVisibleAtEnd() {
- Assume.assumeFalse(isShellTransitionsEnabled)
testSpec.assertLayersEnd {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
}
}
- @FlakyTest
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 206753786)
@Test
- fun testAppIsVisibleAtEnd_ShellTransit() {
- Assume.assumeTrue(isShellTransitionsEnabled)
- testSpec.assertLayersEnd {
- this.isVisible(testApp.component)
- }
- }
+ override fun navBarLayerIsVisibleAtStartAndEnd() =
+ super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 206753786)
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 206753786)
+ @Test
+ override fun navBarWindowIsAlwaysVisible() =
+ super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() =
+ super.taskBarWindowIsAlwaysVisible()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
index 0bb4d398bff4..effd33095530 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
@@ -41,6 +41,7 @@ import org.junit.runners.Parameterized
@Group4
open class LaunchBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition {
transitions {
@@ -53,7 +54,7 @@ open class LaunchBubbleScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen
@Test
open fun testAppIsAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
index 8d1e315e2d5e..a558450f4ed8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.bubble
import android.os.SystemClock
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
@@ -28,8 +29,8 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume
import org.junit.Before
-import org.junit.runner.RunWith
import org.junit.Test
+import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
@@ -51,6 +52,7 @@ open class MultiBubblesScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen
Assume.assumeFalse(isShellTransitionsEnabled)
}
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition {
setup {
@@ -59,15 +61,21 @@ open class MultiBubblesScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen
val addBubbleBtn = waitAndGetAddBubbleBtn()
addBubbleBtn?.run { addBubbleBtn.click() } ?: error("Add Bubble not found")
}
- val showBubble = device.wait(Until.findObject(
- By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
+ val showBubble = device.wait(
+ Until.findObject(
+ By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)
+ ), FIND_OBJECT_TIMEOUT
+ )
showBubble?.run { showBubble.click() } ?: error("Show bubble not found")
SystemClock.sleep(1000)
}
}
transitions {
- val bubbles = device.wait(Until.findObjects(
- By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)), FIND_OBJECT_TIMEOUT)
+ val bubbles = device.wait(
+ Until.findObjects(
+ By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)
+ ), FIND_OBJECT_TIMEOUT
+ )
for (entry in bubbles) {
entry?.run { entry.click() } ?: error("Bubble not found")
SystemClock.sleep(1000)
@@ -79,7 +87,73 @@ open class MultiBubblesScreen(testSpec: FlickerTestParameter) : BaseBubbleScreen
@Test
open fun testAppIsAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
}
}
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() =
+ super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() =
+ super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() =
+ super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() =
+ super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() =
+ super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
index f4305ed19824..ffbac39c6078 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
@@ -17,10 +17,10 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
class AppPairsHelper(
instrumentation: Instrumentation,
activityLabel: String,
- component: FlickerComponentName
+ component: IComponentMatcher
) : BaseAppHelper(instrumentation, activityLabel, component)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
index 912ba67285f7..c4379e9a27cc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/BaseAppHelper.kt
@@ -19,7 +19,6 @@ package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
import android.content.pm.PackageManager.FEATURE_LEANBACK
import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
-import android.os.SystemProperties
import android.support.test.launcherhelper.LauncherStrategyFactory
import android.util.Log
import androidx.test.uiautomator.By
@@ -27,13 +26,13 @@ import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.Until
import com.android.compatibility.common.util.SystemUtil
import com.android.server.wm.flicker.helpers.StandardAppHelper
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import java.io.IOException
abstract class BaseAppHelper(
instrumentation: Instrumentation,
launcherName: String,
- component: FlickerComponentName
+ component: IComponentMatcher
) : StandardAppHelper(
instrumentation,
launcherName,
@@ -48,7 +47,7 @@ abstract class BaseAppHelper(
}
val defaultWindowName: String
- get() = component.toWindowName()
+ get() = toWindowName()
val ui: UiObject2?
get() = uiDevice.findObject(appSelector)
@@ -60,9 +59,6 @@ abstract class BaseAppHelper(
companion object {
private const val APP_CLOSE_WAIT_TIME_MS = 3_000L
- fun isShellTransitionsEnabled() =
- SystemProperties.getBoolean("persist.wm.debug.shell_transit", false)
-
fun executeShellCommand(instrumentation: Instrumentation, cmd: String) {
try {
SystemUtil.runShellCommand(instrumentation, cmd)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt
index 12ccbafce651..92b1d216f5ab 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/MultiWindowHelper.kt
@@ -19,12 +19,12 @@ package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
import android.content.Context
import android.provider.Settings
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
class MultiWindowHelper(
instrumentation: Instrumentation,
activityLabel: String,
- componentsInfo: FlickerComponentName
+ componentsInfo: IComponentMatcher
) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) {
companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index 48f9a7e586d8..bdc05e7ecb52 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -149,7 +149,7 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper(
}
private fun getWindowRect(wmHelper: WindowManagerStateHelper): Rect {
- val windowRegion = wmHelper.getWindowRegion(component)
+ val windowRegion = wmHelper.getWindowRegion(this)
require(!windowRegion.isEmpty) {
"Unable to find a PIP window in the current state"
}
@@ -196,7 +196,7 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper(
uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY())
wmHelper.StateSyncBuilder()
.withPipGone()
- .withFullScreenApp(component)
+ .withFullScreenApp(this)
.waitForAndVerify()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
index 49eca63a23ec..ccd5f02e4413 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
@@ -26,17 +26,16 @@ import androidx.test.uiautomator.BySelector
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
import com.android.wm.shell.flicker.testapp.Components
-import org.junit.Assert
class SplitScreenHelper(
instrumentation: Instrumentation,
activityLabel: String,
- componentsInfo: FlickerComponentName
+ componentsInfo: IComponentMatcher
) : BaseAppHelper(instrumentation, activityLabel, componentsInfo) {
companion object {
@@ -111,9 +110,9 @@ class SplitScreenHelper(
}
// Drag to split
- var dragStart = notificationContent.visibleCenter
- var dragMiddle = Point(dragStart.x + 50, dragStart.y)
- var dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4)
+ val dragStart = notificationContent.visibleCenter
+ val dragMiddle = Point(dragStart.x + 50, dragStart.y)
+ val dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4)
val downTime = SystemClock.uptimeMillis()
touch(
@@ -199,10 +198,7 @@ class SplitScreenHelper(
val allApps = taplInstrumentation.workspace.switchToAllApps()
allApps.freeze()
try {
- val appIconSrc = allApps.getAppIcon(appName)
- Assert.assertNotNull("Unable to find app icon", appIconSrc)
- val appIconDest = appIconSrc.dragToHotseat(0)
- Assert.assertNotNull("Unable to drag app icon on hotseat", appIconDest)
+ allApps.getAppIcon(appName).dragToHotseat(0)
} finally {
allApps.unfreeze()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index ce624f2b5bbe..87fa548e8027 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -17,8 +17,8 @@
package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import androidx.test.filters.RequiresDevice
-import com.android.launcher3.tapl.LauncherInstrumentation
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group3
@@ -54,7 +54,6 @@ import org.junit.runners.Parameterized
@FlakyTest(bugId = 238367575)
@Group3
class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(testSpec) {
- protected val taplInstrumentation = LauncherInstrumentation()
/**
* Defines the transition used to run the test
*/
@@ -75,14 +74,14 @@ class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(
}
}
transitions {
- taplInstrumentation.goHome()
+ tapl.goHome()
}
}
+ @Test
override fun pipLayerReduces() {
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.notBiggerThan(previous.visibleRegion.region)
}
@@ -96,9 +95,8 @@ class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(
fun pipLayerMovesTowardsRightBottomCorner() {
// in gestural nav the swipe makes PiP first go upwards
Assume.assumeFalse(testSpec.isGesturalNavigation)
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
// Pip animates towards the right bottom corner, but because it is being resized at the
// same time, it is possible it shrinks first quickly below the default position and get
// moved up after that in just few last frames
@@ -108,9 +106,66 @@ class AutoEnterPipOnGoToHomeTest(testSpec: FlickerTestParameter) : EnterPipTest(
}
}
+ @Test
override fun focusChanges() {
// in gestural nav the focus goes to different activity on swipe up
Assume.assumeFalse(testSpec.isGesturalNavigation)
super.focusChanges()
}
+
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ @Postsubmit
+ @Test
+ override fun pipAppLayerAlwaysVisible() = super.pipAppLayerAlwaysVisible()
+
+ @Postsubmit
+ @Test
+ override fun pipLayerRemainInsideVisibleBounds() = super.pipLayerRemainInsideVisibleBounds()
+
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 9b12e2a04bf3..7b9c1bccda75 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -16,13 +16,18 @@
package com.android.wm.shell.flicker.pip
+import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume
import org.junit.FixMethodOrder
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -72,37 +77,59 @@ class EnterPipOnUserLeaveHintTest(testSpec: FlickerTestParameter) : EnterPipTest
}
}
+ @Postsubmit
+ @Test
override fun pipAppLayerAlwaysVisible() {
if (!testSpec.isGesturalNavigation) super.pipAppLayerAlwaysVisible() else {
// pip layer in gesture nav will disappear during transition
testSpec.assertLayers {
- this.isVisible(pipApp.component)
- .then().isInvisible(pipApp.component)
- .then().isVisible(pipApp.component)
+ this.isVisible(pipApp)
+ .then().isInvisible(pipApp)
+ .then().isVisible(pipApp)
}
}
}
+ @Postsubmit
+ @Test
override fun pipLayerReduces() {
// in gestural nav the pip enters through alpha animation
Assume.assumeFalse(testSpec.isGesturalNavigation)
super.pipLayerReduces()
}
+ @Postsubmit
+ @Test
override fun focusChanges() {
// in gestural nav the focus goes to different activity on swipe up
Assume.assumeFalse(testSpec.isGesturalNavigation)
super.focusChanges()
}
+ @Presubmit
+ @Test
+ override fun entireScreenCovered() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ super.entireScreenCovered()
+ }
+
+ @FlakyTest(bugId = 227313015)
+ @Test
+ fun entireScreenCovered_ShellTransit() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ super.entireScreenCovered()
+ }
+
+ @Postsubmit
+ @Test
override fun pipLayerRemainInsideVisibleBounds() {
if (!testSpec.isGesturalNavigation) super.pipLayerRemainInsideVisibleBounds() else {
// pip layer in gesture nav will disappear during transition
testSpec.assertLayersStart {
- this.visibleRegion(pipApp.component).coversAtMost(displayBounds)
+ this.visibleRegion(pipApp).coversAtMost(displayBounds)
}
testSpec.assertLayersEnd {
- this.visibleRegion(pipApp.component).coversAtMost(displayBounds)
+ this.visibleRegion(pipApp).coversAtMost(displayBounds)
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 19c573b0c15d..90ae36c88348 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
@@ -25,7 +24,7 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -56,9 +55,7 @@ import org.junit.runners.Parameterized
@Group3
open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
- /**
- * Defines the transition used to run the test
- */
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
setupAndTeardown(this)
@@ -84,7 +81,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
@Test
fun pipAppWindowAlwaysVisible() {
testSpec.assertWm {
- this.isAppWindowVisible(pipApp.component)
+ this.isAppWindowVisible(pipApp)
}
}
@@ -95,7 +92,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
@Test
open fun pipAppLayerAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(pipApp.component)
+ this.isVisible(pipApp)
}
}
@@ -106,7 +103,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
@Presubmit
@Test
fun pipWindowRemainInsideVisibleBounds() {
- testSpec.assertWmVisibleRegion(pipApp.component) {
+ testSpec.assertWmVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -118,7 +115,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
@Presubmit
@Test
open fun pipLayerRemainInsideVisibleBounds() {
- testSpec.assertLayersVisibleRegion(pipApp.component) {
+ testSpec.assertLayersVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -129,9 +126,8 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
@Presubmit
@Test
open fun pipLayerReduces() {
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.coversAtMost(previous.visibleRegion.region)
}
@@ -145,22 +141,22 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
@Test
fun pipWindowBecomesPinned() {
testSpec.assertWm {
- invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp.component) }
+ invoke("pipWindowIsNotPinned") { it.isNotPinned(pipApp) }
.then()
- .invoke("pipWindowIsPinned") { it.isPinned(pipApp.component) }
+ .invoke("pipWindowIsPinned") { it.isPinned(pipApp) }
}
}
/**
- * Checks [LAUNCHER] layer remains visible throughout the animation
+ * Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation
*/
@Presubmit
@Test
fun launcherLayerBecomesVisible() {
testSpec.assertLayers {
- isInvisible(LAUNCHER)
+ isInvisible(ComponentMatcher.LAUNCHER)
.then()
- .isVisible(LAUNCHER)
+ .isVisible(ComponentMatcher.LAUNCHER)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index c2ed5a1494c9..dff447b97b9b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -16,7 +16,9 @@
package com.android.wm.shell.flicker.pip
+import android.app.Activity
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
@@ -27,13 +29,15 @@ import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.wm.shell.flicker.helpers.FixedAppHelper
import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT
import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION
import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP
+import org.junit.Assume
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -80,11 +84,17 @@ class EnterPipToOtherOrientationTest(
setup {
eachRun {
// Launch a portrait only app on the fullscreen stack
- testApp.launchViaIntent(wmHelper, stringExtras = mapOf(
- EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString()))
+ testApp.launchViaIntent(
+ wmHelper, stringExtras = mapOf(
+ EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString()
+ )
+ )
// Launch the PiP activity fixed as landscape
- pipApp.launchViaIntent(wmHelper, stringExtras = mapOf(
- EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString()))
+ pipApp.launchViaIntent(
+ wmHelper, stringExtras = mapOf(
+ EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString()
+ )
+ )
}
}
teardown {
@@ -100,19 +110,28 @@ class EnterPipToOtherOrientationTest(
// during rotation the status bar becomes invisible and reappears at the end
wmHelper.StateSyncBuilder()
.withPipShown()
- .withAppTransitionIdle()
- .withNavBarStatusBarVisible()
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
.waitForAndVerify()
}
}
/**
- * Checks that the [FlickerComponentName.NAV_BAR] has the correct position at
+ * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation]
+ * to fix a orientation, Tablets instead keep the same orientation and add letterboxes
+ */
+ @Before
+ fun setup() {
+ Assume.assumeFalse(testSpec.isTablet)
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.NAV_BAR] has the correct position at
* the start and end of the transition
*/
@FlakyTest
@Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() = testSpec.navBarLayerPositionAtStartAndEnd()
/**
* Checks that all parts of the screen are covered at the start and end of the transition
@@ -121,7 +140,7 @@ class EnterPipToOtherOrientationTest(
*/
@Presubmit
@Test
- override fun entireScreenCovered() = testSpec.entireScreenCovered(allStates = false)
+ fun entireScreenCoveredAtStartAndEnd() = testSpec.entireScreenCovered(allStates = false)
/**
* Checks [pipApp] window remains visible and on top throughout the transition
@@ -130,7 +149,7 @@ class EnterPipToOtherOrientationTest(
@Test
fun pipAppWindowIsAlwaysOnTop() {
testSpec.assertWm {
- isAppWindowOnTop(pipApp.component)
+ isAppWindowOnTop(pipApp)
}
}
@@ -141,7 +160,7 @@ class EnterPipToOtherOrientationTest(
@Test
fun testAppWindowInvisibleOnStart() {
testSpec.assertWmStart {
- isAppWindowInvisible(testApp.component)
+ isAppWindowInvisible(testApp)
}
}
@@ -152,7 +171,7 @@ class EnterPipToOtherOrientationTest(
@Test
fun testAppWindowVisibleOnEnd() {
testSpec.assertWmEnd {
- isAppWindowVisible(testApp.component)
+ isAppWindowVisible(testApp)
}
}
@@ -163,7 +182,7 @@ class EnterPipToOtherOrientationTest(
@Test
fun testAppLayerInvisibleOnStart() {
testSpec.assertLayersStart {
- isInvisible(testApp.component)
+ isInvisible(testApp)
}
}
@@ -174,7 +193,7 @@ class EnterPipToOtherOrientationTest(
@Test
fun testAppLayerVisibleOnEnd() {
testSpec.assertLayersEnd {
- isVisible(testApp.component)
+ isVisible(testApp)
}
}
@@ -186,7 +205,7 @@ class EnterPipToOtherOrientationTest(
@Test
fun pipAppLayerCoversFullScreenOnStart() {
testSpec.assertLayersStart {
- visibleRegion(pipApp.component).coversExactly(startingBounds)
+ visibleRegion(pipApp).coversExactly(startingBounds)
}
}
@@ -198,13 +217,24 @@ class EnterPipToOtherOrientationTest(
@Test
fun testAppPlusPipLayerCoversFullScreenOnEnd() {
testSpec.assertLayersEnd {
- val pipRegion = visibleRegion(pipApp.component).region
- visibleRegion(testApp.component)
+ val pipRegion = visibleRegion(pipApp).region
+ visibleRegion(testApp)
.plus(pipRegion)
.coversExactly(endingBounds)
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 227313015)
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
companion object {
/**
* Creates the test configurations.
@@ -216,8 +246,10 @@ class EnterPipToOtherOrientationTest(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3)
+ .getConfigNonRotationTests(
+ supportedRotations = listOf(Surface.ROTATION_0),
+ repetitions = 3
+ )
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
index 990872f58dc1..45851c8b6326 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
@@ -34,7 +34,7 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
@Presubmit
@Test
open fun pipAppWindowRemainInsideVisibleBounds() {
- testSpec.assertWmVisibleRegion(pipApp.component) {
+ testSpec.assertWmVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -46,7 +46,7 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
@Presubmit
@Test
open fun pipAppLayerRemainInsideVisibleBounds() {
- testSpec.assertLayersVisibleRegion(pipApp.component) {
+ testSpec.assertLayersVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -62,11 +62,11 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
// when the activity is STOPPING, sometimes it becomes invisible in an entry before
// the window, sometimes in the same entry. This occurs because we log 1x per frame
// thus we ignore activity here
- isAppWindowVisible(testApp.component)
- .isAppWindowOnTop(pipApp.component)
- .then()
- .isAppWindowInvisible(testApp.component)
- .isAppWindowVisible(pipApp.component)
+ isAppWindowVisible(testApp)
+ .isAppWindowOnTop(pipApp)
+ .then()
+ .isAppWindowInvisible(testApp)
+ .isAppWindowVisible(pipApp)
}
}
@@ -78,11 +78,11 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
@Test
open fun showBothAppLayersThenHidePip() {
testSpec.assertLayers {
- isVisible(testApp.component)
- .isVisible(pipApp.component)
- .then()
- .isInvisible(testApp.component)
- .isVisible(pipApp.component)
+ isVisible(testApp)
+ .isVisible(pipApp)
+ .then()
+ .isInvisible(testApp)
+ .isVisible(pipApp)
}
}
@@ -94,10 +94,10 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
@Test
open fun testPlusPipAppsCoverFullScreenAtStart() {
testSpec.assertLayersStart {
- val pipRegion = visibleRegion(pipApp.component).region
- visibleRegion(testApp.component)
- .plus(pipRegion)
- .coversExactly(displayBounds)
+ val pipRegion = visibleRegion(pipApp).region
+ visibleRegion(testApp)
+ .plus(pipRegion)
+ .coversExactly(displayBounds)
}
}
@@ -109,7 +109,7 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
@Test
open fun pipAppCoversFullScreenAtEnd() {
testSpec.assertLayersEnd {
- visibleRegion(pipApp.component).coversExactly(displayBounds)
+ visibleRegion(pipApp).coversExactly(displayBounds)
}
}
@@ -119,12 +119,16 @@ abstract class ExitPipToAppTransition(testSpec: FlickerTestParameter) : PipTrans
@Presubmit
@Test
open fun pipLayerExpands() {
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.coversAtLeast(previous.visibleRegion.region)
}
}
}
+
+ /** {@inheritDoc} */
+ @Presubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
index 47215b9fb883..33f787182868 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
@@ -16,13 +16,14 @@
package com.android.wm.shell.flicker.pip
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.LAUNCHER
import org.junit.Test
/**
@@ -57,21 +58,21 @@ abstract class ExitPipTransition(testSpec: FlickerTestParameter) : PipTransition
// and isAppWindowInvisible in the same assertion block.
testSpec.assertWm {
this.invoke("hasPipWindow") {
- it.isPinned(pipApp.component)
- .isAppWindowVisible(pipApp.component)
- .isAppWindowOnTop(pipApp.component)
+ it.isPinned(pipApp)
+ .isAppWindowVisible(pipApp)
+ .isAppWindowOnTop(pipApp)
}.then().invoke("!hasPipWindow") {
- it.isNotPinned(pipApp.component)
- .isAppWindowNotOnTop(pipApp.component)
+ it.isNotPinned(pipApp)
+ .isAppWindowNotOnTop(pipApp)
}
}
- testSpec.assertWmEnd { isAppWindowInvisible(pipApp.component) }
+ testSpec.assertWmEnd { isAppWindowInvisible(pipApp) }
} else {
testSpec.assertWm {
this.invoke("hasPipWindow") {
- it.isPinned(pipApp.component).isAppWindowVisible(pipApp.component)
+ it.isPinned(pipApp).isAppWindowVisible(pipApp)
}.then().invoke("!hasPipWindow") {
- it.isNotPinned(pipApp.component).isAppWindowInvisible(pipApp.component)
+ it.isNotPinned(pipApp).isAppWindowInvisible(pipApp)
}
}
}
@@ -86,11 +87,70 @@ abstract class ExitPipTransition(testSpec: FlickerTestParameter) : PipTransition
@Test
open fun pipLayerBecomesInvisible() {
testSpec.assertLayers {
- this.isVisible(pipApp.component)
+ this.isVisible(pipApp)
.isVisible(LAUNCHER)
.then()
- .isInvisible(pipApp.component)
+ .isInvisible(pipApp)
.isVisible(LAUNCHER)
}
}
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index 4e7a9ff10df1..a04ca09e6dd8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -54,7 +54,6 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group3
-@FlakyTest(bugId = 219750830)
class ExitPipViaExpandButtonClickTest(
testSpec: FlickerTestParameter
) : ExitPipToAppTransition(testSpec) {
@@ -75,15 +74,15 @@ class ExitPipViaExpandButtonClickTest(
pipApp.expandPipWindowToApp(wmHelper)
// Wait until the other app is no longer visible
wmHelper.StateSyncBuilder()
- .withWindowSurfaceDisappeared(testApp.component)
+ .withWindowSurfaceDisappeared(testApp)
.waitForAndVerify()
}
}
/** {@inheritDoc} */
- @FlakyTest(bugId = 197726610)
+ @FlakyTest(bugId = 227313015)
@Test
- override fun pipLayerExpands() = super.pipLayerExpands()
+ override fun entireScreenCovered() = super.entireScreenCovered()
companion object {
/**
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 3fbea488d091..1d266140f2e6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -74,7 +74,7 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit
pipApp.exitPipToFullScreenViaIntent(wmHelper)
// Wait until the other app is no longer visible
wmHelper.StateSyncBuilder()
- .withWindowSurfaceDisappeared(testApp.component)
+ .withWindowSurfaceDisappeared(testApp)
.waitForAndVerify()
}
}
@@ -82,16 +82,16 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun statusBarLayerRotatesScales() {
+ override fun statusBarLayerPositionAtStartAndEnd() {
Assume.assumeFalse(isShellTransitionsEnabled)
- super.statusBarLayerRotatesScales()
+ super.statusBarLayerPositionAtStartAndEnd()
}
@Presubmit
@Test
fun statusBarLayerRotatesScales_ShellTransit() {
Assume.assumeTrue(isShellTransitionsEnabled)
- super.statusBarLayerRotatesScales()
+ super.statusBarLayerPositionAtStartAndEnd()
}
/** {@inheritDoc} */
@@ -109,6 +109,11 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit
super.pipLayerExpands()
}
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 227313015)
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
companion object {
/**
* Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
index b9e72a460a5f..5b5b9fc174f6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
@@ -25,6 +24,7 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -58,28 +58,31 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti
get() = {
super.transition(this)
transitions {
- val pipRegion = wmHelper.getWindowRegion(pipApp.component).bounds
+ val pipRegion = wmHelper.getWindowRegion(pipApp).bounds
val pipCenterX = pipRegion.centerX()
val pipCenterY = pipRegion.centerY()
val displayCenterX = device.displayWidth / 2
- device.swipe(pipCenterX, pipCenterY, displayCenterX, device.displayHeight, 10)
+ val barComponent = if (testSpec.isTablet) {
+ ComponentMatcher.TASK_BAR
+ } else {
+ ComponentMatcher.NAV_BAR
+ }
+ val barLayerHeight = wmHelper.currentState.layerState
+ .getLayerWithBuffer(barComponent)
+ ?.visibleRegion
+ ?.height ?: error("Couldn't find Nav or Task bar layer")
+ // The dismiss button doesn't appear at the complete bottom of the screen,
+ val displayY = device.displayHeight - barLayerHeight
+ device.swipe(pipCenterX, pipCenterY, displayCenterX, displayY, 50)
// Wait until the other app is no longer visible
wmHelper.StateSyncBuilder()
.withPipGone()
- .withWindowSurfaceDisappeared(pipApp.component)
+ .withWindowSurfaceDisappeared(pipApp)
.withAppTransitionIdle()
.waitForAndVerify()
}
}
- @FlakyTest
- @Test
- override fun pipWindowBecomesInvisible() = super.pipWindowBecomesInvisible()
-
- @FlakyTest
- @Test
- override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible()
-
/**
* Checks that the focus doesn't change between windows during the transition
*/
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index 32900b17e60a..1c0bd0caa901 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -25,7 +25,7 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -69,7 +69,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@Presubmit
@Test
fun pipWindowRemainInsideVisibleBounds() {
- testSpec.assertWmVisibleRegion(pipApp.component) {
+ testSpec.assertWmVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -81,7 +81,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@Presubmit
@Test
fun pipLayerRemainInsideVisibleBounds() {
- testSpec.assertLayersVisibleRegion(pipApp.component) {
+ testSpec.assertLayersVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -93,7 +93,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@Test
fun pipWindowIsAlwaysVisible() {
testSpec.assertWm {
- isAppWindowVisible(pipApp.component)
+ isAppWindowVisible(pipApp)
}
}
@@ -104,7 +104,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@Test
fun pipLayerIsAlwaysVisible() {
testSpec.assertLayers {
- isVisible(pipApp.component)
+ isVisible(pipApp)
}
}
@@ -114,9 +114,8 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@FlakyTest(bugId = 228012337)
@Test
fun pipLayerExpands() {
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.coversAtLeast(previous.visibleRegion.region)
}
@@ -126,9 +125,8 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@Presubmit
@Test
fun pipSameAspectRatio() {
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.isSameAspectRatio(previous.visibleRegion)
}
@@ -142,18 +140,18 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@Test
fun windowIsAlwaysPinned() {
testSpec.assertWm {
- this.invoke("hasPipWindow") { it.isPinned(pipApp.component) }
+ this.invoke("hasPipWindow") { it.isPinned(pipApp) }
}
}
/**
- * Checks [LAUNCHER] layer remains visible throughout the animation
+ * Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation
*/
@Presubmit
@Test
fun launcherIsAlwaysVisible() {
testSpec.assertLayers {
- isVisible(LAUNCHER)
+ isVisible(ComponentMatcher.LAUNCHER)
}
}
@@ -179,8 +177,10 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3)
+ .getConfigNonRotationTests(
+ supportedRotations = listOf(Surface.ROTATION_0),
+ repetitions = 3
+ )
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
index 768c0905b473..b3f0fb91ab73 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
@@ -70,7 +70,7 @@ open class MovePipDownShelfHeightChangeTest(
}
}
transitions {
- taplInstrumentation.pressHome()
+ tapl.pressHome()
}
}
@@ -89,7 +89,8 @@ open class MovePipDownShelfHeightChangeTest(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+ supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+ )
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
index 0499e7de9a0a..9fb941e2a584 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
-import com.android.launcher3.tapl.LauncherInstrumentation
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.traces.region.RegionSubject
import com.android.wm.shell.flicker.helpers.FixedAppHelper
@@ -29,7 +28,6 @@ import org.junit.Test
abstract class MovePipShelfHeightTransition(
testSpec: FlickerTestParameter
) : PipTransition(testSpec) {
- protected val taplInstrumentation = LauncherInstrumentation()
protected val testApp = FixedAppHelper(instrumentation)
/**
@@ -44,7 +42,7 @@ abstract class MovePipShelfHeightTransition(
@Test
open fun pipWindowIsAlwaysVisible() {
testSpec.assertWm {
- isAppWindowVisible(pipApp.component)
+ isAppWindowVisible(pipApp)
}
}
@@ -55,7 +53,7 @@ abstract class MovePipShelfHeightTransition(
@Test
open fun pipLayerIsAlwaysVisible() {
testSpec.assertLayers {
- isVisible(pipApp.component)
+ isVisible(pipApp)
}
}
@@ -66,7 +64,7 @@ abstract class MovePipShelfHeightTransition(
@Presubmit
@Test
open fun pipWindowRemainInsideVisibleBounds() {
- testSpec.assertWmVisibleRegion(pipApp.component) {
+ testSpec.assertWmVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -78,7 +76,7 @@ abstract class MovePipShelfHeightTransition(
@Presubmit
@Test
open fun pipLayerRemainInsideVisibleBounds() {
- testSpec.assertLayersVisibleRegion(pipApp.component) {
+ testSpec.assertLayersVisibleRegion(pipApp) {
coversAtMost(displayBounds)
}
}
@@ -90,9 +88,8 @@ abstract class MovePipShelfHeightTransition(
@Presubmit
@Test
open fun pipWindowMoves() {
- val windowName = pipApp.component.toWindowName()
testSpec.assertWm {
- val pipWindowList = this.windowStates { it.name.contains(windowName) && it.isVisible }
+ val pipWindowList = this.windowStates { pipApp.windowMatchesAnyOf(it) && it.isVisible }
pipWindowList.zipWithNext { previous, current ->
assertRegionMovement(previous.frame, current.frame)
}
@@ -105,12 +102,11 @@ abstract class MovePipShelfHeightTransition(
@Presubmit
@Test
open fun pipLayerMoves() {
- val layerName = pipApp.component.toLayerName()
testSpec.assertLayers {
- val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
+ val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
assertRegionMovement(previous.visibleRegion, current.visibleRegion)
}
}
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
index 4bc8eb13e26f..8bd5c548f6bd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
@@ -73,7 +73,7 @@ class MovePipUpShelfHeightChangeTest(
get() = buildTransition(eachRun = false) {
teardown {
eachRun {
- taplInstrumentation.pressHome()
+ tapl.pressHome()
}
test {
testApp.exit(wmHelper)
@@ -91,7 +91,8 @@ class MovePipUpShelfHeightChangeTest(
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
companion object {
/**
@@ -104,7 +105,8 @@ class MovePipUpShelfHeightChangeTest(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+ supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+ )
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index 6c4a925ae119..911d402cfde7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.pip
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
@@ -27,7 +28,7 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.wm.shell.flicker.helpers.ImeAppHelper
import org.junit.Assume.assumeFalse
import org.junit.Before
@@ -54,6 +55,7 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS
assumeFalse(isShellTransitionsEnabled)
}
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition(eachRun = false) {
setup {
@@ -78,13 +80,19 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS
}
}
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 206753786)
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
/**
* Ensure the pip window remains visible throughout any keyboard interactions
*/
@Presubmit
@Test
open fun pipInVisibleBounds() {
- testSpec.assertWmVisibleRegion(pipApp.component) {
+ testSpec.assertWmVisibleRegion(pipApp) {
val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
coversAtMost(displayBounds)
}
@@ -97,7 +105,7 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS
@Test
open fun pipIsAboveAppWindow() {
testSpec.assertWmTag(TAG_IME_VISIBLE) {
- isAboveWindow(FlickerComponentName.IME, pipApp.component)
+ isAboveWindow(ComponentMatcher.IME, pipApp)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
index fe51228230cb..3e00b19e2f19 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
@@ -44,5 +44,6 @@ class PipKeyboardTestShellTransit(testSpec: FlickerTestParameter) : PipKeyboardT
@Presubmit
@Test
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-} \ No newline at end of file
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 2c158b8c9969..3326802dfe37 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -16,9 +16,9 @@
package com.android.wm.shell.flicker.pip
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
-import android.platform.test.annotations.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
@@ -28,7 +28,6 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.wm.shell.flicker.helpers.FixedAppHelper
import org.junit.FixMethodOrder
import org.junit.Test
@@ -92,7 +91,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
*/
@FlakyTest
@Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
/**
* Checks that [fixedApp] layer is within [screenBoundsStart] at the start of the transition
@@ -101,7 +100,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
@Test
fun appLayerRotates_StartingBounds() {
testSpec.assertLayersStart {
- visibleRegion(fixedApp.component).coversExactly(screenBoundsStart)
+ visibleRegion(fixedApp).coversExactly(screenBoundsStart)
}
}
@@ -112,7 +111,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
@Test
fun appLayerRotates_EndingBounds() {
testSpec.assertLayersEnd {
- visibleRegion(fixedApp.component).coversExactly(screenBoundsEnd)
+ visibleRegion(fixedApp).coversExactly(screenBoundsEnd)
}
}
@@ -121,7 +120,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
*/
private fun pipLayerRotates_StartingBounds_internal() {
testSpec.assertLayersStart {
- visibleRegion(pipApp.component).coversAtMost(screenBoundsStart)
+ visibleRegion(pipApp).coversAtMost(screenBoundsStart)
}
}
@@ -141,7 +140,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
@Test
fun pipLayerRotates_EndingBounds() {
testSpec.assertLayersEnd {
- visibleRegion(pipApp.component).coversAtMost(screenBoundsEnd)
+ visibleRegion(pipApp).coversAtMost(screenBoundsEnd)
}
}
@@ -153,7 +152,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
@Test
fun pipIsAboveFixedAppWindow_Start() {
testSpec.assertWmStart {
- isAboveWindow(pipApp.component, fixedApp.component)
+ isAboveWindow(pipApp, fixedApp)
}
}
@@ -165,7 +164,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
@Test
fun pipIsAboveFixedAppWindow_End() {
testSpec.assertWmEnd {
- isAboveWindow(pipApp.component, fixedApp.component)
+ isAboveWindow(pipApp, fixedApp)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
deleted file mode 100644
index 7ba085d3cf1a..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTestBase.kt
+++ /dev/null
@@ -1,37 +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.wm.shell.flicker.pip
-
-import com.android.wm.shell.flicker.FlickerTestBase
-import com.android.wm.shell.flicker.helpers.PipAppHelper
-import org.junit.Before
-
-abstract class PipTestBase(
- rotationName: String,
- rotation: Int
-) : FlickerTestBase(rotationName, rotation) {
- protected val testApp = PipAppHelper(instrumentation)
-
- @Before
- override fun televisionSetUp() {
- /**
- * The super implementation assumes ([org.junit.Assume]) that not running on TV, thus
- * disabling the test on TV. This test, however, *should run on TV*, so we overriding this
- * method and simply leaving it blank.
- */
- }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index fe5dd8b83cfb..9ade59783700 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -18,35 +18,22 @@ package com.android.wm.shell.flicker.pip
import android.app.Instrumentation
import android.content.Intent
-import android.platform.test.annotations.Presubmit
import android.view.Surface
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
+import com.android.wm.shell.flicker.BaseTest
import com.android.wm.shell.flicker.helpers.PipAppHelper
import com.android.wm.shell.flicker.testapp.Components
-import org.junit.Test
-abstract class PipTransition(protected val testSpec: FlickerTestParameter) {
- protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
- protected val tapl = LauncherInstrumentation()
+abstract class PipTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
protected val pipApp = PipAppHelper(instrumentation)
protected val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
protected val broadcastActionTrigger = BroadcastActionTrigger(instrumentation)
- protected abstract val transition: FlickerBuilder.() -> Unit
+
// Helper class to process test actions by broadcast.
protected class BroadcastActionTrigger(private val instrumentation: Instrumentation) {
private fun createIntentWithAction(broadcastAction: String): Intent {
@@ -69,13 +56,6 @@ abstract class PipTransition(protected val testSpec: FlickerTestParameter) {
}
}
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- transition(this)
- }
- }
-
/**
* Gets a configuration that handles basic setup and teardown of pip tests
*/
@@ -143,32 +123,4 @@ abstract class PipTransition(protected val testSpec: FlickerTestParameter) {
extraSpec(this)
}
}
-
- @Presubmit
- @Test
- open fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Presubmit
- @Test
- open fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
- @Presubmit
- @Test
- open fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- open fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
- @Presubmit
- @Test
- open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- @Presubmit
- @Test
- open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- open fun entireScreenCovered() = testSpec.entireScreenCovered()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index 1f078b425db2..6d64cb9e0dee 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -16,7 +16,9 @@
package com.android.wm.shell.flicker.pip
+import android.app.Activity
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
@@ -32,6 +34,8 @@ import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.r
import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
import com.android.wm.shell.flicker.testapp.Components
import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION
+import org.junit.Assume
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -53,6 +57,7 @@ open class SetRequestedOrientationWhilePinnedTest(
private val startingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_0)
private val endingBounds = WindowUtils.getDisplayBounds(Surface.ROTATION_90)
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
@@ -70,7 +75,8 @@ open class SetRequestedOrientationWhilePinnedTest(
wmHelper.StateSyncBuilder()
.withPipShown()
.withRotation(Surface.ROTATION_0)
- .withNavBarStatusBarVisible()
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
.waitForAndVerify()
}
}
@@ -88,14 +94,23 @@ open class SetRequestedOrientationWhilePinnedTest(
pipApp.launchViaIntent(wmHelper)
// System bar may fade out during fixed rotation.
wmHelper.StateSyncBuilder()
- .withFullScreenApp(pipApp.component)
+ .withFullScreenApp(pipApp)
.withRotation(Surface.ROTATION_90)
- .withAppTransitionIdle()
- .withNavBarStatusBarVisible()
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
.waitForAndVerify()
}
}
+ /**
+ * This test is not compatible with Tablets. When using [Activity.setRequestedOrientation]
+ * to fix a orientation, Tablets instead keep the same orientation and add letterboxes
+ */
+ @Before
+ fun setup() {
+ Assume.assumeFalse(testSpec.isTablet)
+ }
+
@Presubmit
@Test
fun displayEndsAt90Degrees() {
@@ -104,23 +119,27 @@ open class SetRequestedOrientationWhilePinnedTest(
}
}
+ /** {@inheritDoc} */
@Presubmit
@Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+ /** {@inheritDoc} */
@Presubmit
@Test
- override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+ /** {@inheritDoc} */
@FlakyTest
@Test
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
@Presubmit
@Test
fun pipWindowInsideDisplay() {
testSpec.assertWmStart {
- frameRegion(pipApp.component).coversAtMost(startingBounds)
+ visibleRegion(pipApp).coversAtMost(startingBounds)
}
}
@@ -128,7 +147,7 @@ open class SetRequestedOrientationWhilePinnedTest(
@Test
fun pipAppShowsOnTop() {
testSpec.assertWmEnd {
- isAppWindowOnTop(pipApp.component)
+ isAppWindowOnTop(pipApp)
}
}
@@ -136,7 +155,7 @@ open class SetRequestedOrientationWhilePinnedTest(
@Test
fun pipLayerInsideDisplay() {
testSpec.assertLayersStart {
- visibleRegion(pipApp.component).coversAtMost(startingBounds)
+ visibleRegion(pipApp).coversAtMost(startingBounds)
}
}
@@ -144,7 +163,7 @@ open class SetRequestedOrientationWhilePinnedTest(
@Test
fun pipAlwaysVisible() {
testSpec.assertWm {
- this.isAppWindowVisible(pipApp.component)
+ this.isAppWindowVisible(pipApp)
}
}
@@ -152,10 +171,54 @@ open class SetRequestedOrientationWhilePinnedTest(
@Test
fun pipAppLayerCoversFullScreen() {
testSpec.assertLayersEnd {
- visibleRegion(pipApp.component).coversExactly(endingBounds)
+ visibleRegion(pipApp).coversExactly(endingBounds)
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() =
+ super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
index 9c50630095be..180ced0a6814 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/FlickerTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,29 +14,18 @@
* limitations under the License.
*/
-package com.android.wm.shell.flicker
+package com.android.wm.shell.flicker.pip.tv
import android.app.Instrumentation
import android.content.pm.PackageManager
-import android.content.pm.PackageManager.FEATURE_LEANBACK
-import android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY
import android.view.Surface
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
-import org.junit.Assume.assumeFalse
+import com.android.wm.shell.flicker.helpers.PipAppHelper
import org.junit.Before
import org.junit.runners.Parameterized
-/**
- * Base class of all Flicker test that performs common functions for all flicker tests:
- *
- * - Caches transitions so that a transition is run once and the transition results are used by
- * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
- * multiple times.
- * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
- * - Fails tests if results are not available for any test due to jank.
- */
-abstract class FlickerTestBase(
+abstract class PipTestBase(
protected val rotationName: String,
protected val rotation: Int
) {
@@ -45,16 +34,20 @@ abstract class FlickerTestBase(
val packageManager: PackageManager = instrumentation.context.packageManager
protected val isTelevision: Boolean by lazy {
packageManager.run {
- hasSystemFeature(FEATURE_LEANBACK) || hasSystemFeature(FEATURE_LEANBACK_ONLY)
+ hasSystemFeature(PackageManager.FEATURE_LEANBACK) ||
+ hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)
}
}
+ protected val testApp = PipAppHelper(instrumentation)
- /**
- * By default WmShellFlickerTests do not run on TV devices.
- * If the test should run on TV - it should override this method.
- */
@Before
- open fun televisionSetUp() = assumeFalse(isTelevision)
+ open fun televisionSetUp() {
+ /**
+ * The super implementation assumes ([org.junit.Assume]) that not running on TV, thus
+ * disabling the test on TV. This test, however, *should run on TV*, so we overriding this
+ * method and simply leaving it blank.
+ */
+ }
companion object {
@Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
index a97994e7d6c3..aeff0ac9f4f2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
@@ -25,7 +25,6 @@ import android.view.Surface.rotationToString
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
-import com.android.wm.shell.flicker.pip.PipTestBase
import org.junit.After
import org.junit.Assert.assertFalse
import org.junit.Assume.assumeTrue
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index cfba3387825c..779be0ad95e3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.splitscreen
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
@@ -57,7 +58,7 @@ class EnterSplitScreenByDragFromAllApps(
@Before
fun before() {
- Assume.assumeTrue(taplInstrumentation.isTablet)
+ Assume.assumeTrue(tapl.isTablet)
}
override val transition: FlickerBuilder.() -> Unit
@@ -65,12 +66,12 @@ class EnterSplitScreenByDragFromAllApps(
super.transition(this)
setup {
eachRun {
- taplInstrumentation.goHome()
+ tapl.goHome()
primaryApp.launchViaIntent(wmHelper)
}
}
transitions {
- taplInstrumentation.launchedAppState.taskbar
+ tapl.launchedAppState.taskbar
.openAllApps()
.getAppIcon(secondaryApp.appName)
.dragToSplitscreen(secondaryApp.`package`, primaryApp.`package`)
@@ -83,30 +84,96 @@ class EnterSplitScreenByDragFromAllApps(
@Presubmit
@Test
- fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+ fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp)
@Presubmit
@Test
- fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component)
+ fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp)
@Presubmit
@Test
fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
- testSpec.endRotation, primaryApp.component, false /* splitLeftTop */)
+ testSpec.endRotation, primaryApp, false /* splitLeftTop */)
@Presubmit
@Test
fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
- testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */)
+ testSpec.endRotation, secondaryApp, true /* splitLeftTop */)
@Presubmit
@Test
- fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+ fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp)
@Presubmit
@Test
fun secondaryAppWindowBecomesVisible() =
- testSpec.appWindowBecomesVisible(secondaryApp.component)
+ testSpec.appWindowBecomesVisible(secondaryApp)
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() =
+ super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() =
+ super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() =
+ super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() =
+ super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() =
+ super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
@Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 7323d992ecd4..d47d81b4287a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.splitscreen
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
@@ -60,9 +61,10 @@ class EnterSplitScreenByDragFromNotification(
@Before
fun before() {
- Assume.assumeTrue(taplInstrumentation.isTablet)
+ Assume.assumeTrue(tapl.isTablet)
}
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
@@ -76,7 +78,7 @@ class EnterSplitScreenByDragFromNotification(
)
sendNotification?.click() ?: error("Send notification button not found")
- taplInstrumentation.goHome()
+ tapl.goHome()
primaryApp.launchViaIntent(wmHelper)
}
}
@@ -96,33 +98,99 @@ class EnterSplitScreenByDragFromNotification(
@Presubmit
@Test
- fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+ fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp)
@Presubmit
@Test
fun secondaryAppLayerBecomesVisible() =
- testSpec.layerBecomesVisible(sendNotificationApp.component)
+ testSpec.layerBecomesVisible(sendNotificationApp)
@Presubmit
@Test
fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
- testSpec.endRotation, primaryApp.component, false /* splitLeftTop */
+ testSpec.endRotation, primaryApp, false /* splitLeftTop */
)
@Presubmit
@Test
fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
- testSpec.endRotation, sendNotificationApp.component, true /* splitLeftTop */
+ testSpec.endRotation, sendNotificationApp, true /* splitLeftTop */
)
@Presubmit
@Test
- fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+ fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp)
@Presubmit
@Test
fun secondaryAppWindowIsVisibleAtEnd() =
- testSpec.appWindowIsVisibleAtEnd(sendNotificationApp.component)
+ testSpec.appWindowIsVisibleAtEnd(sendNotificationApp)
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() =
+ super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() =
+ super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() =
+ super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() =
+ super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() =
+ super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
@Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index 60b0f8ed1135..1493d1fd3cce 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.splitscreen
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
@@ -57,23 +58,24 @@ class EnterSplitScreenByDragFromTaskbar(
@Before
fun before() {
- Assume.assumeTrue(taplInstrumentation.isTablet)
+ Assume.assumeTrue(tapl.isTablet)
}
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
setup {
eachRun {
- taplInstrumentation.goHome()
+ tapl.goHome()
SplitScreenHelper.createShortcutOnHotseatIfNotExist(
- taplInstrumentation, secondaryApp.appName
+ tapl, secondaryApp.appName
)
primaryApp.launchViaIntent(wmHelper)
}
}
transitions {
- taplInstrumentation.launchedAppState.taskbar
+ tapl.launchedAppState.taskbar
.getAppIcon(secondaryApp.appName)
.dragToSplitscreen(
secondaryApp.`package`,
@@ -88,32 +90,98 @@ class EnterSplitScreenByDragFromTaskbar(
@Presubmit
@Test
- fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+ fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp)
@Presubmit
@Test
- fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component)
+ fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp)
@Presubmit
@Test
fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
- testSpec.endRotation, primaryApp.component, false /* splitLeftTop */
+ testSpec.endRotation, primaryApp, splitLeftTop = false
)
@Presubmit
@Test
fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
- testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */
+ testSpec.endRotation, secondaryApp, splitLeftTop = true
)
@Presubmit
@Test
- fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+ fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp)
@Presubmit
@Test
fun secondaryAppWindowBecomesVisible() =
- testSpec.appWindowBecomesVisible(secondaryApp.component)
+ testSpec.appWindowBecomesVisible(secondaryApp)
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() =
+ super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() =
+ super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() =
+ super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() =
+ super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() =
+ super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
@Parameterized.Parameters(name = "{0}")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
index 52c2daf96a3c..81390b243ef9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
@@ -16,37 +16,26 @@
package com.android.wm.shell.flicker.splitscreen
-import android.app.Instrumentation
import android.content.Context
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.setRotation
+import com.android.wm.shell.flicker.BaseTest
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-abstract class SplitScreenBase(protected val testSpec: FlickerTestParameter) {
- protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
- protected val taplInstrumentation = LauncherInstrumentation()
+abstract class SplitScreenBase(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
protected val context: Context = instrumentation.context
protected val primaryApp = SplitScreenHelper.getPrimary(instrumentation)
protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- transition(this)
- }
- }
-
- protected open val transition: FlickerBuilder.() -> Unit
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
test {
- taplInstrumentation.setEnableRotation(true)
+ tapl.setEnableRotation(true)
setRotation(testSpec.startRotation)
- taplInstrumentation.setExpectedRotation(testSpec.startRotation)
+ tapl.setExpectedRotation(testSpec.startRotation)
}
}
teardown {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java
new file mode 100644
index 000000000000..1effc97a0de3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellInitImplTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.draganddrop.DragAndDropController;
+import com.android.wm.shell.freeform.FreeformTaskListener;
+import com.android.wm.shell.fullscreen.FullscreenTaskListener;
+import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
+import com.android.wm.shell.pip.phone.PipTouchHandler;
+import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.startingsurface.StartingWindowController;
+import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Optional;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class ShellInitImplTest extends ShellTestCase {
+
+ @Mock private DisplayController mDisplayController;
+ @Mock private DisplayImeController mDisplayImeController;
+ @Mock private DisplayInsetsController mDisplayInsetsController;
+ @Mock private DragAndDropController mDragAndDropController;
+ @Mock private ShellTaskOrganizer mShellTaskOrganizer;
+ @Mock private KidsModeTaskOrganizer mKidsModeTaskOrganizer;
+ @Mock private Optional<BubbleController> mBubblesOptional;
+ @Mock private Optional<SplitScreenController> mSplitScreenOptional;
+ @Mock private Optional<PipTouchHandler> mPipTouchHandlerOptional;
+ @Mock private FullscreenTaskListener mFullscreenTaskListener;
+ @Mock private Optional<UnfoldAnimationController> mUnfoldAnimationController;
+ @Mock private Optional<UnfoldTransitionHandler> mUnfoldTransitionHandler;
+ @Mock private Optional<FreeformTaskListener<?>> mFreeformTaskListenerOptional;
+ @Mock private Optional<RecentTasksController> mRecentTasks;
+ @Mock private Transitions mTransitions;
+ @Mock private StartingWindowController mStartingWindow;
+ @Mock private ShellExecutor mMainExecutor;
+
+ private ShellInitImpl mImpl;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mImpl = new ShellInitImpl(mDisplayController, mDisplayImeController,
+ mDisplayInsetsController, mDragAndDropController, mShellTaskOrganizer,
+ mKidsModeTaskOrganizer, mBubblesOptional, mSplitScreenOptional,
+ mPipTouchHandlerOptional, mFullscreenTaskListener, mUnfoldAnimationController,
+ mUnfoldTransitionHandler, mFreeformTaskListenerOptional, mRecentTasks, mTransitions,
+ mStartingWindow, mMainExecutor);
+ }
+
+ @Test
+ public void testAddInitCallbacks_expectCalledInOrder() {
+ ArrayList<Integer> results = new ArrayList<>();
+ mImpl.addInitCallback(() -> {
+ results.add(1);
+ }, new Object());
+ mImpl.addInitCallback(() -> {
+ results.add(2);
+ }, new Object());
+ mImpl.addInitCallback(() -> {
+ results.add(3);
+ }, new Object());
+ mImpl.init();
+ assertTrue(results.get(0) == 1);
+ assertTrue(results.get(1) == 2);
+ assertTrue(results.get(2) == 3);
+ }
+
+ @Test
+ public void testNoInitCallbacksAfterInit_expectException() {
+ mImpl.init();
+ try {
+ mImpl.addInitCallback(() -> {}, new Object());
+ fail("Expected exception when adding callback after init");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testDoubleInit_expectNoOp() {
+ ArrayList<Integer> results = new ArrayList<>();
+ mImpl.addInitCallback(() -> {
+ results.add(1);
+ }, new Object());
+ mImpl.init();
+ assertTrue(results.size() == 1);
+ mImpl.init();
+ assertTrue(results.size() == 1);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index f1e2323f70ef..3dd00329253c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -26,11 +26,13 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_MULTI_WINDOW;
import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
+import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
@@ -146,6 +148,7 @@ public class ShellTaskOrganizerTests extends ShellTestCase {
@Test
public void testTaskLeashReleasedAfterVanished() throws RemoteException {
+ assumeFalse(ENABLE_SHELL_TRANSITIONS);
RunningTaskInfo taskInfo = createTaskInfo(1, WINDOWING_MODE_MULTI_WINDOW);
SurfaceControl taskLeash = new SurfaceControl.Builder(new SurfaceSession())
.setName("task").build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index f1e602fcf778..95725bbfd855 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -133,7 +133,7 @@ public class SplitLayoutTests extends ShellTestCase {
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
waitDividerFlingFinished();
- verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false));
+ verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false), anyInt());
}
@Test
@@ -145,7 +145,7 @@ public class SplitLayoutTests extends ShellTestCase {
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
waitDividerFlingFinished();
- verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
+ verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true), anyInt());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index c90a8259a9ef..c10e4a143076 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -24,6 +24,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -90,12 +91,13 @@ public class SplitScreenControllerTests extends ShellTestCase {
@Test
public void testIsLaunchingAdjacently_notInSplitScreen() {
doReturn(false).when(mSplitScreenController).isSplitScreenVisible();
+ doReturn(true).when(mSplitScreenController).isValidToEnterSplitScreen(any());
// Verify launching the same activity returns true.
Intent startIntent = createStartIntent("startActivity");
ActivityManager.RunningTaskInfo focusTaskInfo =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
- mSplitScreenController.onFocusTaskChanged(focusTaskInfo);
+ doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
assertTrue(mSplitScreenController.isLaunchingAdjacently(
startIntent, SPLIT_POSITION_TOP_OR_LEFT));
@@ -103,7 +105,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
Intent diffIntent = createStartIntent("diffActivity");
focusTaskInfo =
createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, diffIntent);
- mSplitScreenController.onFocusTaskChanged(focusTaskInfo);
+ doReturn(focusTaskInfo).when(mSplitScreenController).getFocusingTaskInfo();
assertFalse(mSplitScreenController.isLaunchingAdjacently(
startIntent, SPLIT_POSITION_TOP_OR_LEFT));
}
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 af2c495c85c5..4b68870d4129 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
@@ -127,6 +127,9 @@ public class StageCoordinatorTests extends ShellTestCase {
mRootTask = new TestRunningTaskInfoBuilder().build();
mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
mStageCoordinator.onTaskAppeared(mRootTask, mRootLeash);
+
+ mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
+ mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
}
@Test
@@ -224,8 +227,8 @@ public class StageCoordinatorTests extends ShellTestCase {
mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
verify(mMainStage).reorderChild(eq(testTaskId), eq(true),
any(WindowContainerTransaction.class));
- verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false));
- verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(true));
+ verify(mSideStage).dismiss(any(WindowContainerTransaction.class), eq(false));
+ verify(mMainStage).resetBounds(any(WindowContainerTransaction.class));
}
@Test
@@ -237,8 +240,8 @@ public class StageCoordinatorTests extends ShellTestCase {
mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
verify(mSideStage).reorderChild(eq(testTaskId), eq(true),
any(WindowContainerTransaction.class));
- verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(true));
- verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
+ verify(mSideStage).resetBounds(any(WindowContainerTransaction.class));
+ verify(mMainStage).dismiss(any(WindowContainerTransaction.class), eq(false));
}
@Test
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index 0aa14655725c..ed453b158579 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -497,16 +497,29 @@ namespace PaintGlue {
return true;
}
- static jfloat doRunAdvance(const Paint* paint, const Typeface* typeface, const jchar buf[],
- jint start, jint count, jint bufSize, jboolean isRtl, jint offset) {
+ static jfloat doRunAdvance(JNIEnv* env, const Paint* paint, const Typeface* typeface,
+ const jchar buf[], jint start, jint count, jint bufSize,
+ jboolean isRtl, jint offset, jfloatArray advances,
+ jint advancesIndex) {
+ if (advances) {
+ size_t advancesLength = env->GetArrayLength(advances);
+ if ((size_t)(count + advancesIndex) > advancesLength) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ }
minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
- if (offset == start + count) {
+ if (offset == start + count && advances == nullptr) {
return MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count,
bufSize, nullptr);
}
std::unique_ptr<float[]> advancesArray(new float[count]);
MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize,
advancesArray.get());
+
+ if (advances) {
+ env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get());
+ }
return minikin::getRunAdvance(advancesArray.get(), buf, start, count, offset);
}
@@ -515,9 +528,23 @@ namespace PaintGlue {
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
const Typeface* typeface = paint->getAndroidTypeface();
ScopedCharArrayRO textArray(env, text);
- jfloat result = doRunAdvance(paint, typeface, textArray.get() + contextStart,
- start - contextStart, end - start, contextEnd - contextStart, isRtl,
- offset - contextStart);
+ jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart,
+ start - contextStart, end - start, contextEnd - contextStart,
+ isRtl, offset - contextStart, nullptr, 0);
+ return result;
+ }
+
+ static jfloat getRunCharacterAdvance___CIIIIZI_FI_F(JNIEnv* env, jclass, jlong paintHandle,
+ jcharArray text, jint start, jint end,
+ jint contextStart, jint contextEnd,
+ jboolean isRtl, jint offset,
+ jfloatArray advances, jint advancesIndex) {
+ const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+ const Typeface* typeface = paint->getAndroidTypeface();
+ ScopedCharArrayRO textArray(env, text);
+ jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart,
+ start - contextStart, end - start, contextEnd - contextStart,
+ isRtl, offset - contextStart, advances, advancesIndex);
return result;
}
@@ -1034,113 +1061,112 @@ namespace PaintGlue {
}; // namespace PaintGlue
static const JNINativeMethod methods[] = {
- {"nGetNativeFinalizer", "()J", (void*) PaintGlue::getNativeFinalizer},
- {"nInit","()J", (void*) PaintGlue::init},
- {"nInitWithPaint","(J)J", (void*) PaintGlue::initWithPaint},
- {"nBreakText","(J[CIIFI[F)I", (void*) PaintGlue::breakTextC},
- {"nBreakText","(JLjava/lang/String;ZFI[F)I", (void*) PaintGlue::breakTextS},
- {"nGetTextAdvances","(J[CIIIII[FI)F",
- (void*) PaintGlue::getTextAdvances___CIIIII_FI},
- {"nGetTextAdvances","(JLjava/lang/String;IIIII[FI)F",
- (void*) PaintGlue::getTextAdvances__StringIIIII_FI},
-
- {"nGetTextRunCursor", "(J[CIIIII)I", (void*) PaintGlue::getTextRunCursor___C},
- {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I",
- (void*) PaintGlue::getTextRunCursor__String},
- {"nGetTextPath", "(JI[CIIFFJ)V", (void*) PaintGlue::getTextPath___C},
- {"nGetTextPath", "(JILjava/lang/String;IIFFJ)V", (void*) PaintGlue::getTextPath__String},
- {"nGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
- (void*) PaintGlue::getStringBounds },
- {"nGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
- (void*) PaintGlue::getCharArrayBounds },
- {"nHasGlyph", "(JILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph },
- {"nGetRunAdvance", "(J[CIIIIZI)F", (void*) PaintGlue::getRunAdvance___CIIIIZI_F},
- {"nGetOffsetForAdvance", "(J[CIIIIZF)I",
- (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I},
- {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
- (void*)PaintGlue::getFontMetricsIntForText___C},
- {"nGetFontMetricsIntForText",
- "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
- (void*)PaintGlue::getFontMetricsIntForText___String},
-
- // --------------- @FastNative ----------------------
-
- {"nSetTextLocales","(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales},
- {"nSetFontFeatureSettings","(JLjava/lang/String;)V",
- (void*) PaintGlue::setFontFeatureSettings},
- {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F",
- (void*)PaintGlue::getFontMetrics},
- {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I",
- (void*)PaintGlue::getFontMetricsInt},
-
- // --------------- @CriticalNative ------------------
-
- {"nReset","(J)V", (void*) PaintGlue::reset},
- {"nSet","(JJ)V", (void*) PaintGlue::assign},
- {"nGetFlags","(J)I", (void*) PaintGlue::getFlags},
- {"nSetFlags","(JI)V", (void*) PaintGlue::setFlags},
- {"nGetHinting","(J)I", (void*) PaintGlue::getHinting},
- {"nSetHinting","(JI)V", (void*) PaintGlue::setHinting},
- {"nSetAntiAlias","(JZ)V", (void*) PaintGlue::setAntiAlias},
- {"nSetSubpixelText","(JZ)V", (void*) PaintGlue::setSubpixelText},
- {"nSetLinearText","(JZ)V", (void*) PaintGlue::setLinearText},
- {"nSetUnderlineText","(JZ)V", (void*) PaintGlue::setUnderlineText},
- {"nSetStrikeThruText","(JZ)V", (void*) PaintGlue::setStrikeThruText},
- {"nSetFakeBoldText","(JZ)V", (void*) PaintGlue::setFakeBoldText},
- {"nSetFilterBitmap","(JZ)V", (void*) PaintGlue::setFilterBitmap},
- {"nSetDither","(JZ)V", (void*) PaintGlue::setDither},
- {"nGetStyle","(J)I", (void*) PaintGlue::getStyle},
- {"nSetStyle","(JI)V", (void*) PaintGlue::setStyle},
- {"nSetColor","(JI)V", (void*) PaintGlue::setColor},
- {"nSetColor","(JJJ)V", (void*) PaintGlue::setColorLong},
- {"nSetAlpha","(JI)V", (void*) PaintGlue::setAlpha},
- {"nGetStrokeWidth","(J)F", (void*) PaintGlue::getStrokeWidth},
- {"nSetStrokeWidth","(JF)V", (void*) PaintGlue::setStrokeWidth},
- {"nGetStrokeMiter","(J)F", (void*) PaintGlue::getStrokeMiter},
- {"nSetStrokeMiter","(JF)V", (void*) PaintGlue::setStrokeMiter},
- {"nGetStrokeCap","(J)I", (void*) PaintGlue::getStrokeCap},
- {"nSetStrokeCap","(JI)V", (void*) PaintGlue::setStrokeCap},
- {"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin},
- {"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin},
- {"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath},
- {"nSetShader","(JJ)J", (void*) PaintGlue::setShader},
- {"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter},
- {"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode},
- {"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect},
- {"nSetMaskFilter","(JJ)J", (void*) PaintGlue::setMaskFilter},
- {"nSetTypeface","(JJ)V", (void*) PaintGlue::setTypeface},
- {"nGetTextAlign","(J)I", (void*) PaintGlue::getTextAlign},
- {"nSetTextAlign","(JI)V", (void*) PaintGlue::setTextAlign},
- {"nSetTextLocalesByMinikinLocaleListId","(JI)V",
- (void*) PaintGlue::setTextLocalesByMinikinLocaleListId},
- {"nIsElegantTextHeight","(J)Z", (void*) PaintGlue::isElegantTextHeight},
- {"nSetElegantTextHeight","(JZ)V", (void*) PaintGlue::setElegantTextHeight},
- {"nGetTextSize","(J)F", (void*) PaintGlue::getTextSize},
- {"nSetTextSize","(JF)V", (void*) PaintGlue::setTextSize},
- {"nGetTextScaleX","(J)F", (void*) PaintGlue::getTextScaleX},
- {"nSetTextScaleX","(JF)V", (void*) PaintGlue::setTextScaleX},
- {"nGetTextSkewX","(J)F", (void*) PaintGlue::getTextSkewX},
- {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX},
- {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
- {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
- {"nGetWordSpacing","(J)F", (void*) PaintGlue::getWordSpacing},
- {"nSetWordSpacing","(JF)V", (void*) PaintGlue::setWordSpacing},
- {"nGetStartHyphenEdit", "(J)I", (void*) PaintGlue::getStartHyphenEdit},
- {"nGetEndHyphenEdit", "(J)I", (void*) PaintGlue::getEndHyphenEdit},
- {"nSetStartHyphenEdit", "(JI)V", (void*) PaintGlue::setStartHyphenEdit},
- {"nSetEndHyphenEdit", "(JI)V", (void*) PaintGlue::setEndHyphenEdit},
- {"nAscent","(J)F", (void*) PaintGlue::ascent},
- {"nDescent","(J)F", (void*) PaintGlue::descent},
- {"nGetUnderlinePosition","(J)F", (void*) PaintGlue::getUnderlinePosition},
- {"nGetUnderlineThickness","(J)F", (void*) PaintGlue::getUnderlineThickness},
- {"nGetStrikeThruPosition","(J)F", (void*) PaintGlue::getStrikeThruPosition},
- {"nGetStrikeThruThickness","(J)F", (void*) PaintGlue::getStrikeThruThickness},
- {"nSetShadowLayer", "(JFFFJJ)V", (void*)PaintGlue::setShadowLayer},
- {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer},
- {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement},
+ {"nGetNativeFinalizer", "()J", (void*)PaintGlue::getNativeFinalizer},
+ {"nInit", "()J", (void*)PaintGlue::init},
+ {"nInitWithPaint", "(J)J", (void*)PaintGlue::initWithPaint},
+ {"nBreakText", "(J[CIIFI[F)I", (void*)PaintGlue::breakTextC},
+ {"nBreakText", "(JLjava/lang/String;ZFI[F)I", (void*)PaintGlue::breakTextS},
+ {"nGetTextAdvances", "(J[CIIIII[FI)F", (void*)PaintGlue::getTextAdvances___CIIIII_FI},
+ {"nGetTextAdvances", "(JLjava/lang/String;IIIII[FI)F",
+ (void*)PaintGlue::getTextAdvances__StringIIIII_FI},
+
+ {"nGetTextRunCursor", "(J[CIIIII)I", (void*)PaintGlue::getTextRunCursor___C},
+ {"nGetTextRunCursor", "(JLjava/lang/String;IIIII)I",
+ (void*)PaintGlue::getTextRunCursor__String},
+ {"nGetTextPath", "(JI[CIIFFJ)V", (void*)PaintGlue::getTextPath___C},
+ {"nGetTextPath", "(JILjava/lang/String;IIFFJ)V", (void*)PaintGlue::getTextPath__String},
+ {"nGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V",
+ (void*)PaintGlue::getStringBounds},
+ {"nGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V",
+ (void*)PaintGlue::getCharArrayBounds},
+ {"nHasGlyph", "(JILjava/lang/String;)Z", (void*)PaintGlue::hasGlyph},
+ {"nGetRunAdvance", "(J[CIIIIZI)F", (void*)PaintGlue::getRunAdvance___CIIIIZI_F},
+ {"nGetRunCharacterAdvance", "(J[CIIIIZI[FI)F",
+ (void*)PaintGlue::getRunCharacterAdvance___CIIIIZI_FI_F},
+ {"nGetOffsetForAdvance", "(J[CIIIIZF)I", (void*)PaintGlue::getOffsetForAdvance___CIIIIZF_I},
+ {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
+ (void*)PaintGlue::getFontMetricsIntForText___C},
+ {"nGetFontMetricsIntForText",
+ "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V",
+ (void*)PaintGlue::getFontMetricsIntForText___String},
+
+ // --------------- @FastNative ----------------------
+
+ {"nSetTextLocales", "(JLjava/lang/String;)I", (void*)PaintGlue::setTextLocales},
+ {"nSetFontFeatureSettings", "(JLjava/lang/String;)V",
+ (void*)PaintGlue::setFontFeatureSettings},
+ {"nGetFontMetrics", "(JLandroid/graphics/Paint$FontMetrics;)F",
+ (void*)PaintGlue::getFontMetrics},
+ {"nGetFontMetricsInt", "(JLandroid/graphics/Paint$FontMetricsInt;)I",
+ (void*)PaintGlue::getFontMetricsInt},
+
+ // --------------- @CriticalNative ------------------
+
+ {"nReset", "(J)V", (void*)PaintGlue::reset},
+ {"nSet", "(JJ)V", (void*)PaintGlue::assign},
+ {"nGetFlags", "(J)I", (void*)PaintGlue::getFlags},
+ {"nSetFlags", "(JI)V", (void*)PaintGlue::setFlags},
+ {"nGetHinting", "(J)I", (void*)PaintGlue::getHinting},
+ {"nSetHinting", "(JI)V", (void*)PaintGlue::setHinting},
+ {"nSetAntiAlias", "(JZ)V", (void*)PaintGlue::setAntiAlias},
+ {"nSetSubpixelText", "(JZ)V", (void*)PaintGlue::setSubpixelText},
+ {"nSetLinearText", "(JZ)V", (void*)PaintGlue::setLinearText},
+ {"nSetUnderlineText", "(JZ)V", (void*)PaintGlue::setUnderlineText},
+ {"nSetStrikeThruText", "(JZ)V", (void*)PaintGlue::setStrikeThruText},
+ {"nSetFakeBoldText", "(JZ)V", (void*)PaintGlue::setFakeBoldText},
+ {"nSetFilterBitmap", "(JZ)V", (void*)PaintGlue::setFilterBitmap},
+ {"nSetDither", "(JZ)V", (void*)PaintGlue::setDither},
+ {"nGetStyle", "(J)I", (void*)PaintGlue::getStyle},
+ {"nSetStyle", "(JI)V", (void*)PaintGlue::setStyle},
+ {"nSetColor", "(JI)V", (void*)PaintGlue::setColor},
+ {"nSetColor", "(JJJ)V", (void*)PaintGlue::setColorLong},
+ {"nSetAlpha", "(JI)V", (void*)PaintGlue::setAlpha},
+ {"nGetStrokeWidth", "(J)F", (void*)PaintGlue::getStrokeWidth},
+ {"nSetStrokeWidth", "(JF)V", (void*)PaintGlue::setStrokeWidth},
+ {"nGetStrokeMiter", "(J)F", (void*)PaintGlue::getStrokeMiter},
+ {"nSetStrokeMiter", "(JF)V", (void*)PaintGlue::setStrokeMiter},
+ {"nGetStrokeCap", "(J)I", (void*)PaintGlue::getStrokeCap},
+ {"nSetStrokeCap", "(JI)V", (void*)PaintGlue::setStrokeCap},
+ {"nGetStrokeJoin", "(J)I", (void*)PaintGlue::getStrokeJoin},
+ {"nSetStrokeJoin", "(JI)V", (void*)PaintGlue::setStrokeJoin},
+ {"nGetFillPath", "(JJJ)Z", (void*)PaintGlue::getFillPath},
+ {"nSetShader", "(JJ)J", (void*)PaintGlue::setShader},
+ {"nSetColorFilter", "(JJ)J", (void*)PaintGlue::setColorFilter},
+ {"nSetXfermode", "(JI)V", (void*)PaintGlue::setXfermode},
+ {"nSetPathEffect", "(JJ)J", (void*)PaintGlue::setPathEffect},
+ {"nSetMaskFilter", "(JJ)J", (void*)PaintGlue::setMaskFilter},
+ {"nSetTypeface", "(JJ)V", (void*)PaintGlue::setTypeface},
+ {"nGetTextAlign", "(J)I", (void*)PaintGlue::getTextAlign},
+ {"nSetTextAlign", "(JI)V", (void*)PaintGlue::setTextAlign},
+ {"nSetTextLocalesByMinikinLocaleListId", "(JI)V",
+ (void*)PaintGlue::setTextLocalesByMinikinLocaleListId},
+ {"nIsElegantTextHeight", "(J)Z", (void*)PaintGlue::isElegantTextHeight},
+ {"nSetElegantTextHeight", "(JZ)V", (void*)PaintGlue::setElegantTextHeight},
+ {"nGetTextSize", "(J)F", (void*)PaintGlue::getTextSize},
+ {"nSetTextSize", "(JF)V", (void*)PaintGlue::setTextSize},
+ {"nGetTextScaleX", "(J)F", (void*)PaintGlue::getTextScaleX},
+ {"nSetTextScaleX", "(JF)V", (void*)PaintGlue::setTextScaleX},
+ {"nGetTextSkewX", "(J)F", (void*)PaintGlue::getTextSkewX},
+ {"nSetTextSkewX", "(JF)V", (void*)PaintGlue::setTextSkewX},
+ {"nGetLetterSpacing", "(J)F", (void*)PaintGlue::getLetterSpacing},
+ {"nSetLetterSpacing", "(JF)V", (void*)PaintGlue::setLetterSpacing},
+ {"nGetWordSpacing", "(J)F", (void*)PaintGlue::getWordSpacing},
+ {"nSetWordSpacing", "(JF)V", (void*)PaintGlue::setWordSpacing},
+ {"nGetStartHyphenEdit", "(J)I", (void*)PaintGlue::getStartHyphenEdit},
+ {"nGetEndHyphenEdit", "(J)I", (void*)PaintGlue::getEndHyphenEdit},
+ {"nSetStartHyphenEdit", "(JI)V", (void*)PaintGlue::setStartHyphenEdit},
+ {"nSetEndHyphenEdit", "(JI)V", (void*)PaintGlue::setEndHyphenEdit},
+ {"nAscent", "(J)F", (void*)PaintGlue::ascent},
+ {"nDescent", "(J)F", (void*)PaintGlue::descent},
+ {"nGetUnderlinePosition", "(J)F", (void*)PaintGlue::getUnderlinePosition},
+ {"nGetUnderlineThickness", "(J)F", (void*)PaintGlue::getUnderlineThickness},
+ {"nGetStrikeThruPosition", "(J)F", (void*)PaintGlue::getStrikeThruPosition},
+ {"nGetStrikeThruThickness", "(J)F", (void*)PaintGlue::getStrikeThruThickness},
+ {"nSetShadowLayer", "(JFFFJJ)V", (void*)PaintGlue::setShadowLayer},
+ {"nHasShadowLayer", "(J)Z", (void*)PaintGlue::hasShadowLayer},
+ {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement},
};
-
int register_android_graphics_Paint(JNIEnv* env) {
return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods));
}
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index f4e965f422c0..2b9f15911f4d 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -59,6 +59,7 @@ interface ILocationManager
void registerLocationPendingIntent(String provider, in LocationRequest request, in PendingIntent pendingIntent, String packageName, @nullable String attributionTag);
void unregisterLocationPendingIntent(in PendingIntent pendingIntent);
+ @EnforcePermission(allOf={"LOCATION_HARDWARE", "ACCESS_FINE_LOCATION"})
void injectLocation(in Location location);
void requestListenerFlush(String provider, in ILocationListener listener, int requestCode);
@@ -113,8 +114,10 @@ interface ILocationManager
boolean isProviderPackage(@nullable String provider, String packageName, @nullable String attributionTag);
List<String> getProviderPackages(String provider);
+ @EnforcePermission("LOCATION_HARDWARE")
void setExtraLocationControllerPackage(String packageName);
String getExtraLocationControllerPackage();
+ @EnforcePermission("LOCATION_HARDWARE")
void setExtraLocationControllerPackageEnabled(boolean enabled);
boolean isExtraLocationControllerPackageEnabled();
@@ -125,7 +128,9 @@ interface ILocationManager
boolean isAdasGnssLocationEnabledForUser(int userId);
void setAdasGnssLocationEnabledForUser(boolean enabled, int userId);
+ @EnforcePermission("CONTROL_AUTOMOTIVE_GNSS")
boolean isAutomotiveGnssSuspended();
+ @EnforcePermission("CONTROL_AUTOMOTIVE_GNSS")
void setAutomotiveGnssSuspended(boolean suspended);
void addTestProvider(String name, in ProviderProperties properties,
diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java
index f3e15084d730..2031929514f3 100644
--- a/location/java/android/location/SatellitePvt.java
+++ b/location/java/android/location/SatellitePvt.java
@@ -539,7 +539,7 @@ public final class SatellitePvt implements Parcelable {
*
* <p>This field is valid if {@link #hasIssueOfDataEphemeris()} is true.
*/
- @IntRange(from = 0, to = 255)
+ @IntRange(from = 0, to = 1023)
public int getIssueOfDataEphemeris() {
return mIssueOfDataEphemeris;
}
@@ -847,8 +847,8 @@ public final class SatellitePvt implements Parcelable {
*/
@NonNull
public Builder setIssueOfDataEphemeris(
- @IntRange(from = 0, to = 255) int issueOfDataEphemeris) {
- Preconditions.checkArgumentInRange(issueOfDataEphemeris, 0, 255,
+ @IntRange(from = 0, to = 1023) int issueOfDataEphemeris) {
+ Preconditions.checkArgumentInRange(issueOfDataEphemeris, 0, 1023,
"issueOfDataEphemeris");
mIssueOfDataEphemeris = issueOfDataEphemeris;
mFlags = (byte) (mFlags | HAS_ISSUE_OF_DATA_EPHEMERIS);
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index e28178a8d5d8..f9b043f2525c 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -107,6 +107,7 @@ interface IAudioService {
boolean isMasterMute();
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
in String attributionTag);
@@ -118,27 +119,37 @@ interface IAudioService {
@UnsupportedAppUsage
int getStreamMaxVolume(int streamType);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
List<AudioVolumeGroup> getAudioVolumeGroups();
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags,
String callingPackage, in String attributionTag);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
int getVolumeIndexForAttributes(in AudioAttributes aa);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
int getMaxVolumeIndexForAttributes(in AudioAttributes aa);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
int getMinVolumeIndexForAttributes(in AudioAttributes aa);
+ @EnforcePermission("QUERY_AUDIO_STATE")
int getLastAudibleStreamVolume(int streamType);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
void setSupportedSystemUsages(in int[] systemUsages);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
int[] getSupportedSystemUsages();
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
List<AudioProductStrategy> getAudioProductStrategies();
boolean isMicrophoneMuted();
+ @EnforcePermission("ACCESS_ULTRASOUND")
boolean isUltrasoundSupported();
void setMicrophoneMute(boolean on, String callingPackage, int userId, in String attributionTag);
@@ -220,6 +231,7 @@ interface IAudioService {
IRingtonePlayer getRingtonePlayer();
int getUiSoundsStreamType();
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
void setWiredDeviceConnectionState(in AudioDeviceAttributes aa, int state, String caller);
@UnsupportedAppUsage
@@ -306,8 +318,10 @@ interface IAudioService {
int setPreferredDevicesForStrategy(in int strategy, in List<AudioDeviceAttributes> device);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
int removePreferredDevicesForStrategy(in int strategy);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
List<AudioDeviceAttributes> getPreferredDevicesForStrategy(in int strategy);
List<AudioDeviceAttributes> getDevicesForAttributes(in AudioAttributes attributes);
@@ -325,6 +339,7 @@ interface IAudioService {
oneway void setRttEnabled(in boolean rttEnabled);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
void setDeviceVolumeBehavior(in AudioDeviceAttributes device,
in int deviceVolumeBehavior, in String pkgName);
@@ -333,13 +348,16 @@ interface IAudioService {
// WARNING: read warning at top of file, new methods that need to be used by native
// code via IAudioManager.h need to be added to the top section.
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
oneway void setMultiAudioFocusEnabled(in boolean enabled);
int setPreferredDevicesForCapturePreset(
in int capturePreset, in List<AudioDeviceAttributes> devices);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
int clearPreferredDevicesForCapturePreset(in int capturePreset);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(in int capturePreset);
void registerCapturePresetDevicesRoleDispatcher(ICapturePresetDevicesRoleDispatcher dispatcher);
@@ -407,12 +425,16 @@ interface IAudioService {
boolean isSpatializerAvailable();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
boolean isSpatializerAvailableForDevice(in AudioDeviceAttributes device);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
boolean hasHeadTracker(in AudioDeviceAttributes device);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void setHeadTrackerEnabled(boolean enabled, in AudioDeviceAttributes device);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
boolean isHeadTrackerEnabled(in AudioDeviceAttributes device);
boolean isHeadTrackerAvailable();
@@ -420,6 +442,7 @@ interface IAudioService {
void registerSpatializerHeadTrackerAvailableCallback(
in ISpatializerHeadTrackerAvailableCallback cb, boolean register);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void setSpatializerEnabled(boolean enabled);
boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
@@ -428,46 +451,65 @@ interface IAudioService {
void unregisterSpatializerCallback(in ISpatializerCallback cb);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void registerSpatializerHeadTrackingCallback(in ISpatializerHeadTrackingModeCallback cb);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void unregisterSpatializerHeadTrackingCallback(in ISpatializerHeadTrackingModeCallback cb);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void registerHeadToSoundstagePoseCallback(in ISpatializerHeadToSoundStagePoseCallback cb);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void unregisterHeadToSoundstagePoseCallback(in ISpatializerHeadToSoundStagePoseCallback cb);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void addSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void removeSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void setDesiredHeadTrackingMode(int mode);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
int getDesiredHeadTrackingMode();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
int[] getSupportedHeadTrackingModes();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
int getActualHeadTrackingMode();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
oneway void setSpatializerGlobalTransform(in float[] transform);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
oneway void recenterHeadTracker();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void setSpatializerParameter(int key, in byte[] value);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void getSpatializerParameter(int key, inout byte[] value);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
int getSpatializerOutput();
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void registerSpatializerOutputCallback(in ISpatializerOutputCallback cb);
+ @EnforcePermission("MODIFY_DEFAULT_AUDIO_EFFECTS")
void unregisterSpatializerOutputCallback(in ISpatializerOutputCallback cb);
boolean isVolumeFixed();
VolumeInfo getDefaultVolumeInfo();
+ @EnforcePermission("CALL_AUDIO_INTERCEPTION")
boolean isPstnCallAudioInterceptable();
oneway void muteAwaitConnection(in int[] usagesToMute, in AudioDeviceAttributes dev,
@@ -475,8 +517,10 @@ interface IAudioService {
oneway void cancelMuteAwaitConnection(in AudioDeviceAttributes dev);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
AudioDeviceAttributes getMutingExpectedDevice();
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
void registerMuteAwaitConnectionDispatcher(in IMuteAwaitConnectionCallback cb,
boolean register);
@@ -486,22 +530,28 @@ interface IAudioService {
void registerDeviceVolumeBehaviorDispatcher(boolean register,
in IDeviceVolumeBehaviorDispatcher dispatcher);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
List<AudioFocusInfo> getFocusStack();
boolean sendFocusLoss(in AudioFocusInfo focusLoser, in IAudioPolicyCallback apcb);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
void addAssistantServicesUids(in int[] assistantUID);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
void removeAssistantServicesUids(in int[] assistantUID);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
void setActiveAssistantServiceUids(in int[] activeUids);
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
int[] getAssistantServicesUids();
+ @EnforcePermission("MODIFY_AUDIO_ROUTING")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
int[] getActiveAssistantServiceUids();
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index d7f3338f1f98..7b273580ebce 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -445,6 +445,14 @@ import java.util.concurrent.locks.ReentrantLock;
<td class=NA>Not Used</td>
<td class=NA>Not Used</td>
</tr>
+ <tr>
+ <td>AV1</td>
+ <td>AV1 <a href="https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax">
+ AV1CodecConfigurationRecord</a> Data (optional)
+ </td>
+ <td class=NA>Not Used</td>
+ <td class=NA>Not Used</td>
+ </tr>
</tbody>
</table>
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index d8995b419f50..57f105671ed4 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -102,6 +102,12 @@ public final class MediaRouter2 {
private final String mPackageName;
+ /**
+ * Stores the latest copy of all routes received from {@link MediaRouter2ServiceImpl}, without
+ * any filtering, sorting, or deduplication.
+ *
+ * <p>Uses {@link MediaRoute2Info#getId()} to set each entry's key.
+ */
@GuardedBy("mLock")
final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
@@ -121,7 +127,22 @@ public final class MediaRouter2 {
final Handler mHandler;
+ /**
+ * Stores an auxiliary copy of {@link #mFilteredRoutes} at the time of the last route callback
+ * dispatch. This is only used to determine what callback a route should be assigned to (added,
+ * removed, changed) in {@link #dispatchFilteredRoutesChangedLocked(List)}.
+ */
private volatile ArrayMap<String, MediaRoute2Info> mPreviousRoutes = new ArrayMap<>();
+
+ /**
+ * Stores the latest copy of exposed routes after filtering, sorting, and deduplication. Can be
+ * accessed through {@link #getRoutes()}.
+ *
+ * <p>This list is a copy of {@link #mRoutes} which has undergone filtering, sorting, and
+ * deduplication using criteria in {@link #mDiscoveryPreference}.
+ *
+ * @see #filterRoutesWithCompositePreferenceLocked(List)
+ */
private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 13f7ee6e8c8b..bbb4d1fa76bc 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -1161,6 +1161,10 @@ public class Tuner implements AutoCloseable {
public int tune(@NonNull FrontendSettings settings) {
mFrontendLock.lock();
try {
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
final int type = settings.getType();
if (mFrontendHandle != null && type != mFrontendType) {
Log.e(TAG, "Frontend was opened with type " + mFrontendType
@@ -1204,6 +1208,10 @@ public class Tuner implements AutoCloseable {
public int cancelTuning() {
mFrontendLock.lock();
try {
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
return nativeStopTune();
} finally {
mFrontendLock.unlock();
@@ -1237,6 +1245,10 @@ public class Tuner implements AutoCloseable {
mFrontendLock.lock();
try {
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
synchronized (mScanCallbackLock) {
// Scan can be called again for blink scan if scanCallback and executor are same as
//before.
@@ -1287,6 +1299,10 @@ public class Tuner implements AutoCloseable {
public int cancelScanning() {
mFrontendLock.lock();
try {
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
synchronized (mScanCallbackLock) {
FrameworkStatsLog.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SCAN_STOPPED);
@@ -1377,6 +1393,9 @@ public class Tuner implements AutoCloseable {
if (mFrontend == null) {
throw new IllegalStateException("frontend is not initialized");
}
+ if (mFeOwnerTuner != null) {
+ throw new IllegalStateException("Operation cannot be done by sharee of tuner");
+ }
return nativeGetFrontendStatus(statusTypes);
} finally {
mFrontendLock.unlock();
@@ -1480,6 +1499,10 @@ public class Tuner implements AutoCloseable {
mFrontendCiCamLock.lock();
mFrontendLock.lock();
try {
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
if (TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1,
"linkFrontendToCiCam")) {
@@ -1543,6 +1566,10 @@ public class Tuner implements AutoCloseable {
public int disconnectFrontendToCiCam(int ciCamId) {
acquireTRMSLock("disconnectFrontendToCiCam()");
try {
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
if (TunerVersionChecker.checkHigherOrEqualVersionTo(
TunerVersionChecker.TUNER_VERSION_1_1,
"unlinkFrontendToCiCam")) {
@@ -1591,6 +1618,10 @@ public class Tuner implements AutoCloseable {
if (mFrontend == null) {
throw new IllegalStateException("frontend is not initialized");
}
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
return nativeRemoveOutputPid(pid);
} finally {
mFrontendLock.unlock();
@@ -1621,6 +1652,9 @@ public class Tuner implements AutoCloseable {
if (mFrontend == null) {
throw new IllegalStateException("frontend is not initialized");
}
+ if (mFeOwnerTuner != null) {
+ throw new IllegalStateException("Operation cannot be done by sharee of tuner");
+ }
FrontendStatusReadiness[] readiness = nativeGetFrontendStatusReadiness(statusTypes);
if (readiness == null) {
return Collections.EMPTY_LIST;
@@ -1697,6 +1731,9 @@ public class Tuner implements AutoCloseable {
if (mFrontend == null) {
throw new IllegalStateException("frontend is not initialized");
}
+ if (mFeOwnerTuner != null) {
+ throw new IllegalStateException("Operation cannot be done by sharee of tuner");
+ }
return nativeGetFrontendHardwareInfo();
} finally {
mFrontendLock.unlock();
@@ -1726,6 +1763,10 @@ public class Tuner implements AutoCloseable {
if (maxNumber < 0) {
return RESULT_INVALID_ARGUMENT;
}
+ if (mFeOwnerTuner != null) {
+ Log.d(TAG, "Operation cannot be done by sharee of tuner");
+ return RESULT_INVALID_STATE;
+ }
int res = nativeSetMaxNumberOfFrontends(frontendType, maxNumber);
if (res == RESULT_SUCCESS) {
if (!mTunerResourceManager.setMaxNumberOfFrontends(frontendType, maxNumber)) {
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
index f6914efd6d83..23d6e34db4f1 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
@@ -22,8 +22,8 @@ import static com.android.server.backup.encryption.protos.nano.ChunksMetadataPro
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
index 096b2da10c98..bfc5d0dca3ff 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
@@ -18,9 +18,9 @@ package com.android.server.backup.encryption.tasks;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
index fa4fef50ac1a..222b88221ba2 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
@@ -19,8 +19,8 @@ package com.android.server.backup.encryption.tasks;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertFalse;
@@ -41,13 +41,6 @@ import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
import com.android.server.backup.testing.CryptoTestUtils;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.crypto.SecretKey;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -59,6 +52,14 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.crypto.SecretKey;
+
+
@RunWith(RobolectricTestRunner.class)
public class EncryptedKvBackupTaskTest {
private static final boolean INCREMENTAL = true;
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 03d8d50d788b..f51266c55a65 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stroom jou foon se programme"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 2b106bc1c8d2..b84ba922f5e0 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን ስልክ ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index d69ec1b62e4c..7c2f0fffb73b 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"بث تطبيقات هاتفك"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"تطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"يطلب التطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> لمشاركة التطبيقات بين أجهزتك."</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index fcdd8cddce3f..e79780c05955 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"আপোনাৰ ফ’নৰ এপ্‌ ষ্ট্ৰীম কৰক"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ফ’নৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index e8c11e84d492..4ef3111c23ac 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun tətbiqlərini yayımlayın"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 37f96c37c210..baf55d2174b4 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Strimujte aplikacije na telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 559fa9450027..cab8068609f7 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Трансліруйце змесціва праграм з вашага тэлефона"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў вашага тэлефона"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на перадачу праграм плынню паміж вашымі прыладамі"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 5e34bc754c64..16a785353d5d 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Поточно предаване на приложенията на телефона ви"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 381d5101a49e..b9b130f02388 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"আপনার ফোনের অ্যাপ স্ট্রিমিংয়ের মাধ্যমে কাস্ট করুন"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 5c57571fd431..8c941accbe40 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Prenosite aplikacije s telefona"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama s telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa ovim informacijama s vašeg telefona"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 80665cc7a8bc..eee184cc9580 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Reprodueix en continu aplicacions del telèfon"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per reproduir en continu aplicacions entre els dispositius"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index ac4dadcdbf1b..aff0cdaa93b6 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streamujte aplikace v telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 0e7a5b741b0c..a043978f3de1 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stream din telefons apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Giv &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; adgang til disse oplysninger fra din telefon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Tillad, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får adgang til disse oplysninger fra din telefon"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 8fed026e8368..a136841a64f6 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Smartphone-Apps streamen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 9f3b2ac47d1a..56d7dcde2a61 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 85a3275d8cf2..c80620ebad86 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 85a3275d8cf2..c80620ebad86 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 85a3275d8cf2..c80620ebad86 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 85a3275d8cf2..c80620ebad86 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Stream your phone’s apps"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index e95cc0dc5f0c..1b8833bd60cb 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎Stream your phone’s apps‎‏‎‎‏‎"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎Cross-device services‎‏‎‎‏‎"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to access your phone’s photos, media, and notifications‎‏‎‎‏‎"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps between your devices‎‏‎‎‏‎"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎Photos and media‎‏‎‎‏‎"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎Google Play services‎‏‎‎‏‎"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps between your devices‎‏‎‎‏‎"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to access your phone’s photos, media, and notifications‎‏‎‎‏‎"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎Allow‎‏‎‎‏‎"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 4797315bbb01..6bf4f6f124f6 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Transmitir las apps de tu teléfono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 7233e5673db8..a8c6be3ddcb7 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Emite las aplicaciones de tu teléfono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde tu teléfono"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 8dcf60a171f5..e56b6236735a 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefoni rakenduste voogesitamine"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotlevad teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 0db66f46ff7d..31ebe978b3b9 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Igorri zuzenean telefonoko aplikazioak"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Eman informazio hori telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 4e500cc4a9be..09fd7e48346b 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"جاری‌سازی برنامه‌های تلفن"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏اجازه دادن به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای دسترسی به اطلاعات تلفن"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویس‌های بین‌دستگاهی"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> به عکس‌ها، رسانه، و اعلان‌های تلفن شما دسترسی پیدا کند"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; مجاز می‌شود به این اطلاعات در دستگاهتان دسترسی پیدا کند"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"عکس‌ها و رسانه‌ها"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامه‌ها را بین دستگاه‌های شما جاری‌سازی کند"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index bb4e9a58ac78..6f44de6fce7b 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Striimaa puhelimen sovelluksia"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn näihin puhelimesi tietoihin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteeltasi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) lupaa striimata sovelluksia laitteidesi välillä"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index c6696d5b2b62..a10136bd43bb 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Diffusez les applications de votre téléphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 6d0e2d396af8..836d56201b94 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Diffuser en streaming les applis de votre téléphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 8eae0cb40da8..48110c45a83e 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Emite as aplicacións do teu teléfono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir aplicacións entre os teus aparellos"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 1186eddd650a..2f552ad1738d 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"તમારા ફોનની ઍપ સ્ટ્રીમ કરો"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ફોનના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index a8c6c6f6c605..e49b6537ce9a 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"अपने फ़ोन के ऐप्लिकेशन को स्ट्रीम करें"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रही हैं"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवाएं"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, डिवाइसों के बीच ऐप्लिकेशन को स्ट्रीम करने की अनुमति मांग रहा है"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 224bf69200f6..0c6d3a224395 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikacija vašeg telefona"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> da pristupi fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za emitiranje aplikacija između vaših uređaja"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za streamanje aplikacija između vaših uređaja"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index b06e28974f2d..b39854a9211a 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"A telefon alkalmazásainak streamelése"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 1fe333193acb..dfd18e49ca92 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Հեռարձակել հեռախոսի հավելվածները"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 2ee559d8726d..86c678e8feb5 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streaming aplikasi ponsel"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses informasi ini dari ponsel Anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses informasi ini dari ponsel Anda"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index f694d0f3b4a9..cf622e65e734 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streymdu forritum símans"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild fyrir straumspilun forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 3997a6e1ee66..baaf53e952a9 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Trasmetti in streaming le app del tuo telefono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a queste informazioni dal tuo telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a questa informazione dal tuo telefono"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 00b732ad973f..b4141253a163 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"שידור אפליקציות מהטלפון"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור ה‑<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index c2810636ff12..cf25568adad1 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャ"</string>
+ <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャー"</string>
<string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; へのアクセスを許可"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"スマートフォンのアプリのストリーミング"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"このスマートフォンからの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"許可"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 7db3d0c2ca96..514cefe66921 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"თქვენი ტელეფონის აპების სტრიმინგი"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის სტრიმინგი შეძლოს"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 58a625cbad64..e4027de705bc 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Телефон қолданбаларын трансляциялайды."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 7f3b93358d04..a4e59110a977 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ផ្សាយកម្មវិធីរបស់ទូរសព្ទអ្នក"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
@@ -35,11 +36,12 @@
<string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
- <string name="consent_no" msgid="2640796915611404382">"កុំអនុញ្ញាត"</string>
+ <string name="consent_no" msgid="2640796915611404382">"មិនអនុញ្ញាត"</string>
<string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"ផ្ដល់​ការអនុញ្ញាតឱ្យ​កម្មវិធីនៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ដូចនៅលើ &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ឬ?"</string>
<string name="permission_sync_summary" msgid="4866838188678457084">"&lt;p&gt;សកម្មភាពនេះ​អាចរួមបញ្ចូល​ការចូលប្រើ​ទីតាំង កាមេរ៉ា និងមីក្រូហ្វូន និងការអនុញ្ញាត​ដែលមានលក្ខណៈ​រសើបផ្សេងទៀត​នៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;។&lt;/p&gt; &lt;p&gt;អ្នកអាចប្ដូរ​ការអនុញ្ញាតទាំងនេះ​បានគ្រប់ពេលវេលា​នៅក្នុងការកំណត់​នៅលើ &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;។&lt;/p&gt;"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index e0f2fd5eb338..72d9318210cf 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ನಿಮ್ಮ ಫೋನ್‍ನ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ನಿಮ್ಮ ಫೋನ್‌ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 99acb18834df..ed6fc63b2b21 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"휴대전화의 앱을 스트리밍합니다."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 앱이 휴대전화에서 이 정보에 액세스하도록 허용합니다."</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"허용"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 63d6fbafcb46..63318cbd5fbd 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Телефондогу колдонмолорду алып ойнотуу"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиа"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду тышкы экранга чыгарууга уруксат сурап жатат"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ооба"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 910a527875ec..af79fab4dcd6 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຂອງໂທລະສັບທ່ານ"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 5edd78d0ae5a..f88eba907db8 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefono programų perdavimas srautu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 582cf84e4b25..f058e54df179 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Var straumēt jūsu tālruņa lietotnes"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 3393f360b4d3..23ced12a3338 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Стримувајте ги апликациите на телефонот"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index be36c5cc97f4..17f304536485 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"നിങ്ങളുടെ ഫോണിലെ ആപ്പുകൾ സ്‌ട്രീം ചെയ്യാൻ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിനു വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു."</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index dc52154d2b7e..1c74e48488f2 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Таны утасны аппуудыг дамжуулах"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс утасны зураг, медиа болон мэдэгдэлд хандахын тулд зөвшөөрөл хүсэж байна"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс төхөөрөмж хооронд апп дамжуулахын тулд зөвшөөрөл хүсэж байна"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index e5bdfd5afcab..3f83446133ce 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"फोनवरील ॲप्स स्ट्रीम करा"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 70d03731816a..bf1b537e9e7b 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Strim apl telefon anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses maklumat ini daripada telefon anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses maklumat ini daripada telefon anda"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index e47e834459a3..61272cc720c9 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်လွှင့်နိုင်သည်"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; အား သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုခြင်း"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် သင်၏ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 58d5f23838ca..5a4b911dc8e7 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Strøm appene på telefonen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å få tilgang til bilder, medier og varsler på telefonen din"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> for å strømme apper mellom enhetene dine"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index a056fcc3231a..9184bf576057 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index a3b4cef932f4..2039ee04fcca 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"De apps van je telefoon streamen"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 4fe9d0cba278..f7b22ca46cbc 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 5fdcd366ddd3..804574cae147 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index c890fbc27948..d7fd7b405fc9 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Odtwarzaj strumieniowo aplikacje z telefonu"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Zezwól aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania aplikacji między urządzeniami"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 87986f11b310..82ae48f5ee2a 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 0584694cc62c..87eba3daed14 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Faça stream das apps do telemóvel"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, conteúdo multimédia e notificações do seu telemóvel"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e multimédia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 87986f11b310..82ae48f5ee2a 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Faça streaming dos apps do seu smartphone"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 449dc86c37fa..619468e6eb43 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Să redea în stream aplicațiile telefonului"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permiteți ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele dvs."</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index b7f0547d3ec9..dcc98502535a 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Трансляция приложений с телефона."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает доступ от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 48674b781f1b..bf5361ea6bfa 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"ඔබගේ දුරකථනයේ යෙදුම් ප්‍රවාහ කරන්න"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්‍ය සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටී"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්‍ය"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටී"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්‍ය සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටියි"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 5c2ce5cd01d5..89ddd79424b3 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streamovanie aplikácií v telefóne"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 3b31abc49451..2c4e8ba2c07c 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Pretočno predvajanje aplikacij telefona"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index a63eaaa58cd5..ae35c027190e 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Transmeto aplikacionet e telefonit tënd"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 9d39188c7da3..0d05e1ac1b76 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Стримујте апликације на телефону"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 31dd2d8a6c7c..928201742978 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Streama telefonens appar"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index e906dc8089ed..4e281a85bc28 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Tiririsha programu za simu yako"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kufikia picha, maudhui na arifa za simu yako"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili kutiririsha programu kati ya vifaa vyako"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 1cba5e8f7e4f..a7eeae73182d 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"உங்கள் மொபைலின் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவும்"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"உங்கள் மொபைலிலிருந்து இந்தத் தகவலை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதியுங்கள்"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 96e760832d64..37bfea581050 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"మీ ఫోన్ యాప్‌లను స్ట్రీమ్ చేయండి"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> మీ ఫోన్ ఫోటోలు, మీడియా, నోటిఫికేషన్‌లను యాక్సెస్ చేయడానికి మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరపున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
@@ -35,10 +36,11 @@
<string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"మీ పరికరాల మధ్య యాప్‌లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరపున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
- <string name="consent_yes" msgid="8344487259618762872">"అనుమతించు"</string>
+ <string name="consent_yes" msgid="8344487259618762872">"అనుమతించండి"</string>
<string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
<string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
<string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;లోని యాప్‌లకు &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;లో ఉన్న అనుమతులను ఇవ్వాలా?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index d5ba74a8fbba..9be02097688a 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"สตรีมแอปของโทรศัพท์คุณ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนในโทรศัพท์ของคุณ"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 6376863649ce..e86bc41432a4 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"I-stream ang mga app ng iyong telepono"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyong ito sa iyong telepono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyon sa iyong telepono"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index bba7922582a1..008a02f6af8e 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefonunuzun uygulamalarını yayınlama"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 718fad35580f..062820e1cc6d 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Транслювати додатки телефона"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Надайте пристрою &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index ef93add2e454..8b6a14ae4d2c 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"اپنے فون کی ایپس کی سلسلہ بندی کریں"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‎ کو اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی اجازت دیں"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت طلب کر رہی ہے"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏اپنے فون سے اس معلومات تک رسائی حاصل Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کرنے کی اجازت دیں"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"‏Google Play سروسز"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 1813857d3166..5c1262c85304 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Telefondagi ilovalarni translatsiya qilish"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 045547b0e61b..b29e08c8d382 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Truyền các ứng dụng trên điện thoại của bạn"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string>
+ <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
@@ -35,7 +35,7 @@
<string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
+ <string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 06a8b3eaab81..7b95bad7adaf 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"流式传输手机上的应用"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”&lt;strong&gt;&lt;/strong&gt;访问您手机中的这项信息"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允许 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 访问您手机中的这项信息"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允许"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 6956affe9092..cb32f8b4b9b3 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"串流播放手機應用程式內容"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便存取手機上的相片、媒體和通知"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求必要權限,以便在裝置之間串流應用程式內容"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 8d4623a7c676..bafeaaf8c975 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"串流傳輸手機應用程式內容"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取手機中的這項資訊"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便存取手機上的相片、媒體和通知"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資訊"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"允許"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index c6697367c5fe..e148d0a82739 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -25,7 +25,8 @@
<string name="permission_apps_summary" msgid="798718816711515431">"Sakaza ama-app wefoni yakho"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifinyelele lolu lwazi kusukela efonini yakho"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
- <string name="helper_summary_app_streaming" msgid="7380294597268573523">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string>
+ <!-- no translation found for helper_summary_app_streaming (5977509499890099) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Vumela &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukufinyelela lolu lwazi kusuka efonini yakho"</string>
@@ -35,7 +36,8 @@
<string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string>
- <string name="helper_summary_computer" msgid="1676407599909474428">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
+ <!-- no translation found for helper_summary_computer (9050724687678157852) -->
+ <skip />
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="summary_generic" msgid="2346762210105903720"></string>
<string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-or/strings.xml b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
index 05b9016d45b0..b5ec29259f7c 100644
--- a/packages/DynamicSystemInstallationService/res/values-or/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
@@ -7,7 +7,7 @@
<string name="notification_install_failed" msgid="4066039210317521404">"ଇନଷ୍ଟଲ୍ କରିବା ବିଫଳ ହୋଇଛି"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"ଇମେଜ୍ ବୈଧକରଣ ବିଫଳ ହୋଇଛି। ଇନଷ୍ଟଲେସନ୍ ରଦ୍ଦ କରନ୍ତୁ।"</string>
<string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ବର୍ତ୍ତମାନ ଏକ ଡାଇନାମିକ୍ ସିଷ୍ଟମ୍ ଚାଲୁଛି। ମୂଳ Android ସଂସ୍କରଣ ବ୍ୟବହାର କରିବାକୁ ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ।"</string>
- <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+ <string name="notification_action_cancel" msgid="5929299408545961077">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="notification_action_discard" msgid="1817481003134947493">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
<string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml
index 2c53626e55f8..88d55f2ff32a 100644
--- a/packages/InputDevices/res/values-zu/strings.xml
+++ b/packages/InputDevices/res/values-zu/strings.xml
@@ -3,51 +3,51 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="8016145283189546017">"Amadivayisi wokufaka"</string>
<string name="keyboard_layouts_label" msgid="6688773268302087545">"Ikhibhodi ye-Android"</string>
- <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"I-English (UK)"</string>
- <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"I-English (US)"</string>
- <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"I-English (US), isitayela sakwamanye amazwe"</string>
- <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"I-English (US), isitayela se-Colemak"</string>
- <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"I-English (US), isitayela se-Dvorak"</string>
- <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"I-English (US), isitayela sokusebenza"</string>
- <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Isi-German"</string>
- <string name="keyboard_layout_french_label" msgid="813450119589383723">"Isi-French"</string>
- <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Isi-French (Canada)"</string>
+ <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string>
+ <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string>
+ <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), isitayela sakwamanye amazwe"</string>
+ <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), isitayela se-Colemak"</string>
+ <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), isitayela se-Dvorak"</string>
+ <string name="keyboard_layout_english_us_workman_label" msgid="2944541595262173111">"English (US), isitayela sokusebenza"</string>
+ <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+ <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+ <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
<string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Isi-Russian"</string>
<string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Isi-Russian, isitayela se-Mac"</string>
- <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Isi-Spanish"</string>
+ <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
<string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Isi-Swiss French"</string>
<string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Isi-Swiss German"</string>
<string name="keyboard_layout_belgian" msgid="2011984572838651558">"Isi-Belgian"</string>
<string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Isi-Bulgarian"</string>
<string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"Isi-Bulgarian, Ifonetiki"</string>
- <string name="keyboard_layout_italian" msgid="6497079660449781213">"Isi-Italian"</string>
- <string name="keyboard_layout_danish" msgid="8036432066627127851">"Isi-Danish"</string>
- <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Isi-Norwegian"</string>
- <string name="keyboard_layout_swedish" msgid="732959109088479351">"Isi-Swedish"</string>
- <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Isi-Finnish"</string>
+ <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+ <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+ <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+ <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+ <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
<string name="keyboard_layout_croatian" msgid="4172229471079281138">"Isi-Croatian"</string>
- <string name="keyboard_layout_czech" msgid="1349256901452975343">"Isi-Czech"</string>
+ <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
<string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Isitayela se-Czech QWERTY"</string>
<string name="keyboard_layout_estonian" msgid="8775830985185665274">"Isi-Estonian"</string>
- <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Isi-Hungarian"</string>
- <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Isi-Icelandic"</string>
+ <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+ <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
<string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Isi-Brazilian"</string>
- <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Isi-Portuguese"</string>
+ <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
<string name="keyboard_layout_slovak" msgid="2469379934672837296">"Isi-Slovak"</string>
- <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Isi-Slovenian"</string>
- <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Isi-Turkish"</string>
+ <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+ <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
<string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"I-Turkish-F"</string>
<string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Isi-Ukrainian"</string>
- <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Isi-Arabic"</string>
- <string name="keyboard_layout_greek" msgid="7289253560162386040">"Isi-Greek"</string>
- <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Isi-Hebrew"</string>
- <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Isi-Lithuanian"</string>
- <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Isi-Spanish (Latin)"</string>
- <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Isi-Latvian"</string>
- <string name="keyboard_layout_persian" msgid="3920643161015888527">"Isi-Persian"</string>
- <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Isi-Azebhayijani"</string>
- <string name="keyboard_layout_polish" msgid="1121588624094925325">"Isi-Polish"</string>
- <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Isi-Belarusian"</string>
+ <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabic"</string>
+ <string name="keyboard_layout_greek" msgid="7289253560162386040">"Greek"</string>
+ <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrew"</string>
+ <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lithuanian"</string>
+ <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Spanish (Latin)"</string>
+ <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Latvian"</string>
+ <string name="keyboard_layout_persian" msgid="3920643161015888527">"Persian"</string>
+ <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Azerbaijani"</string>
+ <string name="keyboard_layout_polish" msgid="1121588624094925325">"Polish"</string>
+ <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusian"</string>
<string name="keyboard_layout_mongolian" msgid="7678483495823936626">"isi-Mongolian"</string>
- <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Okwesi-Georgian"</string>
+ <string name="keyboard_layout_georgian" msgid="4596185456863747454">"Georgian"</string>
</resources>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index fac338bca0a8..fe6edcea8dd8 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -85,8 +85,8 @@
<string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
<string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Baliteke telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea."</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
- <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Baliteke tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu hura erabiltzeagatik tabletari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea zeu izango zarela."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Baliteke telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu hura erabiltzeagatik telebistari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea zeu izango zarela."</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Ezarpenak"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Wear aplikazioak instalatzea/desinstalatzea"</string>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index 4bc5bec46543..75d5d2ddb1ce 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -20,7 +20,7 @@
<string name="install" msgid="711829760615509273">"ଇନଷ୍ଟଲ୍‍ କରନ୍ତୁ"</string>
<string name="update" msgid="3932142540719227615">"ଅପଡେଟ୍ କରନ୍ତୁ"</string>
<string name="done" msgid="6632441120016885253">"ହୋଇଗଲା"</string>
- <string name="cancel" msgid="1018267193425558088">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+ <string name="cancel" msgid="1018267193425558088">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="installing" msgid="4921993079741206516">"ଇନଷ୍ଟଲ୍‌ କରାଯାଉଛି…"</string>
<string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଇନଷ୍ଟଲ୍‌ କରାଯାଉଛି…"</string>
<string name="install_done" msgid="5987363587661783896">"ଆପ ଇନଷ୍ଟଲ ହୋଇଗଲା।"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
index 36294ac040a6..c9230b4ebf5b 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -69,7 +69,7 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
getContext().getPackageManager().getApplicationInfo(pkg, 0).storageUuid,
pkg, user);
return stats.getDataBytes();
- } catch (PackageManager.NameNotFoundException | IOException e) {
+ } catch (PackageManager.NameNotFoundException | IOException | SecurityException e) {
Log.e(LOG_TAG, "Cannot determine amount of app data for " + pkg, e);
}
diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml
index fa10909b92ed..6f215d3af18b 100644
--- a/packages/PrintSpooler/res/values-or/strings.xml
+++ b/packages/PrintSpooler/res/values-or/strings.xml
@@ -83,7 +83,7 @@
<string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ବାତିଲ୍‍ କରାଯାଉଛି"</string>
<string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ପ୍ରିଣ୍ଟର୍‍ ତ୍ରୁଟି"</string>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"ପ୍ରିଣ୍ଟର୍‍ ଦ୍ୱାରା ରୋକାଯାଇଥିବା <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
- <string name="cancel" msgid="4373674107267141885">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+ <string name="cancel" msgid="4373674107267141885">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="restart" msgid="2472034227037808749">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"ପ୍ରିଣ୍ଟର୍‍କୁ କୌଣସି ସଂଯୋଗ ନାହିଁ"</string>
<string name="reason_unknown" msgid="5507940196503246139">"ଅଜଣା"</string>
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 87e61b527477..a83c090df771 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -13,12 +13,15 @@ android_library {
static_libs: [
"androidx.annotation_annotation",
- "androidx.legacy_legacy-support-v4",
- "androidx.recyclerview_recyclerview",
- "androidx.preference_preference",
"androidx.appcompat_appcompat",
+ "androidx.coordinatorlayout_coordinatorlayout",
+ "androidx.core_core",
+ "androidx.fragment_fragment",
"androidx.lifecycle_lifecycle-runtime",
- "androidx.mediarouter_mediarouter-nodeps",
+ "androidx.loader_loader",
+ "androidx.localbroadcastmanager_localbroadcastmanager",
+ "androidx.preference_preference",
+ "androidx.recyclerview_recyclerview",
"com.google.android.material_material",
"iconloader",
@@ -74,13 +77,15 @@ java_defaults {
name: "SettingsLibDefaults",
static_libs: [
"androidx.annotation_annotation",
- "androidx.lifecycle_lifecycle-common",
- "androidx.legacy_legacy-support-v4",
+ "androidx.appcompat_appcompat",
+ "androidx.coordinatorlayout_coordinatorlayout",
+ "androidx.core_core",
+ "androidx.fragment_fragment",
"androidx.lifecycle_lifecycle-runtime",
- "androidx.recyclerview_recyclerview",
+ "androidx.loader_loader",
+ "androidx.localbroadcastmanager_localbroadcastmanager",
"androidx.preference_preference",
- "androidx.appcompat_appcompat",
- "androidx.legacy_legacy-preference-v14",
+ "androidx.recyclerview_recyclerview",
"SettingsLib",
],
}
diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk
index 8c309ff97370..d9596569a0da 100644
--- a/packages/SettingsLib/common.mk
+++ b/packages/SettingsLib/common.mk
@@ -19,15 +19,17 @@
# NOTE: keep this file and ./Android.bp in sync.
LOCAL_STATIC_JAVA_LIBRARIES += \
- androidx.annotation_annotation \
- androidx.lifecycle_lifecycle-common
+ androidx.annotation_annotation
LOCAL_STATIC_ANDROID_LIBRARIES += \
- androidx.legacy_legacy-support-v4 \
+ androidx.appcompat_appcompat \
+ androidx.coordinatorlayout_coordinatorlayout \
+ androidx.core_core \
+ androidx.fragment_fragment \
androidx.lifecycle_lifecycle-runtime \
- androidx.recyclerview_recyclerview \
+ androidx.loader_loader \
+ androidx.localbroadcastmanager_localbroadcastmanager \
androidx.preference_preference \
- androidx.appcompat_appcompat \
- androidx.legacy_legacy-preference-v14 \
+ androidx.recyclerview_recyclerview \
SettingsLib
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 1ccc1b3d280e..6eef0534e61b 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -667,7 +667,7 @@
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"ነባሪ"</string>
<string name="turn_screen_on_title" msgid="3266937298097573424">"ማያ ገጽን ያብሩ"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"ማያ ገጹን ማብራት ይፍቀዱ"</string>
- <string name="allow_turn_screen_on_description" msgid="43834403291575164">"አንድ መተግበሪያ ማያ ገጹን እንዲያበራ ይፍቀዱለት። ከተሰጠ፣ መተግበሪያው ያለእርስዎ ግልጽ ሐሳብ በማንኛውም ጊዜ ማያ ገጹን ሊያበራ ይችላል።"</string>
+ <string name="allow_turn_screen_on_description" msgid="43834403291575164">"አንድ መተግበሪያ ማያ ገጹን እንዲያበራ ይፍቀዱለት። ከተሰጠ፣ መተግበሪያው ያለእርስዎ ግልፅ ሐሳብ በማንኛውም ጊዜ ማያ ገጹን ሊያበራ ይችላል።"</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 718624872934..03c72bcdc2e0 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -665,7 +665,7 @@
<string name="physical_keyboard_title" msgid="4811935435315835220">"Fyysinen näppäimistö"</string>
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Valitse näppäimistöasettelu"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Oletus"</string>
- <string name="turn_screen_on_title" msgid="3266937298097573424">"Käynnistä näyttö"</string>
+ <string name="turn_screen_on_title" msgid="3266937298097573424">"Näytön käynnistys"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Salli näytön käynnistäminen"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Salli sovelluksen käynnistää näyttö. Jos sovellus saa luvan, se voi käynnistää näytön itsenäisesti milloin tahansa."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index f2aa3b6173b5..fbe89e399ec7 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -148,7 +148,7 @@
<string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIO ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"ପେୟାର୍‌"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ପେୟାର୍‌"</string>
- <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ବାତିଲ୍‌ କରନ୍ତୁ"</string>
+ <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ପେୟାରିଂ ଫଳରେ ସଂଯୁକ୍ତ ଥିବା ବେଳେ ଆପଣଙ୍କ ସମ୍ପର୍କଗୁଡ଼ିକୁ ଏବଂ କଲ୍‌ର ଇତିବୃତିକୁ ଆକସେସ୍‌ ମଞ୍ଜୁର ହୁଏ।"</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିହେଲା ନାହିଁ।"</string>
<string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ଏକ ଭୁଲ୍‌ PIN କିମ୍ବା ପାସକୀ କାରଣରୁ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିପାରିଲା ନାହିଁ।"</string>
@@ -305,7 +305,7 @@
<string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ବ୍ୟକ୍ତିଗତ DNS"</string>
<string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
<string name="private_dns_mode_off" msgid="7065962499349997041">"ବନ୍ଦ"</string>
- <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ସ୍ଵଚାଳିତ"</string>
+ <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ଅଟୋମେଟିକ"</string>
<string name="private_dns_mode_provider" msgid="3619040641762557028">"ବ୍ୟକ୍ତିଗତ DNS ପ୍ରଦାତା ହୋଷ୍ଟନାମ"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ପ୍ରଦାନକାରୀଙ୍କ ହୋଷ୍ଟନାମ ଲେଖନ୍ତୁ"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
@@ -524,7 +524,7 @@
<string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}=1{1ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}other{#ଟି ଡିଭାଇସ ସଂଯୁକ୍ତ ହୋଇଛି}}"</string>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"ଅଧିକ ସମୟ।"</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"କମ୍ ସମୟ।"</string>
- <string name="cancel" msgid="5665114069455378395">"ବାତିଲ୍"</string>
+ <string name="cancel" msgid="5665114069455378395">"ବାତିଲ"</string>
<string name="okay" msgid="949938843324579502">"ଠିକ୍‌ ଅଛି"</string>
<string name="done" msgid="381184316122520313">"ହୋଇଗଲା"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
@@ -624,7 +624,7 @@
<string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ଡିଭାଇସ୍ ଡିଫଲ୍ଟ"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string>
- <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ୍ କରନ୍ତୁ।"</string>
+ <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ କରନ୍ତୁ।"</string>
<string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"ତାରଯୁକ୍ତ ହେଡଫୋନ୍"</string>
<string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"ଚାଲୁ ଅଛି"</string>
<string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"ବନ୍ଦ ଅଛି"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index a5b9f79325fd..513fb6e87a10 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -50,8 +50,8 @@
</string-array>
<string-array name="hdcp_checking_titles">
<item msgid="2377230797542526134">"ఎప్పటికీ తనిఖీ చేయవద్దు"</item>
- <item msgid="3919638466823112484">"DRM కంటెంట్‌కు మాత్రమే తనిఖీ చేయండి"</item>
- <item msgid="9048424957228926377">"ఎల్లప్పుడూ తనిఖీ చేయండి"</item>
+ <item msgid="3919638466823112484">"DRM కంటెంట్‌కు మాత్రమే చెక్ చేయండి"</item>
+ <item msgid="9048424957228926377">"ఎల్లప్పుడూ చెక్ చేయండి"</item>
</string-array>
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"ఎప్పటికీ HDCP తనిఖీని ఉపయోగించవద్దు"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index f89775f16747..3f82d47ddb66 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -204,7 +204,7 @@
<string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g>కి పూర్తి మద్దతు ఉంది"</string>
<string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g>కి నెట్‌వర్క్ కనెక్షన్ అవసరం"</string>
<string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g>కు మద్దతు లేదు"</string>
- <string name="tts_status_checking" msgid="8026559918948285013">"తనిఖీ చేస్తోంది..."</string>
+ <string name="tts_status_checking" msgid="8026559918948285013">"చెక్ చేస్తోంది..."</string>
<string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> కోసం సెట్టింగ్‌లు"</string>
<string name="tts_engine_settings_button" msgid="477155276199968948">"ఇంజిన్ సెట్టింగ్‌లను ప్రారంభించండి"</string>
<string name="tts_engine_preference_section_title" msgid="3861562305498624904">"ప్రాధాన్య ఇంజిన్"</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"అభివృద్ధి సెట్టింగ్‌లను అనుమతించాలా?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"ఈ సెట్టింగ్‌లు అభివృద్ధి వినియోగం కోసం మాత్రమే ఉద్దేశించబడినవి. వీటి వలన మీ పరికరం మరియు దీనిలోని యాప్‌లు విచ్ఛిన్నం కావచ్చు లేదా తప్పుగా ప్రవర్తించవచ్చు."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB ద్వారా యాప్‌లను వెరిఫై చేయి"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన యాప్‌లను తనిఖీ చేయి."</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన యాప్‌లను చెక్ చేయండి."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"పేర్లు (MAC అడ్రస్‌లు మాత్రమే) లేని బ్లూటూత్ పరికరాలు డిస్‌ప్లే కాబడతాయి"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"రిమోట్ పరికరాల్లో ఆమోదించలేని స్థాయిలో అధిక వాల్యూమ్ ఉండటం లేదా వాల్యూమ్ కంట్రోల్ లేకపోవడం వంటి సమస్యలు ఉంటే బ్లూటూత్ సంపూర్ణ వాల్యూమ్ ఫీచర్‌ను డిజేబుల్ చేస్తుంది."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"బ్లూటూత్ Gabeldorsche ఫీచర్ స్ట్యాక్‌ను ఎనేబుల్ చేస్తుంది."</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index d6d73046bed3..281501e6043c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
import android.media.RoutingSessionInfo;
import android.os.Build;
import android.text.TextUtils;
@@ -83,6 +84,7 @@ public class LocalMediaManager implements BluetoothCallback {
private InfoMediaManager mInfoMediaManager;
private String mPackageName;
private MediaDevice mOnTransferBluetoothDevice;
+ private AudioManager mAudioManager;
@VisibleForTesting
List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
@@ -126,6 +128,7 @@ public class LocalMediaManager implements BluetoothCallback {
mPackageName = packageName;
mLocalBluetoothManager =
LocalBluetoothManager.getInstance(context, /* onInitCallback= */ null);
+ mAudioManager = context.getSystemService(AudioManager.class);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mLocalBluetoothManager == null) {
Log.e(TAG, "Bluetooth is not supported on this device");
@@ -148,6 +151,7 @@ public class LocalMediaManager implements BluetoothCallback {
mInfoMediaManager = infoMediaManager;
mPackageName = packageName;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mAudioManager = context.getSystemService(AudioManager.class);
}
/**
@@ -527,13 +531,16 @@ public class LocalMediaManager implements BluetoothCallback {
synchronized (mMediaDevicesLock) {
mMediaDevices.clear();
mMediaDevices.addAll(devices);
- // Add disconnected bluetooth devices only when phone output device is available.
+ // Add muting expected bluetooth devices only when phone output device is available.
for (MediaDevice device : devices) {
final int type = device.getDeviceType();
if (type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE
|| type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE
|| type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE) {
- mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
+ MediaDevice mutingExpectedDevice = getMutingExpectedDevice();
+ if (mutingExpectedDevice != null) {
+ mMediaDevices.add(mutingExpectedDevice);
+ }
break;
}
}
@@ -552,6 +559,34 @@ public class LocalMediaManager implements BluetoothCallback {
}
}
+ private MediaDevice getMutingExpectedDevice() {
+ if (mBluetoothAdapter == null
+ || mAudioManager.getMutingExpectedDevice() == null) {
+ Log.w(TAG, "BluetoothAdapter is null or muting expected device not exist");
+ return null;
+ }
+ final List<BluetoothDevice> bluetoothDevices =
+ mBluetoothAdapter.getMostRecentlyConnectedDevices();
+ final CachedBluetoothDeviceManager cachedDeviceManager =
+ mLocalBluetoothManager.getCachedDeviceManager();
+ for (BluetoothDevice device : bluetoothDevices) {
+ final CachedBluetoothDevice cachedDevice =
+ cachedDeviceManager.findDevice(device);
+ if (isBondedMediaDevice(cachedDevice) && isMutingExpectedDevice(cachedDevice)) {
+ return new BluetoothMediaDevice(mContext,
+ cachedDevice,
+ null, null, mPackageName);
+ }
+ }
+ return null;
+ }
+
+ private boolean isMutingExpectedDevice(CachedBluetoothDevice cachedDevice) {
+ return mAudioManager.getMutingExpectedDevice() != null
+ && cachedDevice.getAddress().equals(
+ mAudioManager.getMutingExpectedDevice().getAddress());
+ }
+
private List<MediaDevice> buildDisconnectedBluetoothDevice() {
if (mBluetoothAdapter == null) {
Log.w(TAG, "buildDisconnectedBluetoothDevice() BluetoothAdapter is null");
@@ -595,6 +630,13 @@ public class LocalMediaManager implements BluetoothCallback {
return new ArrayList<>(mDisconnectedMediaDevices);
}
+ private boolean isBondedMediaDevice(CachedBluetoothDevice cachedDevice) {
+ return cachedDevice != null
+ && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
+ && !cachedDevice.isConnected()
+ && isMediaDevice(cachedDevice);
+ }
+
private boolean isMediaDevice(CachedBluetoothDevice device) {
for (LocalBluetoothProfile profile : device.getConnectableProfiles()) {
if (profile instanceof A2dpProfile || profile instanceof HearingAidProfile ||
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
index 1f2297ba3a0c..fc2bf0a9bd93 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java
@@ -21,10 +21,10 @@ import static android.os.UserHandle.MU_ENABLED;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
index 95f7ef41b10b..508dffc2fa21 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
@@ -18,7 +18,7 @@ package com.android.settingslib.net;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
index 69484ed527b5..f760032e4a40 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import android.app.Activity;
@@ -147,7 +147,7 @@ public class EditUserInfoControllerTest {
dialog.show();
dialog.cancel();
- verifyZeroInteractions(successCallback);
+ verifyNoInteractions(successCallback);
verify(cancelCallback, times(1))
.run();
}
@@ -163,7 +163,7 @@ public class EditUserInfoControllerTest {
dialog.show();
dialog.getButton(Dialog.BUTTON_NEGATIVE).performClick();
- verifyZeroInteractions(successCallback);
+ verifyNoInteractions(successCallback);
verify(cancelCallback, times(1))
.run();
}
@@ -184,7 +184,7 @@ public class EditUserInfoControllerTest {
verify(successCallback, times(1))
.accept("test", oldUserIcon);
- verifyZeroInteractions(cancelCallback);
+ verifyNoInteractions(cancelCallback);
}
@Test
@@ -202,7 +202,7 @@ public class EditUserInfoControllerTest {
verify(successCallback, times(1))
.accept("test", null);
- verifyZeroInteractions(cancelCallback);
+ verifyNoInteractions(cancelCallback);
}
@Test
@@ -223,7 +223,7 @@ public class EditUserInfoControllerTest {
verify(successCallback, times(1))
.accept(expectedNewName, mCurrentIcon);
- verifyZeroInteractions(cancelCallback);
+ verifyNoInteractions(cancelCallback);
}
@Test
@@ -242,7 +242,7 @@ public class EditUserInfoControllerTest {
verify(successCallback, times(1))
.accept("test", newPhoto);
- verifyZeroInteractions(cancelCallback);
+ verifyNoInteractions(cancelCallback);
}
@Test
@@ -261,7 +261,7 @@ public class EditUserInfoControllerTest {
verify(successCallback, times(1))
.accept("test", newPhoto);
- verifyZeroInteractions(cancelCallback);
+ verifyNoInteractions(cancelCallback);
}
@Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
index 0b3495def21f..ca0aa0d7b900 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/UpdatableListPreferenceDialogFragmentTest.java
@@ -56,7 +56,7 @@ public class UpdatableListPreferenceDialogFragmentTest {
mUpdatableListPrefDlgFragment = spy(UpdatableListPreferenceDialogFragment
.newInstance(KEY, MetricsProto.MetricsEvent.DIALOG_SWITCH_A2DP_DEVICES));
- mEntries = spy(new ArrayList<>());
+ mEntries = new ArrayList<>();
mUpdatableListPrefDlgFragment.setEntries(mEntries);
mUpdatableListPrefDlgFragment
.setMetricsCategory(mUpdatableListPrefDlgFragment.getArguments());
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index 3ad3f34c013f..298bbbdda89b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -92,7 +92,7 @@ public class GlobalSettings {
Settings.Global.Wearable.AMBIENT_ENABLED,
Settings.Global.Wearable.AMBIENT_TILT_TO_WAKE,
Settings.Global.Wearable.AMBIENT_TOUCH_TO_WAKE,
- Settings.Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE,
+ Settings.Global.Wearable.GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED,
Settings.Global.Wearable.BATTERY_SAVER_MODE,
Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS,
Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index d1ba27e6ddea..796b4c453f00 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -51,6 +51,7 @@ public class GlobalSettingsValidators {
|| (val == BatteryManager.BATTERY_PLUGGED_AC)
|| (val == BatteryManager.BATTERY_PLUGGED_USB)
|| (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
+ || (val == BatteryManager.BATTERY_PLUGGED_DOCK)
|| (val
== (BatteryManager.BATTERY_PLUGGED_AC
| BatteryManager.BATTERY_PLUGGED_USB))
@@ -58,12 +59,29 @@ public class GlobalSettingsValidators {
== (BatteryManager.BATTERY_PLUGGED_AC
| BatteryManager.BATTERY_PLUGGED_WIRELESS))
|| (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_DOCK))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+ || (val
== (BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_DOCK))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_WIRELESS
+ | BatteryManager.BATTERY_PLUGGED_DOCK))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB
| BatteryManager.BATTERY_PLUGGED_WIRELESS))
|| (val
== (BatteryManager.BATTERY_PLUGGED_AC
| BatteryManager.BATTERY_PLUGGED_USB
- | BatteryManager.BATTERY_PLUGGED_WIRELESS));
+ | BatteryManager.BATTERY_PLUGGED_DOCK))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS
+ | BatteryManager.BATTERY_PLUGGED_DOCK));
} catch (NumberFormatException e) {
return false;
}
@@ -313,7 +331,8 @@ public class GlobalSettingsValidators {
VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.COOLDOWN_MODE_ON, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ Global.Wearable.GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.SCREEN_UNLOCK_SOUND_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.BEDTIME_MODE, BOOLEAN_VALIDATOR);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 2d384c233f10..b31e36c417ab 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -596,6 +596,9 @@
<!-- Permission required for CTS test - ClipboardManagerTest -->
<uses-permission android:name="android.permission.SET_CLIP_SOURCE" />
+ <!-- Permission required for CTS test - CtsInputMethodTestCases -->
+ <uses-permission android:name="android.permission.TEST_INPUT_METHOD" />
+
<!-- Permission required for CTS test - FontManagerTest -->
<uses-permission android:name="android.permission.UPDATE_FONTS" />
diff --git a/packages/Shell/res/values-pa/strings.xml b/packages/Shell/res/values-pa/strings.xml
index daeac3cf0b04..57ad5e25fb8f 100644
--- a/packages/Shell/res/values-pa/strings.xml
+++ b/packages/Shell/res/values-pa/strings.xml
@@ -39,7 +39,7 @@
<string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string>
<string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ।"</string>
<string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਵੇਰਵੇ"</string>
- <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਨਾਮ"</string>
+ <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਦਾ ਨਾਮ"</string>
<string name="bugreport_info_title" msgid="2306030793918239804">"ਬੱਗ ਸਿਰਲੇਖ"</string>
<string name="bugreport_info_description" msgid="5072835127481627722">"ਬੱਗ ਸਾਰਾਂਸ਼"</string>
<string name="save" msgid="4781509040564835759">"ਰੱਖਿਅਤ ਕਰੋ"</string>
diff --git a/packages/SimAppDialog/res/values-fa/strings.xml b/packages/SimAppDialog/res/values-fa/strings.xml
index 7eb87dddf41d..74e81a42e675 100644
--- a/packages/SimAppDialog/res/values-fa/strings.xml
+++ b/packages/SimAppDialog/res/values-fa/strings.xml
@@ -21,6 +21,6 @@
<string name="install_carrier_app_title" msgid="334729104862562585">"سرویس دستگاه همراه را فعال کنید"</string>
<string name="install_carrier_app_description" msgid="4014303558674923797">"برای اینکه سیم‌کارت جدیدتان به‌درستی کار کند، باید برنامه <xliff:g id="ID_1">%1$s</xliff:g> را نصب کنید"</string>
<string name="install_carrier_app_description_default" msgid="7356830245205847840">"برای اینکه سیم‌کارت جدیدتان به‌درستی کار کند، باید برنامه شرکت مخابراتی را نصب کنید"</string>
- <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"الآن نه"</string>
+ <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"حالا نه"</string>
<string name="install_carrier_app_download_action" msgid="7859229305958538064">"بارگیری برنامه"</string>
</resources>
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index f9a9ef65cab6..154a6fca9d09 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -102,7 +102,7 @@
//
// If you don't use @Staging or @Postsubmit, your new test will immediately
// block presubmit, which is probably not what you want!
- "platinum-postsubmit": [
+ "sysui-platinum-postsubmit": [
{
"name": "PlatformScenarioTests",
"options": [
@@ -121,7 +121,7 @@
]
}
],
- "staged-platinum-postsubmit": [
+ "sysui-staged-platinum-postsubmit": [
{
"name": "PlatformScenarioTests",
"options": [
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index 4b0c62bff60d..cc7d23e97d0c 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -106,7 +106,7 @@ class ViewHierarchyAnimator {
ephemeral: Boolean
): Boolean {
if (
- !isVisible(
+ !occupiesSpace(
rootView.visibility,
rootView.left,
rootView.top,
@@ -177,7 +177,7 @@ class ViewHierarchyAnimator {
fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR
): Boolean {
if (
- isVisible(
+ occupiesSpace(
rootView.visibility,
rootView.left,
rootView.top,
@@ -295,7 +295,7 @@ class ViewHierarchyAnimator {
(view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
- if (!isVisible(view.visibility, left, top, right, bottom)) {
+ if (!occupiesSpace(view.visibility, left, top, right, bottom)) {
setBound(view, Bound.LEFT, left)
setBound(view, Bound.TOP, top)
setBound(view, Bound.RIGHT, right)
@@ -362,7 +362,7 @@ class ViewHierarchyAnimator {
duration: Long = DEFAULT_DURATION
): Boolean {
if (
- !isVisible(
+ !occupiesSpace(
rootView.visibility,
rootView.left,
rootView.top,
@@ -530,17 +530,17 @@ class ViewHierarchyAnimator {
}
/**
- * Returns whether the given [visibility] and bounds are consistent with a view being
- * currently visible on screen.
+ * Returns whether the given [visibility] and bounds are consistent with a view being a
+ * contributing part of the hierarchy.
*/
- private fun isVisible(
+ private fun occupiesSpace(
visibility: Int,
left: Int,
top: Int,
right: Int,
bottom: Int
): Boolean {
- return visibility == View.VISIBLE && left != right && top != bottom
+ return visibility != View.GONE && left != right && top != bottom
}
/**
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 8457312dc403..61fc48f6c2f9 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -32,6 +32,7 @@ java_library_host {
"auto_service_annotations",
"lint_api",
],
+ kotlincflags: ["-Xjvm-default=all"],
}
java_test_host {
diff --git a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
index 7a0b1f190f99..e611e8bf0068 100644
--- a/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
+++ b/packages/SystemUI/compose/testing/src/com/android/systemui/testing/compose/ComposeScreenshotTestRule.kt
@@ -24,22 +24,37 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onRoot
import com.android.systemui.compose.theme.SystemUITheme
import com.android.systemui.testing.screenshot.ScreenshotActivity
-import com.android.systemui.testing.screenshot.ScreenshotTestRule
-import com.android.systemui.testing.screenshot.ScreenshotTestSpec
+import com.android.systemui.testing.screenshot.SystemUIGoldenImagePathManager
+import com.android.systemui.testing.screenshot.UnitTestBitmapMatcher
+import com.android.systemui.testing.screenshot.drawIntoBitmap
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
+import platform.test.screenshot.DeviceEmulationRule
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.MaterialYouColorsRule
+import platform.test.screenshot.ScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
/** A rule for Compose screenshot diff tests. */
-class ComposeScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
+class ComposeScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
+ private val colorsRule = MaterialYouColorsRule()
+ private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
+ private val screenshotRule =
+ ScreenshotTestRule(
+ SystemUIGoldenImagePathManager(getEmulatedDevicePathConfig(emulationSpec))
+ )
private val composeRule = createAndroidComposeRule<ScreenshotActivity>()
- private val screenshotRule = ScreenshotTestRule(testSpec)
-
- private val delegate = RuleChain.outerRule(screenshotRule).around(composeRule)
+ private val delegateRule =
+ RuleChain.outerRule(colorsRule)
+ .around(deviceEmulationRule)
+ .around(screenshotRule)
+ .around(composeRule)
+ private val matcher = UnitTestBitmapMatcher
override fun apply(base: Statement, description: Description): Statement {
- return delegate.apply(base, description)
+ return delegateRule.apply(base, description)
}
/**
@@ -69,6 +84,6 @@ class ComposeScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
composeRule.waitForIdle()
val view = (composeRule.onRoot().fetchSemanticsNode().root as ViewRootForTest).view
- screenshotRule.screenshotTest(goldenIdentifier, view)
+ screenshotRule.assertBitmapAgainstGolden(view.drawIntoBitmap(), goldenIdentifier, matcher)
}
}
diff --git a/packages/SystemUI/docs/user-file-manager.md b/packages/SystemUI/docs/user-file-manager.md
new file mode 100644
index 000000000000..64f1694af50a
--- /dev/null
+++ b/packages/SystemUI/docs/user-file-manager.md
@@ -0,0 +1,13 @@
+# UserFileManager
+
+This class is used to generate file paths and SharedPreferences that is compatible for multiple
+users in SystemUI. Due to constraints in SystemUI, we can only read/write files as the system user.
+Therefore, for secondary users, we want to store secondary user specific files into the system user
+directory.
+
+## Handling User Removal
+
+This class will listen for Intent.ACTION_USER_REMOVED and remove directories that no longer
+corresponding to active users. Additionally, upon start up, the class will run the same query for
+deletion to ensure that there is no stale data.
+
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index 4889dbd23913..100848137bd4 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -61,11 +61,7 @@ interface Clock {
/** Initializes various rendering parameters. If never called, provides reasonable defaults. */
fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
- events.onColorPaletteChanged(
- resources,
- ClockDarkness.DEFAULT,
- ClockDarkness.DEFAULT
- )
+ events.onColorPaletteChanged(resources, RegionDarkness.DEFAULT, RegionDarkness.DEFAULT)
animations.doze(dozeFraction)
animations.fold(foldFraction)
events.onTimeTick()
@@ -95,8 +91,8 @@ interface ClockEvents {
/** Call whenever the color palette should update */
fun onColorPaletteChanged(
resources: Resources,
- smallClockIsDark: ClockDarkness,
- largeClockIsDark: ClockDarkness
+ smallClockIsDark: RegionDarkness,
+ largeClockIsDark: RegionDarkness
) { }
}
@@ -124,8 +120,8 @@ data class ClockMetadata(
/**
* Enum for whether clock region is dark or light.
*/
-enum class ClockDarkness(val isDark: Boolean) {
- DEFAULT(true),
+enum class RegionDarkness(val isDark: Boolean) {
+ DEFAULT(false),
DARK(true),
LIGHT(false)
}
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 6ffd66163653..84ebe77724d1 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -8,9 +8,9 @@
-keep class com.android.systemui.statusbar.car.CarStatusBar
-keep class com.android.systemui.statusbar.phone.CentralSurfaces
-keep class com.android.systemui.statusbar.tv.TvStatusBar
--keep class com.android.systemui.car.CarSystemUIFactory
--keep class com.android.systemui.SystemUIFactory
--keep class com.android.systemui.tv.TvSystemUIFactory
+-keep class ** extends com.android.systemui.SystemUIInitializer {
+ *;
+}
-keep class * extends com.android.systemui.CoreStartable
-keep class * implements com.android.systemui.CoreStartable$Injector
diff --git a/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml b/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml
new file mode 100644
index 000000000000..159655e39d24
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_overlay_camera_off.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="56dp"
+ android:height="24dp"
+ android:viewportWidth="56"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+ android:fillColor="#5F6368"/>
+ <path
+ android:pathData="M21.872,5.873L20.926,6.813L21.492,7.38C21.392,7.566 21.332,7.773 21.332,8V16C21.332,16.733 21.932,17.333 22.666,17.333H30.666C30.892,17.333 31.099,17.273 31.286,17.173L33.186,19.073L34.126,18.133L31.999,16L21.872,5.873ZM31.999,10.986V8C31.999,7.266 31.399,6.666 30.666,6.666H24.552L25.886,8H30.666V12.78L31.999,14.113V13.013L34.666,15.666V8.333L31.999,10.986ZM22.666,8.553V16H30.112L22.666,8.553Z"
+ android:fillColor="#ffffff"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml b/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml
new file mode 100644
index 000000000000..087dde78833f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_overlay_mic_and_camera_off.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="56dp"
+ android:height="24dp"
+ android:viewportWidth="56"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+ android:fillColor="#5F6368"/>
+ <path
+ android:pathData="M15.332,7.333C15.332,6.966 15.632,6.666 15.999,6.666C16.366,6.666 16.666,6.966 16.666,7.333V10.78L17.879,11.993C17.952,11.786 17.999,11.566 17.999,11.333V7.333C17.999,6.226 17.106,5.333 15.999,5.333C14.892,5.333 13.999,6.226 13.999,7.333V8.113L15.332,9.446V7.333ZM9.872,5.873L8.926,6.813L16.692,14.58C16.472,14.633 16.239,14.666 15.999,14.666C14.159,14.666 12.666,13.173 12.666,11.333H11.332C11.332,13.686 13.072,15.62 15.332,15.946V18H16.666V15.946C17.046,15.893 17.412,15.786 17.759,15.64L21.186,19.066L22.126,18.126L9.872,5.873ZM19.332,11.333H20.666C20.666,12.313 20.359,13.213 19.846,13.96L18.872,12.986C19.159,12.5 19.332,11.94 19.332,11.333Z"
+ android:fillColor="#ffffff"
+ android:fillType="evenOdd"/>
+ <path
+ android:pathData="M33.872,5.873L32.926,6.813L33.492,7.38C33.392,7.566 33.332,7.773 33.332,8V16C33.332,16.733 33.932,17.333 34.666,17.333H42.666C42.892,17.333 43.099,17.273 43.286,17.173L45.186,19.073L46.126,18.133L43.999,16L33.872,5.873ZM43.999,10.986V8C43.999,7.266 43.399,6.666 42.666,6.666H36.552L37.886,8H42.666V12.78L43.999,14.113V13.013L46.666,15.666V8.333L43.999,10.986ZM34.666,8.553V16H42.112L34.666,8.553Z"
+ android:fillColor="#ffffff"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml b/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml
new file mode 100644
index 000000000000..693250d39f95
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_overlay_mic_off.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="56dp"
+ android:height="24dp"
+ android:viewportWidth="56"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,0L44,0A12,12 0,0 1,56 12L56,12A12,12 0,0 1,44 24L12,24A12,12 0,0 1,0 12L0,12A12,12 0,0 1,12 0z"
+ android:fillColor="#5F6368"/>
+ <path
+ android:pathData="M27.807,7.133C27.807,6.767 28.107,6.467 28.473,6.467C28.84,6.467 29.14,6.767 29.14,7.133V10.58L30.353,11.793C30.427,11.587 30.473,11.367 30.473,11.133V7.133C30.473,6.027 29.58,5.133 28.473,5.133C27.367,5.133 26.473,6.027 26.473,7.133V7.913L27.807,9.247V7.133ZM22.347,5.673L21.4,6.613L29.167,14.38C28.947,14.433 28.713,14.467 28.473,14.467C26.633,14.467 25.14,12.973 25.14,11.133H23.807C23.807,13.487 25.547,15.42 27.807,15.747V17.8H29.14V15.747C29.52,15.693 29.887,15.587 30.233,15.44L33.66,18.867L34.6,17.927L22.347,5.673ZM31.807,11.133H33.14C33.14,12.113 32.833,13.013 32.32,13.76L31.347,12.787C31.633,12.3 31.807,11.74 31.807,11.133Z"
+ android:fillColor="#ffffff"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml b/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
new file mode 100644
index 000000000000..f239a8dd4291
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_airplane_icon_off.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c M1.5 1.5 C1.5,1.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml b/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
new file mode 100644
index 000000000000..d46fafa25816
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_airplane_icon_on.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="667"
+ android:pathData="M 12.125,34.75C 12.104,30.958 12.021,15.792 12,12"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="517"
+ android:pathData="M 12,12C 12.021,8.312 12.104,-6.436999999999999 12.125,-10.125"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="683"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="12.125"
+ android:translateY="34.75">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M10 4 C10,4 10,2 10,2 C10,2 1.5,-3 1.5,-3 C1.5,-3 1.5,-8.5 1.5,-8.5 C1.5,-9.33 0.83,-10 0,-10 C-0.83,-10 -1.5,-9.33 -1.5,-8.5 C-1.5,-8.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5 C1.5,1.5 10,4 10,4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-1.5 -3.02 C-1.5,-3.02 -1.5,-8.5 -1.5,-8.5 C-1.5,-9.33 -0.83,-10 0,-10 C0.83,-10 1.5,-9.33 1.5,-8.5 C1.5,-8.5 1.5,-3 1.5,-3 C1.5,-3 10,2 10,2 C10,2 10,4 10,4 C10,4 1.51,1.49 1.51,1.49 C1.51,1.49 -1.5,-3.02 -1.5,-3.02c M1.5 1.5 C1.5,1.5 -1.5,-3 -1.5,-3 C-1.5,-3 -10,2 -10,2 C-10,2 -10,4 -10,4 C-10,4 -1.5,1.5 -1.5,1.5 C-1.5,1.5 -1.5,7 -1.5,7 C-1.5,7 -4,8.5 -4,8.5 C-4,8.5 -4,10 -4,10 C-4,10 0,9 0,9 C0,9 4,10 4,10 C4,10 4,8.5 4,8.5 C4,8.5 1.5,7 1.5,7 C1.5,7 1.5,1.5 1.5,1.5c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml b/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml
new file mode 100644
index 000000000000..7b9f23d133ea
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_battery_saver_icon_off.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M3.67 -8 C3.67,-8 2,-8 2,-8 C2,-8 2,-10 2,-10 C2,-10 -2,-10 -2,-10 C-2,-10 -2,-8 -2,-8 C-2,-8 -3.67,-8 -3.67,-8 C-4.4,-8 -5,-7.4 -5,-6.67 C-5,-6.67 -5,8.66 -5,8.66 C-5,9.4 -4.4,10 -3.67,10 C-3.67,10 3.66,10 3.66,10 C4.4,10 5,9.4 5,8.67 C5,8.67 5,-6.67 5,-6.67 C5,-7.4 4.4,-8 3.67,-8c "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2" />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M2 -10 C2,-10 2,-7 2,-7 C2,-7 -2,-7 -2,-7 C-2,-7 -2,-10 -2,-10 C-2,-10 2,-10 2,-10c " />
+ <path
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml b/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml
new file mode 100644
index 000000000000..5e4af398e017
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_battery_saver_icon_on.xml
@@ -0,0 +1,636 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_4_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="317"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="417"
+ android:pathData="M 0,0.875C 0,-0.9690000000000001 0,-8.344000000000001 0,-10.188"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c1,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="417"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="112"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c1,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="250"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="fillAlpha"
+ android:startOffset="333"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="550"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="83"
+ android:pathData="M -0.875,9C -0.854,6.156000000000001 -0.896,11.844 -0.875,9"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="550"
+ android:pathData="M -0.875,9C -0.854,6.156000000000001 -0.771,-5.218 -0.75,-8.062"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="83">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="67"
+ android:valueTo="67"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="550"
+ android:propertyName="rotation"
+ android:startOffset="83"
+ android:valueFrom="67"
+ android:valueTo="192"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="417"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="267"
+ android:propertyName="fillAlpha"
+ android:startOffset="500"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="767"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:pathData="M 2.125,9.375C 2.146,6.468999999999999 2.104,12.281 2.125,9.375"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="600"
+ android:pathData="M 2.125,9.375C 2.146,6.468999999999999 2.229,-5.155999999999999 2.25,-8.062"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="250">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="28"
+ android:valueTo="28"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="rotation"
+ android:startOffset="250"
+ android:valueFrom="28"
+ android:valueTo="153"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="533"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="533"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="fillAlpha"
+ android:startOffset="617"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="867"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M -2,10C -2,6.99 -2,13.01 -2,10"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="600"
+ android:pathData="M -2,10C -2,6.99 -2,-5.052 -2,-8.062"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="350">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="28"
+ android:valueTo="28"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="600"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="28"
+ android:valueTo="153"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="883"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="fillAlpha"
+ android:startOffset="883"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="667"
+ android:pathData="M 0,11.5C 0,9.729 0,13.271 0,11.5"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="667"
+ android:pathData="M 0,11.5C 0,9.729 0,2.646 0,0.875"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="667">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="667"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="-48"
+ android:valueTo="-48"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="667"
+ android:propertyName="rotation"
+ android:startOffset="667"
+ android:valueFrom="-48"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.6,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1350"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_5_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_5_G_D_0_P_0"
+ android:pathData=" M3.67 -8 C3.67,-8 2,-8 2,-8 C2,-8 2,-10 2,-10 C2,-10 -2,-10 -2,-10 C-2,-10 -2,-8 -2,-8 C-2,-8 -3.67,-8 -3.67,-8 C-4.4,-8 -5,-7.4 -5,-6.67 C-5,-6.67 -5,8.66 -5,8.66 C-5,9.4 -4.4,10 -3.67,10 C-3.67,10 3.66,10 3.66,10 C4.4,10 5,9.4 5,8.67 C5,8.67 5,-6.67 5,-6.67 C5,-7.4 4.4,-8 3.67,-8c "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2" />
+ <path
+ android:name="_R_G_L_5_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M2 -10 C2,-10 2,-7 2,-7 C2,-7 -2,-7 -2,-7 C-2,-7 -2,-10 -2,-10 C-2,-10 2,-10 2,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_N_6_T_0"
+ android:translateX="12"
+ android:translateY="12">
+ <group
+ android:name="_R_G_L_4_G_T_1"
+ android:rotation="0"
+ android:translateX="0"
+ android:translateY="0.875">
+ <group
+ android:name="_R_G_L_4_G"
+ android:translateY="-0.875">
+ <path
+ android:name="_R_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_3_G_N_6_T_0"
+ android:translateX="12"
+ android:translateY="12">
+ <group
+ android:name="_R_G_L_3_G_T_1"
+ android:rotation="67"
+ android:scaleX="0.7"
+ android:scaleY="0.7"
+ android:translateX="-0.875"
+ android:translateY="9">
+ <group
+ android:name="_R_G_L_3_G"
+ android:translateY="-0.875">
+ <path
+ android:name="_R_G_L_3_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_2_G_N_6_T_0"
+ android:translateX="12"
+ android:translateY="12">
+ <group
+ android:name="_R_G_L_2_G_T_1"
+ android:rotation="28"
+ android:scaleX="0.85"
+ android:scaleY="0.85"
+ android:translateX="2.125"
+ android:translateY="9.375">
+ <group
+ android:name="_R_G_L_2_G"
+ android:translateY="-0.875">
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_6_T_0"
+ android:translateX="12"
+ android:translateY="12">
+ <group
+ android:name="_R_G_L_1_G_T_1"
+ android:rotation="28"
+ android:scaleX="0.55"
+ android:scaleY="0.55"
+ android:translateX="-2"
+ android:translateY="10">
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateY="-0.875">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_6_T_0"
+ android:translateX="12"
+ android:translateY="12">
+ <group
+ android:name="_R_G_L_0_G_T_1"
+ android:rotation="-48"
+ android:translateX="0"
+ android:translateY="11.5">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateY="-0.875">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3 2 C3,2 1,2 1,2 C1,2 1,4 1,4 C1,4 -1,4 -1,4 C-1,4 -1,2 -1,2 C-1,2 -3,2 -3,2 C-3,2 -3,0 -3,0 C-3,0 -1,0 -1,0 C-1,0 -1,-2 -1,-2 C-1,-2 1,-2 1,-2 C1,-2 1,0 1,0 C1,0 3,0 3,0 C3,0 3,2 3,2c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml b/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml
new file mode 100644
index 000000000000..8f9ecbe482e3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_camera_access_icon_off.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-5.98,-5.57 -6.46,-6.23 -6.83,-6.68 C-7.84,-6.64 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.88,6.1 5,5.23 C4.73,4.96 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+ android:valueTo="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-6.02,-5.5 -6.69,-6.17 -7.12,-6.61 C-7.82,-6.41 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.79,6.11 4.97,5.37 C4.7,5.1 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-10.96 -7.79 C-10.96,-7.79 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -10.96,-7.79 -10.96,-7.79c "
+ android:valueTo="M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-10.96 -7.79 C-10.96,-7.79 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 -10.96,-7.79 -10.96,-7.79c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml b/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml
new file mode 100644
index 000000000000..beb8b72d29ad
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_camera_access_icon_on.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c "
+ android:valueTo="M7.44 10.62 C7.44,10.62 7.45,10.62 7.45,10.62 C7.45,10.62 8.85,9.22 8.85,9.22 C8.85,9.22 8.84,9.22 8.84,9.22 C8.84,9.22 7.44,10.62 7.44,10.62c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.55,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-6.02,-5.5 -6.69,-6.17 -7.12,-6.61 C-7.82,-6.41 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.79,6.11 4.97,5.37 C4.7,5.1 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+ android:valueTo="M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -6.84,-6.68 -6.84,-6.68 C-6.54,-6.37 -6.07,-5.56 -5.49,-5 C-5.49,-5 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.32,3.73 3.32,3.73 C3.32,3.73 5,5.23 5,5.23 C5,5.23 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c M3.34 5 C3.34,5 -6.67,5 -6.67,5 C-6.67,5 -6.67,-5.01 -6.67,-5.01 C-6.67,-5.01 -5.5,-5 -5.5,-5 C-5.98,-5.57 -6.46,-6.23 -6.83,-6.68 C-7.84,-6.64 -8.34,-5.77 -8.34,-5.01 C-8.34,-5.01 -8.34,5 -8.34,5 C-8.34,5.91 -7.58,6.66 -6.67,6.66 C-6.67,6.66 3.34,6.66 3.34,6.66 C4.13,6.66 4.88,6.1 5,5.23 C4.73,4.96 3.73,4.13 3.34,3.73 C3.34,3.73 3.34,5 3.34,5c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M7.44 10.61 C7.44,10.61 -10.96,-7.79 -10.96,-7.79 C-10.96,-7.79 -9.56,-9.19 -9.56,-9.19 C-9.56,-9.19 8.84,9.21 8.84,9.21 C8.84,9.21 7.44,10.61 7.44,10.61c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M5 1.3 C5,1.3 8.35,4.63 8.35,4.63 C8.35,4.63 8.35,-4.58 8.35,-4.58 C8.35,-4.58 5,-1.25 5,-1.25 C5,-1.25 5,-5 5,-5 C5,-5.92 4.25,-6.67 3.33,-6.67 C3.33,-6.67 -4.28,-6.67 -4.28,-6.67 C-3.98,-6.36 -3.13,-5.56 -2.55,-4.99 C-2.55,-4.99 3.33,-5 3.33,-5 C3.33,-5 3.33,-1.91 3.33,-1.91 C3.33,-1.91 3.33,0.9 3.33,0.9 C3.33,0.9 5.01,2.59 5.01,2.59 C5.01,2.59 5,2.14 5,2.14 C5,2.14 5,1.3 5,1.3c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_dnd_icon_off.xml b/packages/SystemUI/res/drawable/qs_dnd_icon_off.xml
new file mode 100644
index 000000000000..e42381a4d5a3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_dnd_icon_off.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:rotation="-225"
+ android:scaleX="0.85"
+ android:scaleY="0.85"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-2.83 -4.24 C-2.83,-4.24 4.24,2.83 4.24,2.83 C4.24,2.83 2.83,4.24 2.83,4.24 C2.83,4.24 -4.24,-2.83 -4.24,-2.83 C-4.24,-2.83 -2.83,-4.24 -2.83,-4.24c M7.07 7.09 C4.65,9.51 1.78,10.02 0,10.02 C-5.52,10.02 -10,5.54 -10,0.02 C-10,-1.76 -9.49,-4.52 -7.07,-7.07 C-7.07,-7.07 -5.66,-5.67 -5.66,-5.67 C-7.73,-3.44 -8,-1.2 -8,0.02 C-8,4.43 -4.41,8.02 0,8.02 C1.22,8.02 3.42,7.71 5.67,5.64 C5.67,5.64 7.07,7.09 7.07,7.09c M-7.06 -7.1 C-4.62,-9.54 -1.81,-9.94 -0.03,-9.94 C5.49,-9.94 9.97,-5.46 9.97,0.06 C9.97,1.84 9.49,4.63 7.07,7.05 C7.07,7.05 5.66,5.64 5.66,5.64 C7.67,3.51 7.97,1.28 7.97,0.06 C7.97,-4.35 4.38,-7.94 -0.03,-7.94 C-1.25,-7.94 -3.43,-7.88 -5.65,-5.66 C-5.65,-5.66 -7.06,-7.1 -7.06,-7.1c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_dnd_icon_on.xml b/packages/SystemUI/res/drawable/qs_dnd_icon_on.xml
new file mode 100644
index 000000000000..a63cb238f5a0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_dnd_icon_on.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="500"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="-225"
+ android:valueTo="-45"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="517"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:rotation="-225"
+ android:scaleX="0.85"
+ android:scaleY="0.85"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-2.83 -4.24 C-2.83,-4.24 4.24,2.83 4.24,2.83 C4.24,2.83 2.83,4.24 2.83,4.24 C2.83,4.24 -4.24,-2.83 -4.24,-2.83 C-4.24,-2.83 -2.83,-4.24 -2.83,-4.24c M7.07 7.09 C4.65,9.51 1.78,10.02 0,10.02 C-5.52,10.02 -10,5.54 -10,0.02 C-10,-1.76 -9.49,-4.52 -7.07,-7.07 C-7.07,-7.07 -5.66,-5.67 -5.66,-5.67 C-7.73,-3.44 -8,-1.2 -8,0.02 C-8,4.43 -4.41,8.02 0,8.02 C1.22,8.02 3.42,7.71 5.67,5.64 C5.67,5.64 7.07,7.09 7.07,7.09c M-7.06 -7.1 C-4.62,-9.54 -1.81,-9.94 -0.03,-9.94 C5.49,-9.94 9.97,-5.46 9.97,0.06 C9.97,1.84 9.49,4.63 7.07,7.05 C7.07,7.05 5.66,5.64 5.66,5.64 C7.67,3.51 7.97,1.28 7.97,0.06 C7.97,-4.35 4.38,-7.94 -0.03,-7.94 C-1.25,-7.94 -3.43,-7.88 -5.65,-5.66 C-5.65,-5.66 -7.06,-7.1 -7.06,-7.1c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_location_icon_off.xml b/packages/SystemUI/res/drawable/qs_location_icon_off.xml
new file mode 100644
index 000000000000..97eb91cd33b0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_location_icon_off.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="175"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M3.98 4.01 C3.98,4.01 2.56,2.54 2.56,2.54 C3.34,1.49 4.41,0.01 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -4.01,-6.61 -4.61,-4.61 C-4.61,-4.61 -6.24,-6.22 -6.24,-6.22 C-5.27,-8.11 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.86,-0.99 6.49,0.02 C6.12,1.04 4.57,3.23 3.98,4.01c "
+ android:valueTo="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="75"
+ android:propertyName="pathData"
+ android:startOffset="175"
+ android:valueFrom="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+ android:valueTo="M5.18 2.33 C5.18,2.33 3.75,0.88 3.75,0.88 C4.13,0.29 4.45,-0.23 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.16,-6.94 -3.61,-6.46 C-3.61,-6.46 -5.07,-7.86 -5.07,-7.86 C-4.42,-8.54 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.84,-0.81 6.49,0.02 C6.14,0.86 5.68,1.58 5.18,2.33c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="125"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-0.96 -0.67 C0.37,-0.16 1.79,-0.77 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-2.08,-4.88 -2.84,-3.58 -2.35,-2.11 C-2.16,-1.55 -1.58,-0.91 -0.96,-0.67c "
+ android:valueTo="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="50"
+ android:propertyName="pathData"
+ android:startOffset="125"
+ android:valueFrom="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+ android:valueTo="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="75"
+ android:propertyName="pathData"
+ android:startOffset="175"
+ android:valueFrom="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+ android:valueTo="M1.8 -1.24 C2.03,-1.47 2.21,-1.76 2.33,-2.05 C2.44,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.25,-5.21 -1.57,-5.02 -1.77,-4.78 C-1.77,-4.78 1.8,-1.24 1.8,-1.24c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="125"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+ android:valueTo="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="125"
+ android:propertyName="pathData"
+ android:startOffset="125"
+ android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+ android:valueTo="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="267"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-5.05 -2.1 C-5.05,-1.06 -4.64,-0.4 -4.23,0.3 C-3.81,1 -3.28,1.75 -2.65,2.55 C-2.22,3.1 -1.78,3.71 -1.35,4.39 C-0.92,5.06 -0.39,5.6 0.01,6.43 C0.21,5.95 0.61,5.27 0.98,4.72 C1.44,4.01 2.13,3.09 2.55,2.54 C2.94,2.95 3.54,3.56 3.98,4 C3.47,4.64 2.65,5.82 2.1,6.77 C1.66,7.55 1.28,8.44 0.98,9.26 C0.88,9.55 0.77,9.67 0.59,9.81 C0.44,9.93 0.28,9.99 0,9.99 C-0.28,9.99 -0.48,9.89 -0.68,9.66 C-0.88,9.44 -1.03,9.18 -1.15,8.9 C-1.45,8.07 -1.68,7.43 -2.17,6.65 C-2.67,5.88 -3.27,4.87 -4.15,3.79 C-4.88,2.75 -5.67,1.6 -6.21,0.62 C-6.74,-0.36 -7,-1.76 -7,-3.01 C-7,-4.08 -6.77,-5.28 -6.23,-6.23 C-5.75,-5.73 -4.92,-4.92 -4.61,-4.61 C-4.87,-3.95 -5.06,-2.93 -5.05,-2.1c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3.98 4.01 C3.98,4.01 2.56,2.54 2.56,2.54 C3.34,1.49 4.41,0.01 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -4.01,-6.61 -4.61,-4.61 C-4.61,-4.61 -6.24,-6.22 -6.24,-6.22 C-5.27,-8.11 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.86,-0.99 6.49,0.02 C6.12,1.04 4.57,3.23 3.98,4.01c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_1"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-0.96 -0.67 C0.37,-0.16 1.79,-0.77 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-2.08,-4.88 -2.84,-3.58 -2.35,-2.11 C-2.16,-1.55 -1.58,-0.91 -0.96,-0.67c " />
+ <path
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_location_icon_on.xml b/packages/SystemUI/res/drawable/qs_location_icon_on.xml
new file mode 100644
index 000000000000..c56b6508eb49
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_location_icon_on.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M5.18 2.33 C5.18,2.33 3.75,0.88 3.75,0.88 C4.13,0.29 4.45,-0.23 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.16,-6.94 -3.61,-6.46 C-3.61,-6.46 -5.07,-7.86 -5.07,-7.86 C-4.42,-8.54 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.84,-0.81 6.49,0.02 C6.14,0.86 5.68,1.58 5.18,2.33c "
+ android:valueTo="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="pathData"
+ android:startOffset="100"
+ android:valueFrom="M4.62 3.11 C4.62,3.11 3.2,1.65 3.2,1.65 C3.77,0.85 4.43,-0.12 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.55,-6.78 -4.16,-5.65 C-4.16,-5.65 -5.67,-7.13 -5.67,-7.13 C-4.81,-8.35 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.85,-0.89 6.49,0.02 C6.13,0.94 5.16,2.35 4.62,3.11c "
+ android:valueTo="M3.98 4.01 C3.98,4.01 2.56,2.54 2.56,2.54 C3.34,1.49 4.41,0.01 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -4.01,-6.61 -4.61,-4.61 C-4.61,-4.61 -6.24,-6.22 -6.24,-6.22 C-5.27,-8.11 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.86,-0.99 6.49,0.02 C6.12,1.04 4.57,3.23 3.98,4.01c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M1.8 -1.24 C2.03,-1.47 2.21,-1.76 2.33,-2.05 C2.44,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.25,-5.21 -1.57,-5.02 -1.77,-4.78 C-1.77,-4.78 1.8,-1.24 1.8,-1.24c "
+ android:valueTo="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="67"
+ android:propertyName="pathData"
+ android:startOffset="100"
+ android:valueFrom="M0.87 -0.65 C1.56,-0.93 2.02,-1.3 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.63,-5.06 -2.14,-4.44 -2.33,-3.91 C-2.11,-3.68 0.66,-0.85 0.87,-0.65c "
+ android:valueTo="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="167"
+ android:valueFrom="M-0.29 -0.52 C0.81,-0.39 1.86,-0.95 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.93,-4.94 -2.6,-3.89 -2.49,-2.82 C-2.18,-2.46 -0.67,-0.84 -0.29,-0.52c "
+ android:valueTo="M-0.96 -0.67 C0.37,-0.16 1.79,-0.77 2.33,-2.05 C2.45,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-2.08,-4.88 -2.84,-3.58 -2.35,-2.11 C-2.16,-1.55 -1.58,-0.91 -0.96,-0.67c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+ android:valueTo="M8.5 10.6 C8.5,10.6 8.51,10.6 8.51,10.6 C8.51,10.6 9.91,9.2 9.91,9.2 C9.91,9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-5.05 -2.1 C-5.05,-1.06 -4.64,-0.4 -4.23,0.3 C-3.81,1 -3.28,1.75 -2.65,2.55 C-2.22,3.1 -1.78,3.71 -1.35,4.39 C-0.92,5.06 -0.39,5.6 0.01,6.43 C0.21,5.95 0.61,5.27 0.98,4.72 C1.44,4.01 2.13,3.09 2.55,2.54 C2.94,2.95 3.54,3.56 3.98,4 C3.47,4.64 2.65,5.82 2.1,6.77 C1.66,7.55 1.28,8.44 0.98,9.26 C0.88,9.55 0.77,9.67 0.59,9.81 C0.44,9.93 0.28,9.99 0,9.99 C-0.28,9.99 -0.48,9.89 -0.68,9.66 C-0.88,9.44 -1.03,9.18 -1.15,8.9 C-1.45,8.07 -1.68,7.43 -2.17,6.65 C-2.67,5.88 -3.27,4.87 -4.15,3.79 C-4.88,2.75 -5.67,1.6 -6.21,0.62 C-6.74,-0.36 -7,-1.76 -7,-3.01 C-7,-4.08 -6.77,-5.28 -6.23,-6.23 C-5.75,-5.73 -4.92,-4.92 -4.61,-4.61 C-4.87,-3.95 -5.06,-2.93 -5.05,-2.1c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M5.18 2.33 C5.18,2.33 3.75,0.88 3.75,0.88 C4.13,0.29 4.45,-0.23 4.68,-0.84 C4.9,-1.45 5,-2.2 5,-3 C5,-4.38 4.51,-5.56 3.54,-6.54 C2.56,-7.51 1.38,-8 0,-8 C-0.7,-8 -1.36,-7.89 -1.99,-7.61 C-2.61,-7.34 -3.16,-6.94 -3.61,-6.46 C-3.61,-6.46 -5.07,-7.86 -5.07,-7.86 C-4.42,-8.54 -3.65,-9.09 -2.79,-9.46 C-1.94,-9.84 -1,-10 0,-10 C1.93,-10 3.6,-9.32 4.97,-7.96 C6.33,-6.59 7,-4.93 7,-3 C7,-1.85 6.84,-0.81 6.49,0.02 C6.14,0.86 5.68,1.58 5.18,2.33c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_1"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M1.8 -1.24 C2.03,-1.47 2.21,-1.76 2.33,-2.05 C2.44,-2.34 2.5,-2.67 2.5,-3.02 C2.5,-3.72 2.24,-4.3 1.76,-4.78 C1.27,-5.27 0.7,-5.5 0,-5.5 C-0.33,-5.5 -0.65,-5.44 -0.95,-5.32 C-1.25,-5.21 -1.57,-5.02 -1.77,-4.78 C-1.77,-4.78 1.8,-1.24 1.8,-1.24c " />
+ <path
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_mic_access_off.xml b/packages/SystemUI/res/drawable/qs_mic_access_off.xml
new file mode 100644
index 000000000000..63a94443c255
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_mic_access_off.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c "
+ android:valueTo="M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="44"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M2.31 1.86 C2.31,1.86 1.01,0.55 0.75,0.31 C1.7,0.27 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.51,0.52 3.23,1.19 2.31,1.86c "
+ android:valueTo="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="39"
+ android:propertyName="pathData"
+ android:startOffset="44"
+ android:valueFrom="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+ android:valueTo="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="pathData"
+ android:startOffset="83"
+ android:valueFrom="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+ android:valueTo="M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M5.04 4.45 C5.04,4.45 3.59,3.02 3.59,3.02 C4.82,1.94 5.31,0.96 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.51,3.17 5.04,4.45c "
+ android:valueTo="M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_3_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="67"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+ android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:startOffset="67"
+ android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+ android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_4_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_4_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c "
+ android:valueTo="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="267"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M2.31 1.86 C2.31,1.86 1.01,0.55 0.75,0.31 C1.7,0.27 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.51,0.52 3.23,1.19 2.31,1.86c " />
+ <path
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M5.04 4.45 C5.04,4.45 3.59,3.02 3.59,3.02 C4.82,1.94 5.31,0.96 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.51,3.17 5.04,4.45c " />
+ <path
+ android:name="_R_G_L_0_G_D_3_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c " />
+ <path
+ android:name="_R_G_L_0_G_D_4_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#edf2eb"
+ android:fillType="nonZero"
+ android:pathData=" M-9.89 -7.81 C-9.89,-7.81 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 -8.49,-9.21 -8.49,-9.21 C-8.49,-9.21 -9.89,-7.81 -9.89,-7.81c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/qs_mic_access_on.xml b/packages/SystemUI/res/drawable/qs_mic_access_on.xml
new file mode 100644
index 000000000000..b485f06d1bf2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_mic_access_on.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c "
+ android:valueTo="M5.05 4.43 C3.98,5.25 3.08,5.53 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.58,3.77 3.61,2.99 C3.61,2.99 5.05,4.43 5.05,4.43c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="125"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c "
+ android:valueTo="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="58"
+ android:propertyName="pathData"
+ android:startOffset="125"
+ android:valueFrom="M3.12 0.99 C3.12,0.99 1.83,-0.26 1.71,-0.38 C1.72,-0.81 1.7,-1.31 1.7,-1.31 C1.7,-1.31 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-2.26 -0.29,-2.26 C-0.29,-2.26 -2.31,-4.23 -2.31,-4.23 C-2.31,-4.23 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.67,-0.54 3.66,-0.3 C3.63,0.12 3.38,0.7 3.12,0.99c "
+ android:valueTo="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="67"
+ android:propertyName="pathData"
+ android:startOffset="183"
+ android:valueFrom="M2.86 1.48 C2.86,1.48 1.58,0.21 1.39,0.03 C1.77,-0.26 1.7,-1.03 1.7,-1.03 C1.7,-1.03 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-1.51 -0.29,-1.51 C-0.29,-1.51 -2.31,-3.5 -2.31,-3.5 C-2.31,-3.5 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.44 3.65,-0.17 C3.61,0.19 3.36,1.05 2.86,1.48c "
+ android:valueTo="M2.42 1.81 C2.42,1.81 1.16,0.52 0.9,0.28 C1.7,0.14 1.7,-0.7 1.7,-0.7 C1.7,-0.7 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.29,-0.66 -0.29,-0.66 C-0.29,-0.66 -2.31,-2.67 -2.31,-2.67 C-2.31,-2.67 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.7,-0.33 3.64,-0.03 C3.58,0.27 3.22,1.2 2.42,1.81c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c "
+ android:valueTo="M5.04 4.43 C5.04,4.43 3.59,2.98 3.59,2.98 C4.61,2.09 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.19,3.44 5.04,4.43c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_3_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+ android:valueTo="M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C-0.4,2.17 -0.94,1.89 -1.41,1.42 C-1.89,0.94 -2.18,0.37 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.1,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_4_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="17"
+ android:propertyName="fillAlpha"
+ android:startOffset="400"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_4_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+ android:valueTo="M8.5 10.6 C8.5,10.6 8.51,10.6 8.51,10.6 C8.51,10.6 9.91,9.2 9.91,9.2 C9.91,9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="433"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="12"
+ android:translateY="12">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M5.02 4.5 C3.59,5.47 2.79,5.64 2.53,5.73 C2.26,5.81 1.98,5.87 1.7,5.9 C1.7,5.9 1.7,9 1.7,9 C1.7,9 -0.3,9 -0.3,9 C-0.3,9 -0.3,5.9 -0.3,5.9 C-2.02,5.65 -3.44,4.88 -4.59,3.59 C-5.73,2.3 -6.3,0.77 -6.3,-1 C-6.3,-1 -4.3,-1 -4.3,-1 C-4.3,0.38 -3.81,1.56 -2.84,2.54 C-1.86,3.51 -0.68,4 0.7,4 C0.88,4 1.06,3.99 1.23,3.96 C1.39,3.94 2.53,3.83 3.58,3.07 C3.58,3.07 5.02,4.5 5.02,4.5c " />
+ <path
+ android:name="_R_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M3.5 -0.05 C3.5,-0.05 1.7,-1.85 1.7,-1.85 C1.7,-1.85 1.7,-1.92 1.7,-1.92 C1.7,-1.92 1.7,-7 1.7,-7 C1.7,-7.28 1.61,-7.52 1.41,-7.71 C1.22,-7.9 0.98,-8 0.7,-8 C0.42,-8 0.18,-7.9 -0.01,-7.71 C-0.2,-7.52 -0.3,-7.28 -0.3,-7 C-0.3,-7 -0.3,-3.85 -0.3,-3.85 C-0.3,-3.85 -2.3,-5.85 -2.3,-5.85 C-2.3,-5.85 -2.3,-7 -2.3,-7 C-2.3,-7.83 -2.01,-8.54 -1.42,-9.12 C-0.84,-9.71 -0.13,-10 0.7,-10 C1.53,-10 2.24,-9.71 2.83,-9.12 C3.41,-8.54 3.7,-7.83 3.7,-7 C3.7,-7 3.7,-1 3.7,-1 C3.7,-0.82 3.68,-0.65 3.64,-0.5 C3.6,-0.35 3.55,-0.2 3.5,-0.05c " />
+ <path
+ android:name="_R_G_L_0_G_D_2_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M6.45 2.95 C6.45,2.95 5,1.5 5,1.5 C5.23,1.12 5.41,0.72 5.53,0.3 C5.64,-0.12 5.7,-0.55 5.7,-1 C5.7,-1 7.7,-1 7.7,-1 C7.7,-0.27 7.59,0.43 7.38,1.09 C7.16,1.75 6.85,2.37 6.45,2.95c " />
+ <path
+ android:name="_R_G_L_0_G_D_3_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M-0.29 -0.71 C-0.29,-0.42 -0.19,-0.19 0,0.01 C0.19,0.2 0.43,0.29 0.71,0.29 C0.76,0.31 0.75,0.31 0.78,0.3 C1.14,0.67 1.92,1.43 2.34,1.85 C2.03,2.04 1.55,2.29 0.71,2.29 C0.55,2.29 0.39,2.28 0.23,2.26 C0.09,2.2 -0.55,1.45 -1.02,0.98 C-1.5,0.5 -2.23,-0.14 -2.26,-0.28 C-2.28,-0.42 -2.29,-0.56 -2.29,-0.71 C-2.29,-0.71 -2.31,-2.72 -2.31,-2.72 C-2.31,-2.72 -0.29,-0.71 -0.29,-0.71c " />
+ <path
+ android:name="_R_G_L_0_G_D_4_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M8.5 10.6 C8.5,10.6 -9.9,-7.8 -9.9,-7.8 C-9.9,-7.8 -8.5,-9.2 -8.5,-9.2 C-8.5,-9.2 9.9,9.2 9.9,9.2 C9.9,9.2 8.5,10.6 8.5,10.6c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/screenshot_edit_background.xml b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
index ff5c62e1600b..a1185a2d5479 100644
--- a/packages/SystemUI/res/drawable/screenshot_edit_background.xml
+++ b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
@@ -17,7 +17,7 @@
<!-- Long screenshot edit FAB background -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:color="?android:textColorPrimary">
+ android:color="@color/overlay_button_ripple">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="?androidprv:attr/colorAccentPrimary"/>
diff --git a/packages/SystemUI/res/layout/auth_container_view.xml b/packages/SystemUI/res/layout/auth_container_view.xml
index 3db01a4e7f3a..2bd2e640127e 100644
--- a/packages/SystemUI/res/layout/auth_container_view.xml
+++ b/packages/SystemUI/res/layout/auth_container_view.xml
@@ -23,7 +23,6 @@
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/biometric_dialog_dim_color"
android:contentDescription="@string/biometric_dialog_empty_space_description"/>
<View
diff --git a/packages/SystemUI/res/layout/brightness_mirror_container.xml b/packages/SystemUI/res/layout/brightness_mirror_container.xml
index ac90db3e5e19..1bf45aad8906 100644
--- a/packages/SystemUI/res/layout/brightness_mirror_container.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror_container.xml
@@ -23,7 +23,6 @@
android:background="@drawable/brightness_mirror_background"
android:layout_gravity="center_vertical"
android:layout_margin="8dp"
- android:padding="@dimen/rounded_slider_background_padding"
android:gravity="center"
android:visibility="invisible">
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index d0f4903a3421..70a770912c7f 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -70,15 +70,32 @@
android:visibility="gone"
android:contentDescription="@string/dream_overlay_status_bar_wifi_off" />
- <com.android.systemui.dreams.DreamOverlayDotImageView
+ <ImageView
+ android:id="@+id/dream_overlay_mic_off"
+ android:layout_width="@dimen/dream_overlay_grey_chip_width"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+ android:src="@drawable/dream_overlay_mic_off"
+ android:visibility="gone"
+ android:contentDescription="@string/dream_overlay_status_bar_mic_off" />
+
+ <ImageView
+ android:id="@+id/dream_overlay_camera_off"
+ android:layout_width="@dimen/dream_overlay_grey_chip_width"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+ android:src="@drawable/dream_overlay_camera_off"
+ android:visibility="gone"
+ android:contentDescription="@string/dream_overlay_status_bar_camera_off" />
+
+ <ImageView
android:id="@+id/dream_overlay_camera_mic_off"
- android:layout_width="@dimen/dream_overlay_camera_mic_off_indicator_size"
- android:layout_height="@dimen/dream_overlay_camera_mic_off_indicator_size"
- android:layout_gravity="center_vertical"
+ android:layout_width="@dimen/dream_overlay_grey_chip_width"
+ android:layout_height="match_parent"
android:layout_marginEnd="@dimen/dream_overlay_status_icon_margin"
+ android:src="@drawable/dream_overlay_mic_and_camera_off"
android:visibility="gone"
- android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off"
- app:dotColor="@color/dream_overlay_camera_mic_off_dot_color" />
+ android:contentDescription="@string/dream_overlay_status_bar_camera_mic_off" />
</LinearLayout>
</com.android.systemui.dreams.DreamOverlayStatusBarView>
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 1efb4796b5b7..93c16e4e119d 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -42,12 +42,35 @@
android:layout_height="wrap_content"
android:paddingStart="12dp"
android:orientation="vertical">
- <ImageView
- android:id="@+id/app_source_icon"
- android:layout_width="20dp"
- android:layout_height="20dp"
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:gravity="center_vertical"
- android:importantForAccessibility="no"/>
+ android:orientation="horizontal">
+ <ImageView
+ android:id="@+id/app_source_icon"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:gravity="center_vertical"
+ android:importantForAccessibility="no"/>
+
+ <Space
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"/>
+
+ <ImageView
+ android:id="@+id/broadcast_icon"
+ android:src="@drawable/settings_input_antenna"
+ android:contentDescription="@string/broadcasting_description_is_broadcasting"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:padding="12dp"
+ android:gravity="center_vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"/>
+ </LinearLayout>
<TextView
android:id="@+id/header_title"
android:layout_width="wrap_content"
@@ -89,8 +112,7 @@
android:id="@+id/list_result"
android:scrollbars="vertical"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:overScrollMode="never"/>
+ android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 9c49607d414e..c526d9cc8dd3 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -150,7 +150,7 @@
<!-- See comment in media_session_collapsed.xml for how these barriers are used -->
<androidx.constraintlayout.widget.Barrier
- android:id="@+id/media_action_barrier"
+ android:id="@+id/media_action_barrier_start"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
@@ -172,6 +172,7 @@
app:layout_constraintStart_toStartOf="parent"
/>
+ <!-- This barrier is used in expanded view to constrain the bottom row of actions -->
<androidx.constraintlayout.widget.Barrier
android:id="@+id/media_action_barrier_top"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
index 0f2d372f7158..c2c79cb0f34b 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<androidx.constraintlayout.widget.ConstraintLayout
+<com.android.systemui.user.UserSwitcherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
@@ -68,4 +68,4 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_min="48dp" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.systemui.user.UserSwitcherRootView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 5b2edbc060bb..3d27dfd95760 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Toestel is gesluit"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skandeer tans gesig"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Stuur"</string>
- <string name="phone_label" msgid="5715229948920451352">"maak foon oop"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"maak stembystand oop"</string>
- <string name="camera_label" msgid="8253821920931143699">"maak kamera oop"</string>
<string name="cancel" msgid="1089011503403416730">"Kanselleer"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestig"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probeer weer"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Tik weer"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk die onsluitikoon om oop te maak"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontsluit met gesig. Druk die ontsluitikoon om oop te maak."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontsluit met gesig. Druk om oop te maak."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesig is herken. Druk om oop te maak."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Saai <xliff:g id="SWITCHAPP">%1$s</xliff:g> uit"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Verander uitvoer"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE. d MMM."</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 7214ec792749..78873e529f13 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"መሣሪያ ተቆልፏል"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"የቅኝት ፊት"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ላክ"</string>
- <string name="phone_label" msgid="5715229948920451352">"ስልክ ክፈት"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"የድምጽ ረዳትን ክፈት"</string>
- <string name="camera_label" msgid="8253821920931143699">"ካሜራ ክፈት"</string>
<string name="cancel" msgid="1089011503403416730">"ይቅር"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"አረጋግጥ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"እንደገና ይሞክሩ"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ለመክፈት የመክፈቻ አዶውን ይጫኑ"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"በመልክ ተከፍቷል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"በመልክ ተከፍቷል። ለመክፈት ይጫኑ።"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"መልክ ተለይቶ ታውቋል። ለመክፈት ይጫኑ።"</string>
@@ -547,7 +546,7 @@
<string name="keyboard_key_dpad_left" msgid="8329738048908755640">"ግራ"</string>
<string name="keyboard_key_dpad_right" msgid="6282105433822321767">"ቀኝ"</string>
<string name="keyboard_key_dpad_center" msgid="4079412840715672825">"መሃል"</string>
- <string name="keyboard_key_tab" msgid="4592772350906496730">"ትር"</string>
+ <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"ክፍተት"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"አስገባ"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"የኋሊት መደምሰሻ"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ውፅዓትን ይቀይሩ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ያልታወቀ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE፣ MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 3138bf966427..98ab7a4b8836 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"الجهاز مُقفل."</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"مسح الوجه"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"إرسال"</string>
- <string name="phone_label" msgid="5715229948920451352">"فتح الهاتف"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"فتح المساعد الصوتي"</string>
- <string name="camera_label" msgid="8253821920931143699">"فتح الكاميرا"</string>
<string name="cancel" msgid="1089011503403416730">"إلغاء"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأكيد"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"إعادة المحاولة"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"اضغط على رمز فتح القفل لفتح قفل الشاشة."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"تم فتح القفل بالتعرّف على وجهك. لفتح الجهاز، اضغط على رمز فتح القفل."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط لفتح الجهاز."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"تم التعرّف على الوجه. اضغط لفتح الجهاز."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغيير جهاز الإخراج"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"غير معروف"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"‏EEE،‏ d‏ MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index fdb27ff739e1..564fd1b11ff1 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইচটো লক হৈ আছে"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"চেহেৰা স্কেন কৰি থকা হৈছে"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পঠিয়াওক"</string>
- <string name="phone_label" msgid="5715229948920451352">"ফ\'ন খোলক"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"কণ্ঠধ্বনিৰে সহায় খোলক"</string>
- <string name="camera_label" msgid="8253821920931143699">"কেমেৰা খোলক"</string>
<string name="cancel" msgid="1089011503403416730">"বাতিল কৰক"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"নিশ্চিত কৰক"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"আকৌ চেষ্টা কৰক"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। খুলিবলৈ টিপক।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ টিপক।"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট সলনি কৰক"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজ্ঞাত"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e747282b2e35..4ce451c86ed1 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilidlənib"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Üzün skan edilməsi"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Göndərin"</string>
- <string name="phone_label" msgid="5715229948920451352">"telefonu açın"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"səs yardımçısını açın"</string>
- <string name="camera_label" msgid="8253821920931143699">"kemaranı açın"</string>
<string name="cancel" msgid="1089011503403416730">"Ləğv edin"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Təsdiq"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yenidən cəhd edin"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Yenidən toxunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"\"Kilidi aç\" ikonasına basıb açın"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb açın."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Üz ilə kiliddən çıxarılıb. Açmaq üçün basın."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Üz tanınıb. Açmaq üçün basın."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Nəticəni dəyişdirin"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Naməlum"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"HHH, AAA g"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ss:dd"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 2b6bd9a8c807..e87cc5effbcf 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
- <string name="phone_label" msgid="5715229948920451352">"otvori telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"otvori glasovnu pomoć"</string>
- <string name="camera_label" msgid="8253821920931143699">"otvori kameru"</string>
<string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probaj ponovo"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano je licem. Pritisnite ikonu otključavanja da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano je licem. Pritisnite da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:min"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"č:min"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index f7fabb7fef34..5779cb3ace7e 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Прылада заблакіравана"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканіраванне твару"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Адправіць"</string>
- <string name="phone_label" msgid="5715229948920451352">"адкрыць тэлефон"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"адкрыць галасавую дапамогу"</string>
- <string name="camera_label" msgid="8253821920931143699">"адкрыць камеру"</string>
<string name="cancel" msgid="1089011503403416730">"Скасаваць"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Пацвердзіць"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Паўтарыць спробу"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Каб адкрыць, націсніце значок разблакіроўкі"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблакіравана распазнаваннем твару. Націсніце, каб адкрыць."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Твар распазнаны. Націсніце, каб адкрыць."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Гэта прылада належыць вашай арганізацыі"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз сеткі VPN"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Трансляцыя праграмы \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змяненне вываду"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невядома"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e6608f3cf489..1784939b8f2d 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Устройството е заключено"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Изпращане"</string>
- <string name="phone_label" msgid="5715229948920451352">"отваряне на телефона"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"отваряне на гласовата помощ"</string>
- <string name="camera_label" msgid="8253821920931143699">"отваряне на камерата"</string>
<string name="cancel" msgid="1089011503403416730">"Отказ"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потвърждаване"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Нов опит"</string>
@@ -278,8 +275,8 @@
<string name="quick_settings_dark_mode_secondary_label_on_at_bedtime" msgid="2274300599408864897">"Включване, когато стане време за сън"</string>
<string name="quick_settings_dark_mode_secondary_label_until_bedtime_ends" msgid="1790772410777123685">"До края на времето за сън"</string>
<string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
- <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string>
- <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string>
+ <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е деактивирана"</string>
+ <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е активирана"</string>
<string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Запис на екрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Старт"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Стоп"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Натиснете иконата за отключване, за да отворите"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отключено с лице. Натиснете иконата за отключване, за да отворите."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отключено с лице. Натиснете за отваряне."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето бе разпознато. Натиснете за отваряне."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Предаване на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промяна на изхода"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 8a8949182055..dfc8a2b714ad 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ডিভাইস লক করা আছে"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ফেস স্ক্যান করা হচ্ছে"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পাঠান"</string>
- <string name="phone_label" msgid="5715229948920451352">"ফোন খুলুন"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ভয়েস সহায়তা খুলুন"</string>
- <string name="camera_label" msgid="8253821920931143699">"ক্যামেরা খুলুন"</string>
<string name="cancel" msgid="1089011503403416730">"বাতিল করুন"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"কনফার্ম করুন"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"আবার চেষ্টা করুন"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"খোলার জন্য আনলক আইকন প্রেস করুন"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ফেসের সাহায্যে আনলক করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য প্রেস করুন।"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করুন"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট পরিবর্তন করুন"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজানা"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index ad7f10b5657f..1ae04fedbf03 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
- <string name="phone_label" msgid="5715229948920451352">"otvori telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"otvori glasovnu pomoć"</string>
- <string name="camera_label" msgid="8253821920931143699">"otvori kameru"</string>
<string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdite"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Ponovo dodirnite"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu za otključavanje da otvorite."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano licem. Pritisnite ikonu za otklj. da otvorite."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano licem. Pritisnite da otvorite."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice prepoznato. Pritisnite da otvorite."</string>
@@ -374,11 +373,11 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet putem VPN-ova"</string>
- <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem VPN-ova"</string>
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je s internetom putem VPN-ova"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem VPN-ova"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može pratiti mrežni saobraćaj na vašem profilu."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni saobraćaj na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Mrežna aktivnost radnog profila je vidljiva vašem IT administratoru"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promijeni izlaz"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"DDD, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index f7441f34073a..0899d882edec 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositiu bloquejat"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"S\'està escanejant la cara"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envia"</string>
- <string name="phone_label" msgid="5715229948920451352">"obre el telèfon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"obre l\'assistència per veu"</string>
- <string name="camera_label" msgid="8253821920931143699">"obre la càmera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancel·la"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirma"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Torna-ho a provar"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Torna a tocar"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Prem la icona de desbloqueig per obrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S\'ha desbloquejat amb la cara. Prem la icona per obrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S\'ha desbloquejat amb la cara. Prem per obrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"S\'ha reconegut la cara. Prem per obrir."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Canvia la sortida"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconeguda"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index bb2ec59f5901..db653160c64d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Zařízení uzamčeno"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenování obličeje"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odeslat"</string>
- <string name="phone_label" msgid="5715229948920451352">"otevřít telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"otevřít hlasovou asistenci"</string>
- <string name="camera_label" msgid="8253821920931143699">"spustit fotoaparát"</string>
<string name="cancel" msgid="1089011503403416730">"Zrušit"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdit"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zkusit znovu"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Znovu klepněte"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Otevřete klepnutím na ikonu odemknutí"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odemknuto obličejem. Stisknutím otevřete."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obličej rozpoznán. Stisknutím otevřete."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zařízení poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu pomocí aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zařízení patří vaší organizaci"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím sítí VPN"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Změna výstupu"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznámé"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"H:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index c9722eb6635b..c1e364b2745b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheden er låst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanner ansigt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
- <string name="phone_label" msgid="5715229948920451352">"åbn telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"åbn taleassistent"</string>
- <string name="camera_label" msgid="8253821920931143699">"åbn kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Annuller"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekræft"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv igen"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Tryk igen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryk på oplåsningsikonet for at åbne"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at åbne."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst op ved hjælp af ansigt. Tryk for at åbne."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansigt genkendt. Tryk for at åbne."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enhed tilhører din organisation, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til internettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Denne enhed tilhører din organisation, og den har forbindelse til nettet via VPN-forbindelser"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Udsend <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skift output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukendt"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"tt.mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 169e475ddc49..618901cae413 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Gerät gesperrt"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Gesicht wird gescannt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senden"</string>
- <string name="phone_label" msgid="5715229948920451352">"Telefon öffnen"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"Sprachassistent öffnen"</string>
- <string name="camera_label" msgid="8253821920931143699">"Kamera öffnen"</string>
<string name="cancel" msgid="1089011503403416730">"Abbrechen"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bestätigen"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Noch einmal versuchen"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Noch einmal tippen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tippe zum Öffnen auf das Symbol „Entsperren“"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Gerät mit dem Gesicht entsperrt. Tippe zum Öffnen."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gesicht erkannt. Tippe zum Öffnen."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> streamen"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ausgabe ändern"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unbekannt"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index fc03b5737d3a..4a15ede13596 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Η συσκευή κλειδώθηκε"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Σάρωση προσώπου"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Αποστολή"</string>
- <string name="phone_label" msgid="5715229948920451352">"άνοιγμα τηλεφώνου"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"άνοιγμα φωνητικής υποβοήθησης"</string>
- <string name="camera_label" msgid="8253821920931143699">"άνοιγμα φωτογραφικής μηχανής"</string>
<string name="cancel" msgid="1089011503403416730">"Ακύρωση"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Επιβεβαίωση"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Δοκιμάστε ξανά"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Πατήστε το εικονίδιο ξεκλειδώματος για άνοιγμα"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ξεκλείδωμα με πρόσωπο. Πατήστε το εικονίδιο ξεκλειδώματος."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για άνοιγμα."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για άνοιγμα."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει σε <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω VPN"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Αλλαγή εξόδου"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Άγνωστο"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ΗΗΗ, ΜΜΜ η"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ώ:λλ"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:λλ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 89b00b4d90bc..634a9daa2abe 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
- <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
- <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancel"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 0519c96dd306..f0e2208a22d0 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
- <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
- <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancel"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 89b00b4d90bc..634a9daa2abe 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
- <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
- <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancel"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 89b00b4d90bc..634a9daa2abe 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Device locked"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
- <string name="phone_label" msgid="5715229948920451352">"open phone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"open voice assist"</string>
- <string name="camera_label" msgid="8253821920931143699">"open camera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancel"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
@@ -310,6 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Press the unlock icon to open"</string>
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"Unlocked by face. Swipe up to open."</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Unlocked by face. Press the unlock icon to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Unlocked by face. Press to open."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Face recognised. Press to open."</string>
@@ -953,4 +951,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a341d5948029..1418095fbfe6 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎Device locked‎‏‎‎‏‎"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎Scanning face‎‏‎‎‏‎"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎Send‎‏‎‎‏‎"</string>
- <string name="phone_label" msgid="5715229948920451352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎open phone‎‏‎‎‏‎"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎open voice assist‎‏‎‎‏‎"</string>
- <string name="camera_label" msgid="8253821920931143699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎open camera‎‏‎‎‏‎"</string>
<string name="cancel" msgid="1089011503403416730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎Confirm‎‏‎‎‏‎"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎Try again‎‏‎‎‏‎"</string>
@@ -310,6 +307,7 @@
<string name="tap_again" msgid="1315420114387908655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎Tap again‎‏‎‎‏‎"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎Swipe up to open‎‏‎‎‏‎"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎Press the unlock icon to open‎‏‎‎‏‎"</string>
+ <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎Unlocked by face. Swipe up to open.‎‏‎‎‏‎"</string>
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎Unlocked by face. Press the unlock icon to open.‎‏‎‎‏‎"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎Unlocked by face. Press to open.‎‏‎‎‏‎"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎Face recognized. Press to open.‎‏‎‎‏‎"</string>
@@ -953,4 +951,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎Broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎Change output‎‏‎‎‏‎"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎Unknown‎‏‎‎‏‎"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎EEE, MMM d‎‏‎‎‏‎"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎h:mm‎‏‎‎‏‎"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎kk:mm‎‏‎‎‏‎"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c759542bdc66..26d980169833 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando rostro"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
- <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"abrir el asistente de voz"</string>
- <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string>
<string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Volver a intentarlo"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Presiona otra vez"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Presiona el ícono de desbloquear para abrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueo con rostro. Presiona el ícono para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueo con rostro. Presiona para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rostro reconocido. Presiona para abrir."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia la salida"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index aff899870990..1876d77f2238 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando cara"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
- <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"abrir el asistente de voz"</string>
- <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string>
<string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reintentar"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Toca de nuevo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pulsa el icono desbloquear para abrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado con la cara. Toca el icono de desbloquear para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado con la cara. Pulsa para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Cara reconocida. Pulsa para abrir."</string>
@@ -402,7 +401,7 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Se ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"El administrador ha activado el registro de la red para supervisar el tráfico en tu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Tu administrador ha activado el registro de la red, por lo que se monitorizará el tráfico de tu perfil de trabajo, aunque no el de tu perfil personal."</string>
- <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string>
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad en esta red, como tus correos electrónicos y tus datos de navegación, es visible para tu administrador de TI."</string>
<string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> y <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string>
<string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Tus aplicaciones de trabajo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red en las aplicaciones de trabajo, incluidos los correos electrónicos y los datos de navegación, es visible para tu administrador de TI y tu proveedor de VPN."</string>
<string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Tus aplicaciones personales están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, como los correos electrónicos y los datos de navegación, es visible para tu proveedor de VPN."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar salida"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index d3e7c8b762de..8d5c3c6bcb6d 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -59,7 +59,7 @@
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"No disponible"</item>
<item msgid="5044688398303285224">"Desactivada"</item>
- <item msgid="8527389108867454098">"Activada"</item>
+ <item msgid="8527389108867454098">"Activado"</item>
</string-array>
<string-array name="tile_states_rotation">
<item msgid="4578491772376121579">"No disponible"</item>
@@ -88,7 +88,7 @@
</string-array>
<string-array name="tile_states_color_correction">
<item msgid="2840507878437297682">"No disponible"</item>
- <item msgid="1909756493418256167">"Desactivada"</item>
+ <item msgid="1909756493418256167">"Desactivado"</item>
<item msgid="4531508423703413340">"Activado"</item>
</string-array>
<string-array name="tile_states_inversion">
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index e11a16597dd2..c64fef9cba6b 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Seade on lukustatud"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Näo skannimine"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Saada"</string>
- <string name="phone_label" msgid="5715229948920451352">"ava telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ava häälabi"</string>
- <string name="camera_label" msgid="8253821920931143699">"ava kaamera"</string>
<string name="cancel" msgid="1089011503403416730">"Tühista"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kinnita"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Proovi uuesti"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Avamiseks vajutage avamise ikooni"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avati näoga. Avamiseks vajutage avamise ikooni."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avati näoga. Avamiseks vajutage."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nägu tuvastati. Avamiseks vajutage."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Rakenduse <xliff:g id="SWITCHAPP">%1$s</xliff:g> ülekandmine"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Väljundi muutmine"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tundmatu"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 35142b95f215..0c1302ebb982 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Gailua blokeatuta dago"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Aurpegia eskaneatzen"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Bidali"</string>
- <string name="phone_label" msgid="5715229948920451352">"ireki telefonoan"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ireki ahots-laguntza"</string>
- <string name="camera_label" msgid="8253821920931143699">"ireki kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Utzi"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Berretsi"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Saiatu berriro"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Sakatu berriro"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Irekitzeko, sakatu desblokeatzeko ikonoa"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Aurpegiaren bidez desblokeatu da. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Aurpegiaren bidez desblokeatu da. Sakatu irekitzeko."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ezagutu da aurpegia. Sakatu irekitzeko."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Igorri <xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Aldatu audio-irteera"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ezezaguna"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 8719b00b17c1..bd0b037bf291 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"دستگاه قفل است"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ارسال"</string>
- <string name="phone_label" msgid="5715229948920451352">"باز کردن تلفن"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"«دستیار صوتی» را باز کنید"</string>
- <string name="camera_label" msgid="8253821920931143699">"باز کردن دوربین"</string>
<string name="cancel" msgid="1089011503403416730">"لغو"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأیید"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"امتحان مجدد"</string>
@@ -293,9 +290,9 @@
<string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"میکروفن مسدود شده است"</string>
<string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"دوربین مسدود شده است"</string>
<string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"میکروفون و دوربین مسدود شده‌اند"</string>
- <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"برای لغو انسداد، کلید حریم‌خصوصی روی دستگاه را به موقعیت میکروفون روشن ببرید تا دسترسی به میکروفون مجاز شود. برای پیدا کردن کلید حریم‌خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
- <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"برای لغو انسداد، کلید حریم‌خصوصی روی دستگاه را به موقعیت دوربین روشن ببرید تا دسترسی به دوربین مجاز شود. برای پیدا کردن کلید حریم‌خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
- <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"برای لغو انسداد آن، کلید حریم‌خصوصی روی دستگاه را به موقعیت لغو انسداد ببرید تا دسترسی مجاز شود. برای پیدا کردن کلید حریم‌خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
+ <string name="sensor_privacy_start_use_mic_blocked_dialog_content" msgid="2138318880682877747">"برای لغو انسداد، کلید حریم خصوصی روی دستگاه را به موقعیت میکروفون روشن ببرید تا دسترسی به میکروفون مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
+ <string name="sensor_privacy_start_use_camera_blocked_dialog_content" msgid="7216015168047965948">"برای لغو انسداد، کلید حریم خصوصی روی دستگاه را به موقعیت دوربین روشن ببرید تا دسترسی به دوربین مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
+ <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_content" msgid="3960837827570483762">"برای لغو انسداد آن، کلید حریم خصوصی روی دستگاه را به موقعیت لغو انسداد ببرید تا دسترسی مجاز شود. برای پیدا کردن کلید حریم خصوصی روی دستگاه، به دفترچه راهنمای دستگاه مراجعه کنید."</string>
<string name="sensor_privacy_mic_unblocked_toast_content" msgid="306555320557065068">"میکروفون دردسترس است"</string>
<string name="sensor_privacy_camera_unblocked_toast_content" msgid="7843105715964332311">"دوربین دردسترس است"</string>
<string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"میکروفون و دوربین دردسترس‌اند"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به‌بالا بکشید"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"برای باز کردن، نماد قفل‌گشایی را فشار دهید"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"قفلْ با چهره باز شد. برای باز کردن، نماد قفل‌گشایی را فشار دهید."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"قفلْ با چهره باز شد. برای باز کردن، فشار دهید."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چهره شناسایی شد. برای باز کردن، فشار دهید."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"همه‌فرستی <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغییر خروجی"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامشخص"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 54be04f04aed..329cc44b4e23 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Laite lukittu"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Kasvojen skannaus"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Lähetä"</string>
- <string name="phone_label" msgid="5715229948920451352">"avaa puhelin"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"Avaa ääniapuri"</string>
- <string name="camera_label" msgid="8253821920931143699">"avaa kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Peru"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Vahvista"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yritä uudelleen"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Napauta uudelleen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Jatka painamalla lukituksen avauskuvaketta."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Avattu kasvojen avulla. Avaa painamalla."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Kasvot tunnistettu. Avaa painamalla."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lähetä <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Muuta ulostuloa"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tuntematon"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"VKP, KKK p"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index f9b18962a157..1fc6b8c9ecd9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
- <string name="phone_label" msgid="5715229948920451352">"Ouvrir le téléphone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ouvrir l\'assistance vocale"</string>
- <string name="camera_label" msgid="8253821920931143699">"Ouvrir l\'appareil photo"</string>
<string name="cancel" msgid="1089011503403416730">"Annuler"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône Déverrouiller pour ouvrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverr. par reconn. faciale. App. sur l\'icône pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverr. par reconnaissance faciale. Appuyez pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> possède cet appareil et peut contrôler le trafic réseau"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de RPV"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Changer la sortie"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 815f0189dd01..79acfdbdb882 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Analyse du visage en cours"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
- <string name="phone_label" msgid="5715229948920451352">"ouvrir le téléphone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ouvrir l\'assistance vocale"</string>
- <string name="camera_label" msgid="8253821920931143699">"ouvrir l\'appareil photo"</string>
<string name="cancel" msgid="1089011503403416730">"Annuler"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Appuyer à nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Appuyez sur l\'icône de déverrouillage pour ouvrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Déverrouillé par visage. Appuyez sur icône déverrouillage pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Déverrouillé par visage. Appuyez pour ouvrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Visage reconnu. Appuyez pour ouvrir."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Modifier le résultat"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM j"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d510b83b90d8..e73aa032171a 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Analizando cara"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
- <string name="phone_label" msgid="5715229948920451352">"abrir teléfono"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"abrir asistente de voz"</string>
- <string name="camera_label" msgid="8253821920931143699">"abrir cámara"</string>
<string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar de novo"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Toca de novo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Preme a icona de desbloquear para abrir a porta"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Usouse o desbloqueo facial. Preme para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Recoñeceuse a cara. Preme para abrir."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar de saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Descoñecida"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 6d14e4621098..e00f5ff22297 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ડિવાઇસ લૉક કરેલું છે"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ચહેરો સ્કૅન કરવો"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"મોકલો"</string>
- <string name="phone_label" msgid="5715229948920451352">"ફોન ખોલો"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"વૉઇસ સહાય ખોલો"</string>
- <string name="camera_label" msgid="8253821920931143699">"કૅમેરા ખોલો"</string>
<string name="cancel" msgid="1089011503403416730">"રદ કરો"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"કન્ફર્મ કરો"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ફરી પ્રયાસ કરો"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ચહેરા દ્વારા અનલૉક કર્યું. ખોલવા માટે દબાવો."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ચહેરો ઓળખ્યો. ખોલવા માટે દબાવો."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"આઉટપુટ બદલો"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"અજાણ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index d385337a1a44..b74d2874fcad 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"डिवाइस लॉक है"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"डिवाइस अनलॉक करने के लिए चेहरा स्कैन किया जाता है"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"भेजें"</string>
- <string name="phone_label" msgid="5715229948920451352">"फ़ोन खोलें"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"आवाज़ से डिवाइस को इस्तेमाल करें"</string>
- <string name="camera_label" msgid="8253821920931143699">"कैमरा खोलें"</string>
<string name="cancel" msgid="1089011503403416730">"रद्द करें"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि करें"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"फिर से कोशिश करें"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहरे से अनलॉक किया. डिवाइस अनलॉक करने के लिए, अनलॉक आइकॉन को दबाएं."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहरे से अनलॉक किया गया. डिवाइस खोलने के लिए टैप करें."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए टैप करें."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट बदलें"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 60a84029b4f1..823d2f495d2a 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Uređaj je zaključan"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
- <string name="phone_label" msgid="5715229948920451352">"otvaranje telefona"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"otvaranje glasovne pomoći"</string>
- <string name="camera_label" msgid="8253821920931143699">"otvaranje fotoaparata"</string>
<string name="cancel" msgid="1089011503403416730">"Odustani"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pritisnite ikonu otključavanja da biste otvorili"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Otključano pomoću lica. Pritisnite da biste otvorili."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Lice je prepoznato. Pritisnite da biste otvorili."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promjena izlaza"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE., d. MMM."</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 9b09cccc1662..12e2d70de609 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Az eszköz zárolva van"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Arc keresése"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Küldés"</string>
- <string name="phone_label" msgid="5715229948920451352">"telefon megnyitása"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"hangsegéd megnyitása"</string>
- <string name="camera_label" msgid="8253821920931143699">"kamera megnyitása"</string>
<string name="cancel" msgid="1089011503403416730">"Mégse"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Megerősítés"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Újrapróbálkozás"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Koppintson újra"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Az eszköz használatához nyomja meg a feloldás ikonját"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Arccal feloldva. A megnyitáshoz nyomja meg a feloldás ikont."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Zárolás arccal feloldva. Koppintson az eszköz használatához."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Arc felismerve. Koppintson az eszköz használatához."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Kimenet módosítása"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ismeretlen"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, HHH n"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ó:pp"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"óó:pp"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index a707c63d2bee..c702969c9058 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Սարքը կողպված է"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Դեմքի սկանավորում"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ուղարկել"</string>
- <string name="phone_label" msgid="5715229948920451352">"բացել հեռախոսը"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"բացեք ձայնային հուշումը"</string>
- <string name="camera_label" msgid="8253821920931143699">"բացել ֆոտոխցիկը"</string>
<string name="cancel" msgid="1089011503403416730">"Չեղարկել"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Հաստատել"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Նորից փորձել"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Բացեք՝ սեղմելով ապակողպման պատկերակը"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ապակողպվել է դեմքով։ Բացեք՝ սեղմելով ապակողպման պատկերակը։"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ապակողպվել է դեմքով։ Սեղմեք բացելու համար։"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Դեմքը ճանաչվեց։ Սեղմեք բացելու համար։"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Հեռարձակել <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Փոխել աուդիո ելքը"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Անհայտ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index fb51e6bf8f32..e52d08d7f721 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Perangkat terkunci"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Memindai wajah"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Kirim"</string>
- <string name="phone_label" msgid="5715229948920451352">"buka ponsel"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"buka bantuan suara"</string>
- <string name="camera_label" msgid="8253821920931143699">"buka kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Batal"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmasi"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Coba lagi"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Ketuk lagi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk membuka"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Kunci dibuka dengan wajah. Tekan untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dikenali. Tekan untuk membuka."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ubah output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 7420ff18d7a0..e8d2d866aec3 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Tækið er læst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Andlit skannað"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senda"</string>
- <string name="phone_label" msgid="5715229948920451352">"opna síma"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"opna raddaðstoð"</string>
- <string name="camera_label" msgid="8253821920931143699">"opna myndavél"</string>
<string name="cancel" msgid="1089011503403416730">"Hætta við"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Staðfesta"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reyna aftur"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Ýttu aftur"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Ýttu á táknið til að taka úr lás til að opna"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Opnað með andliti. Ýttu á táknið taka úr lás til að opna."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Opnað með andliti. Ýttu til að opna."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Andlitið var greint. Ýttu til að opna."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skipta um úttak"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Óþekkt"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"k:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index e16fc15ec3d1..5d318bfb1adf 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloccato"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scansione del viso"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Invia"</string>
- <string name="phone_label" msgid="5715229948920451352">"apri telefono"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"apri Voice Assist"</string>
- <string name="camera_label" msgid="8253821920931143699">"apri fotocamera"</string>
<string name="cancel" msgid="1089011503403416730">"Annulla"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Conferma"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Riprova"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Tocca di nuovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Premi l\'icona Sblocca per aprire"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Sbloccato con il volto. Premi l\'icona Sblocca per aprire."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Sbloccato con il volto. Premi per aprire."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Volto riconosciuto. Premi per aprire."</string>
@@ -953,4 +952,10 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia uscita"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
+ <!-- no translation found for dream_date_complication_date_format (8191225366513860104) -->
+ <skip />
+ <!-- no translation found for dream_time_complication_12_hr_time_format (4691197486690291529) -->
+ <skip />
+ <!-- no translation found for dream_time_complication_24_hr_time_format (6248280719733640813) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a889c9cb552a..25e08c634b6b 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"המכשיר נעול"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"סורק פנים"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string>
- <string name="phone_label" msgid="5715229948920451352">"פתיחת הטלפון"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"פתיחת האסיסטנט"</string>
- <string name="camera_label" msgid="8253821920931143699">"פתיחת המצלמה"</string>
<string name="cancel" msgid="1089011503403416730">"ביטול"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ניסיון נוסף"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"הנעילה בוטלה בזיהוי פנים. פותחים בלחיצה על סמל ביטול הנעילה."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי לפתוח."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"הפנים זוהו. יש ללחוץ כדי לפתוח."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"שידור תוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"שינוי הפלט"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"לא ידוע"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"‏יום EEE,‏ d בMMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 7bfa60cc3e56..69a959268d7f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"デバイスはロックされています"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"顔のスキャン"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"送信"</string>
- <string name="phone_label" msgid="5715229948920451352">"電話を起動"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"音声アシストを開く"</string>
- <string name="camera_label" msgid="8253821920931143699">"カメラを起動"</string>
<string name="cancel" msgid="1089011503403416730">"キャンセル"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試行"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ロック解除アイコンを押して開きます"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"顔でロック解除しました。アイコンを押すと開きます。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"顔でロック解除しました。押すと開きます。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"顔を認識しました。押すと開きます。"</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、<xliff:g id="VPN_APP">%2$s</xliff:g>を介してインターネットに接続しています"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有し、<xliff:g id="VPN_APP">%2$s</xliff:g> を介してインターネットに接続されています"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"これは組織が所有するデバイスです"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"これは組織が所有するデバイスで、VPN を介してインターネットに接続しています"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャスト"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"出力を変更"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 406aea64e618..fc1ecdac36ee 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"მოწყობილობა ჩაკეტილია"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"მიმდინარეობს სახის სკანირება"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"გაგზავნა"</string>
- <string name="phone_label" msgid="5715229948920451352">"ტელეფონის გახსნა"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ხმოვანი დახმარების გახსნა"</string>
- <string name="camera_label" msgid="8253821920931143699">"კამერის გახსნა"</string>
<string name="cancel" msgid="1089011503403416730">"გაუქმება"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"დადასტურება"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ხელახლა ცდა"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"გასახსნელად დააჭირეთ განბლოკვის ხატულას"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"განიბლოკა სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"განიბლოკა სახით. დააჭირეთ გასახსნელად."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ამოცნობილია სახით. დააჭირეთ გასახსნელად."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"აუდიოს გამოსასვლელის შეცვლა"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"უცნობი"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"დდდ, თთთ თ"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"სთ:წთ"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"სთ:წთ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 4f5b7e05cf48..d47c26df09a8 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Құрылғы құлыпталды."</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Бетті сканерлеу"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жіберу"</string>
- <string name="phone_label" msgid="5715229948920451352">"телефонды ашу"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ашық дауыс көмекшісі"</string>
- <string name="camera_label" msgid="8253821920931143699">"камераны ашу"</string>
<string name="cancel" msgid="1089011503403416730">"Бас тарту"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Растау"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Қайталап көріңіз"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Бет үлгісі арқылы ашылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Бетпен ашылды. Ашу үшін басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Бет танылды. Ашу үшін басыңыз."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудио шығысын өзгерту"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгісіз"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index a921cb94b7e2..48fedd222a1f 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"បានចាក់សោ​ឧបករណ៍"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ការ​ស្កេន​មុខ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ផ្ញើ"</string>
- <string name="phone_label" msgid="5715229948920451352">"បើក​ទូរស័ព្ទ"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"បើកជំនួយសំឡេង"</string>
- <string name="camera_label" msgid="8253821920931143699">"បើក​ម៉ាស៊ីន​ថត"</string>
<string name="cancel" msgid="1089011503403416730">"បោះបង់"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"បញ្ជាក់"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ព្យាយាម​ម្ដង​ទៀត"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ចុច​ម្ដងទៀត"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ចុចរូបដោះសោ ដើម្បីបើក"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបើក។"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបើក។"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ការផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ប្ដូរឧបករណ៍បញ្ចេញសំឡេង"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"មិនស្គាល់"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 46fa9a4c4d7e..55afb910c775 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ಸಾಧನ ಲಾಕ್ ಆಗಿದೆ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ಕಳುಹಿಸಿ"</string>
- <string name="phone_label" msgid="5715229948920451352">"ಫೋನ್ ತೆರೆಯಿರಿ"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string>
- <string name="camera_label" msgid="8253821920931143699">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string>
<string name="cancel" msgid="1089011503403416730">"ರದ್ದುಮಾಡಿ"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"ದೃಢೀಕರಿಸಿ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಒತ್ತಿ."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ಅಪರಿಚಿತ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 47c26460b94e..32d345f04532 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"기기 잠김"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"얼굴 스캔 중"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"보내기"</string>
- <string name="phone_label" msgid="5715229948920451352">"휴대전화 열기"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"음성 지원 열기"</string>
- <string name="camera_label" msgid="8253821920931143699">"카메라 열기"</string>
<string name="cancel" msgid="1089011503403416730">"취소"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"확인"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"다시 시도하세요."</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"얼굴 인식으로 잠금 해제되었습니다. 기기를 열려면 잠금 해제 아이콘을 누르세요."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"얼굴 인식으로 잠금 해제되었습니다. 열려면 누르세요."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"얼굴이 인식되었습니다. 열려면 누르세요."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 방송"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"출력 변경"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"알 수 없음"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d일 EEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 437708acefff..a9670589f0cc 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -50,7 +50,7 @@
<string name="usb_debugging_title" msgid="8274884945238642726">"USB аркылуу жөндөөгө уруксат берилсинби?"</string>
<string name="usb_debugging_message" msgid="5794616114463921773">"Компүтердин RSA ачкычынын контролдук суммасы:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="4003121804294739548">"Бул компүтерден дайыма уруксат берилсин"</string>
- <string name="usb_debugging_allow" msgid="1722643858015321328">"Уруксат берүү"</string>
+ <string name="usb_debugging_allow" msgid="1722643858015321328">"Ооба"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string>
<string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Учурда бул аккаунтта USB аркылуу мүчүлүштүктөрдү аныктоо функциясын иштетүүгө болбойт. Негизги колдонуучунун аккаунтуна кириңиз."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Тутум тилин <xliff:g id="LANGUAGE">%1$s</xliff:g> тилине өзгөртөсүзбү?"</string>
@@ -60,7 +60,7 @@
<string name="wifi_debugging_title" msgid="7300007687492186076">"Ушул тармакта мүчүлүштүктөрдү Wi-Fi аркылуу аныктоого уруксат бересизби?"</string>
<string name="wifi_debugging_message" msgid="5461204211731802995">"Тармактын аталышы (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi дареги (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
<string name="wifi_debugging_always" msgid="2968383799517975155">"Бул тармакта ар дайым уруксат берилсин"</string>
- <string name="wifi_debugging_allow" msgid="4573224609684957886">"Уруксат берүү"</string>
+ <string name="wifi_debugging_allow" msgid="4573224609684957886">"Ооба"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат берилген жок"</string>
<string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Учурда бул түзмөккө кирген колдонуучу мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо функциясын күйгүзө албайт. Бул функцияны колдонуу үчүн негизги колдонуучунун аккаунтуна которулуңуз."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB порту өчүрүлдү"</string>
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Түзмөк кулпуланды"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жөнөтүү"</string>
- <string name="phone_label" msgid="5715229948920451352">"телефонду ачуу"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"үн жардамчысысын ачуу"</string>
- <string name="camera_label" msgid="8253821920931143699">"камераны ачуу"</string>
<string name="cancel" msgid="1089011503403416730">"Жок"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Ырастоо"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Кайталоо"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Кулпуну ачуу сүрөтчөсүн басыңыз"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Кулпуну жүзүңүз менен ачтыңыз. Эми кулпуну ачуу сүрөтчөсүн басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Кулпуну жүзүңүз менен ачтыңыз. Ачуу үчүн басыңыз."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Жүз таанылды. Ачуу үчүн басыңыз."</string>
@@ -470,7 +469,7 @@
<string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Жаңырууда"</string>
<string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Колдонуу үчүн кулпусун ачыңыз"</string>
<string name="wallet_error_generic" msgid="257704570182963611">"Кыйытмаларды алууда ката кетти. Бир аздан кийин кайталап көрүңүз."</string>
- <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Кулпуланган экран жөндөөлөрү"</string>
+ <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Экранды кулпулоо параметрлери"</string>
<string name="qr_code_scanner_title" msgid="5290201053875420785">"QR кодун скандоо"</string>
<string name="status_bar_work" msgid="5238641949837091056">"Жумуш профили"</string>
<string name="status_bar_airplane" msgid="4848702508684541009">"Учак режими"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудионун чыгуусун өзгөртүү"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгисиз"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 8e84afec9689..d86198e4d512 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ອຸປະກອນຖືກລັອກໄວ້"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ການສະແກນໜ້າ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ສົ່ງ"</string>
- <string name="phone_label" msgid="5715229948920451352">"​ເປີດ​​ແປ້ນ​ໂທ​ລະ​ສັບ"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ຊ່ວ​ເຫຼືອ​ເປີດ​ສຽງ"</string>
- <string name="camera_label" msgid="8253821920931143699">"ເປີດ​ກ້ອງ"</string>
<string name="cancel" msgid="1089011503403416730">"ຍົກເລີກ"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"ຢືນຢັນ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ລອງໃໝ່"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ກົດໄອຄອນປົດລັອກເພື່ອເປີດ"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອເປີດ."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອເປີດ."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ປ່ຽນເອົ້າພຸດ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ບໍ່ຮູ້ຈັກ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"ຊມ:ນທ"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ຊມ:ນທ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 372217629b04..56bfb2c3713c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Įrenginys užrakintas"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Nuskaitomas veidas"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Siųsti"</string>
- <string name="phone_label" msgid="5715229948920451352">"atidaryti telefoną"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"atidaryti „Voice Assist“"</string>
- <string name="camera_label" msgid="8253821920931143699">"atidaryti fotoaparatą"</string>
<string name="cancel" msgid="1089011503403416730">"Atšaukti"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Patvirtinkite"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Bandyti dar kartą"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Palieskite dar kartą"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Paspauskite atrakinimo piktogramą, kad atidarytumėte"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atrakinta pagal veidą. Pasp. atr. pikt., kad atidarytumėte."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Atrakinta pagal veidą. Paspauskite, kad atidarytumėte."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Veidas atpažintas. Paspauskite, kad atidarytumėte."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Keisti išvestį"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nežinoma"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index a1a242450f73..65e7c5d74b39 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Ierīce ir bloķēta"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Sejas skenēšana"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Sūtīt"</string>
- <string name="phone_label" msgid="5715229948920451352">"atvērt tālruni"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"atvērt balss palīgu"</string>
- <string name="camera_label" msgid="8253821920931143699">"atvērt kameru"</string>
<string name="cancel" msgid="1089011503403416730">"Atcelt"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Apstiprināt"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Mēģināt vēlreiz"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Pieskarieties vēlreiz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Lai atvērtu, nospiediet atbloķēšanas ikonu"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Atbloķēta ar seju. Atvērt: nospiediet atbloķēšanas ikonu."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ierīce atbloķēta ar seju. Nospiediet, lai atvērtu."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Seja atpazīta. Nospiediet, lai atvērtu."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraide"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Izvades maiņa"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nezināms"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"hh:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5c1bf4afff13..85f9cd5329d0 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Уредот е заклучен"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лице"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Испрати"</string>
- <string name="phone_label" msgid="5715229948920451352">"отвори телефон"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"отвори гласовна помош"</string>
- <string name="camera_label" msgid="8253821920931143699">"отвори камера"</string>
<string name="cancel" msgid="1089011503403416730">"Откажи"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Обиди се повторно"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Притиснете ја иконата за отклучување за да отворите"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Отклучено со лик. Притиснете ја иконата за отклучување за да отворите."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Отклучено со лик. Притиснете за да отворите."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицето е препознаено. Притиснете за да отворите."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Променете излез"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e95197891ead..49a807545283 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ഉപകരണം ലോക്ക് ചെയ്തു"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"മുഖം സ്കാൻ ചെയ്യുന്നു"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"അയയ്ക്കുക"</string>
- <string name="phone_label" msgid="5715229948920451352">"ഫോൺ തുറക്കുക"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"വോയ്‌സ് അസിസ്റ്റ് തുറക്കുക"</string>
- <string name="camera_label" msgid="8253821920931143699">"ക്യാമറ തുറക്കുക"</string>
<string name="cancel" msgid="1089011503403416730">"റദ്ദാക്കുക"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"സ്ഥിരീകരിക്കുക"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"വീണ്ടും ശ്രമിക്കുക"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുറക്കാൻ അമർത്തുക."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അമർത്തുക."</string>
@@ -406,7 +405,7 @@
<string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ഈ ഉപകരണം <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> എന്നിവയിലൂടെ ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്‌മിന് ദൃശ്യമാകും."</string>
<string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള, ഔദ്യോഗിക ആപ്പുകളിലെ നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്‌മിനും VPN ദാതാവിനും ദൃശ്യമാകും."</string>
<string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ VPN ദാതാവിന് ദൃശ്യമാകും."</string>
- <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" 5"</string>
+ <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ക്രമീകരണം തുറക്കുക"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്. നിങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ, സ്‌ക്രീൻ സമയം, ലൊക്കേഷൻ എന്നിവ പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ രക്ഷിതാവിന് കാണാനും നിയന്ത്രിക്കാനുമാകും."</string>
<string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുക"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ഔട്ട്പുട്ട് മാറ്റുക"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"അജ്ഞാതം"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f9ca17eace54..c9bd0bf20243 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Төхөөрөмжийг түгжсэн"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Скан хийх нүүр царай"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Илгээх"</string>
- <string name="phone_label" msgid="5715229948920451352">"утас нээх"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"дуут туслахыг нээнэ"</string>
- <string name="camera_label" msgid="8253821920931143699">"камер нээх"</string>
<string name="cancel" msgid="1089011503403416730">"Цуцлах"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Баталгаажуулах"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Дахин оролдох"</string>
@@ -173,7 +170,7 @@
<string name="cell_data_off" msgid="4886198950247099526">"Идэвхгүй"</string>
<string name="accessibility_airplane_mode" msgid="1899529214045998505">"Нислэгийн горим"</string>
<string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN асаалттай байна."</string>
- <string name="accessibility_battery_level" msgid="5143715405241138822">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
+ <string name="accessibility_battery_level" msgid="5143715405241138822">"Батарей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
<string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"Батарей <xliff:g id="PERCENTAGE">%1$s</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Батарейг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"Бүх мэдэгдлийг харах"</string>
@@ -214,7 +211,7 @@
<string name="quick_settings_dnd_label" msgid="7728690179108024338">"Бүү саад бол"</string>
<string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
<string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Хослуулсан төхөөрөмж байхгүй"</string>
- <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерей"</string>
+ <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батарей"</string>
<string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string>
<string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Чихэвч"</string>
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Оролт"</string>
@@ -248,7 +245,7 @@
<string name="quick_settings_done" msgid="2163641301648855793">"Дууссан"</string>
<string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Хаах"</string>
<string name="quick_settings_connected" msgid="3873605509184830379">"Холбогдсон"</string>
- <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Холбогдож байна..."</string>
<string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Сүлжээний цэг"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Асааж байна…"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Царайгаар түгжээг тайлсан. Нээхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Царайгаар түгжээг тайлсан. Нээхийн тулд дарна уу."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Царайг таньсан. Нээхийн тулд дарна уу."</string>
@@ -706,7 +705,7 @@
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Апп (<xliff:g id="ID_1">%s</xliff:g>) Бүү саад бол горимыг асаасан."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Автомат дүрэм эсвэл апп Бүү саад бол горимыг асаасан."</string>
<string name="running_foreground_services_title" msgid="5137313173431186685">"Цаана ажиллаж буй апп"</string>
- <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
+ <string name="running_foreground_services_msg" msgid="3009459259222695385">"Батарей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
<string name="mobile_data_disable_title" msgid="5366476131671617790">"Мобайл датаг унтраах уу?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"Та <xliff:g id="CARRIER">%s</xliff:g>-р дата эсвэл интернэтэд хандах боломжгүй болно. Интернэтэд зөвхөн Wi-Fi-р холбогдох боломжтой болно."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"таны оператор компани"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Гаралтыг өөрчлөх"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Тодорхойгүй"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 19694dbea63e..5922126dcebe 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"डिव्हाइस लॉक केले"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"चेहरा स्कॅन करत आहे"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पाठवा"</string>
- <string name="phone_label" msgid="5715229948920451352">"फोन उघडा"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"व्हॉइस सहाय्य उघडा"</string>
- <string name="camera_label" msgid="8253821920931143699">"कॅमेरा उघडा"</string>
<string name="cancel" msgid="1089011503403416730">"रद्द करा"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"कंफर्म करा"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"पुन्हा प्रयत्न करा"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी दाबा."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी दाबा."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण करा"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपूट बदला"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index e85b3a01e8be..ac6f3deb8e53 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Peranti dikunci"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Mengimbas wajah"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Hantar"</string>
- <string name="phone_label" msgid="5715229948920451352">"buka telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"buka bantuan suara"</string>
- <string name="camera_label" msgid="8253821920931143699">"buka kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Batal"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Sahkan"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Cuba lagi"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Ketik sekali lagi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tekan ikon buka kunci untuk buka"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk buka."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Dibuka kunci dengan wajah. Tekan untuk membuka."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Wajah dicam. Tekan untuk membuka."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Tukar output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 81f8189c00d6..09de7451064f 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"စက်ပစ္စည်းကို လော့ခ်ချထားသည်"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ပို့ရန်"</string>
- <string name="phone_label" msgid="5715229948920451352">"ဖုန်းကို ဖွင့်ရန်"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"အသံ အကူအညီအား ဖွင့်ရန်"</string>
- <string name="camera_label" msgid="8253821920931143699">"ကင်မရာ ဖွင့်ရန်"</string>
<string name="cancel" msgid="1089011503403416730">"မလုပ်တော့"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"အတည်ပြုပါ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ထပ်စမ်းကြည့်ရန်"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"မျက်နှာပြ လော့ခ်ဖွင့်ထားသည်။ လော့ခ်ဖွင့်သင်္ကေတ နှိပ်၍ဝင်ပါ။"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် နှိပ်ပါ။"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"အထွက်ကို ပြောင်းခြင်း"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"မသိ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE၊ MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index d6ce3feb1a79..8b435c2fd43d 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten er låst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanning av ansikt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
- <string name="phone_label" msgid="5715229948920451352">"åpne telefonen"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"åpne talehjelp"</string>
- <string name="camera_label" msgid="8253821920931143699">"åpne kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Avbryt"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekreft"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv på nytt"</string>
@@ -136,7 +133,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
@@ -250,7 +247,7 @@
<string name="quick_settings_connected" msgid="3873605509184830379">"Tilkoblet"</string>
<string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"Tilkoblet, batterinivå <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
<string name="quick_settings_connecting" msgid="2381969772953268809">"Kobler til …"</string>
- <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wi-Fi-sone"</string>
+ <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wifi-sone"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Slår på …"</string>
<string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datasparing er på"</string>
<string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# enhet}other{# enheter}}"</string>
@@ -310,7 +307,9 @@
<string name="tap_again" msgid="1315420114387908655">"Trykk igjen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Trykk på lås opp-ikonet for å åpne"</string>
- <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikon for å fortsette"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
+ <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Låst opp med ansiktet. Trykk for å åpne."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet er gjenkjent. Trykk for å åpne."</string>
<string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
@@ -477,7 +476,7 @@
<string name="zen_alarm_warning" msgid="7844303238486849503">"Du hører ikke neste innstilte alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template" msgid="2234991538018805736">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
- <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wi-Fi-sone"</string>
+ <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Wifi-sone"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string>
<string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string>
@@ -912,7 +911,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wi-Fi kobles ikke til automatisk inntil videre"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Se alle"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"For å bytte nettverk, koble fra Ethernet"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for Wi-Fi-skanning. "<annotation id="link">"Endre"</annotation></string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"For å forbedre brukeropplevelsen på enheten kan apper og tjenester søke etter Wi-Fi-nettverk når som helst – også når Wi-Fi er slått av. Du kan endre dette i innstillingene for wifi-skanning. "<annotation id="link">"Endre"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Slå av flymodus"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vil legge til denne brikken i Hurtiginnstillinger"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Legg til brikke"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Kringkast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Endre utgang"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukjent"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"t:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"tt:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 409db0b91e56..05bb2868125c 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"यन्त्र लक गरिएको छ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"अनुहार स्क्यान गर्दै"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पठाउनुहोस्"</string>
- <string name="phone_label" msgid="5715229948920451352">"फोन खोल्नुहोस्"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"आवाज सहायता खोल्नुहोस्"</string>
- <string name="camera_label" msgid="8253821920931143699">"क्यामेरा खोल्नुहोस्"</string>
<string name="cancel" msgid="1089011503403416730">"रद्द गर्नुहोस्"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि गर्नुहोस्"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"फेरि प्रयास गर्नुहोस्"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"खोल्न अनलक आइकनमा थिच्नुहोस्"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"अनुहार प्रयोग गरी अनलक गरियो। खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"अनुहार प्रयोग गरी अनलक गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"अनुहार पहिचान गरियो। डिभाइस खोल्न थिच्नुहोस्।"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुहोस्"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट परिवर्तन गर्नुहोस्"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9501ddf1dedf..2c91600cc5e5 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Apparaat vergrendeld"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Gezicht scannen"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Verzenden"</string>
- <string name="phone_label" msgid="5715229948920451352">"telefoon openen"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"spraakassistent openen"</string>
- <string name="camera_label" msgid="8253821920931143699">"camera openen"</string>
<string name="cancel" msgid="1089011503403416730">"Annuleren"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestigen"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Opnieuw proberen"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Tik nog een keer"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Druk op het ontgrendelicoon om te openen"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Ontgrendeld via gezicht. Druk om te openen."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Gezicht herkend. Druk om te openen."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft verbinding met internet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft internetverbinding via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dit apparaat is eigendom van je organisatie"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via VPN\'s"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzenden"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Uitvoer wijzigen"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d mmm"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"u:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 681c2bb48b19..f30f7d13d0f7 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -79,8 +79,8 @@
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ସ୍କ୍ରିନସଟକୁ ସେଭ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ଆପ୍‍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍‍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
<string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ନେବା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</string>
- <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ୍ କରନ୍ତୁ"</string>
- <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ୍ କରନ୍ତୁ"</string>
+ <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ କରନ୍ତୁ"</string>
+ <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ କରନ୍ତୁ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ସ୍କ୍ରିନସଟ ସେୟାର କରନ୍ତୁ"</string>
<string name="screenshot_scroll_label" msgid="2930198809899329367">"ଅଧିକ କ୍ୟାପଚର୍ କରନ୍ତୁ"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string>
@@ -124,13 +124,10 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string>
- <string name="phone_label" msgid="5715229948920451352">"ଫୋନ୍‌ ଖୋଲନ୍ତୁ"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ଭଏସ୍‍ ସହାୟକ ଖୋଲନ୍ତୁ"</string>
- <string name="camera_label" msgid="8253821920931143699">"କ୍ୟାମେରା ଖୋଲନ୍ତୁ"</string>
- <string name="cancel" msgid="1089011503403416730">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+ <string name="cancel" msgid="1089011503403416730">"ବାତିଲ କରନ୍ତୁ"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
- <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+ <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"ଆପଣଙ୍କର ମୁହଁକୁ ପ୍ରମାଣ କରୁଛି"</string>
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଦବାନ୍ତୁ।"</string>
@@ -622,7 +621,7 @@
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ଟାଇଲ୍‍ ପୁଣି ସଜାଇବାକୁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍‍ କରନ୍ତୁ"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"ଆପଣଙ୍କର ଅତିକମ୍‌ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string>
- <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
+ <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ କରନ୍ତୁ"</string>
<string name="tuner_time" msgid="2450785840990529997">"ସମୟ"</string>
<string-array name="clock_options">
<item msgid="3986445361435142273">"ଘଣ୍ଟା, ମିନିଟ୍‍ ଏବଂ ସେକେଣ୍ଡ ଦେଖାନ୍ତୁ"</item>
@@ -654,7 +653,7 @@
<string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ଉପଯୋଗକର୍ତ୍ତା ବାଛନ୍ତୁ"</string>
<string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ କନେକ୍ସନ୍ ନାହିଁ"</string>
<string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
- <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଙ୍ଗର କ୍ରମ ସଂଶୋଧନ କରନ୍ତୁ।"</string>
+ <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଂସର କ୍ରମ ଏଡିଟ କରନ୍ତୁ।"</string>
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌"</string>
@@ -826,7 +825,7 @@
<string name="controls_error_generic" msgid="352500456918362905">"ସ୍ଥିତି ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string>
<string name="controls_menu_add" msgid="4447246119229920050">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରନ୍ତୁ"</string>
- <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ୍ କରନ୍ତୁ"</string>
+ <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"ଆଉଟପୁଟ୍ ଯୋଗ କରନ୍ତୁ"</string>
<string name="media_output_dialog_group" msgid="5571251347877452212">"ଗୋଷ୍ଠୀ"</string>
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"1ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string>
@@ -938,7 +937,7 @@
<string name="clipboard_editor" msgid="2971197550401892843">"କ୍ଲିପବୋର୍ଡ ଏଡିଟର"</string>
<string name="clipboard_overlay_window_name" msgid="6450043652167357664">"କ୍ଲିପବୋର୍ଡ"</string>
<string name="clipboard_image_preview" msgid="2156475174343538128">"ଇମେଜ ପ୍ରିଭ୍ୟୁ"</string>
- <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ"</string>
+ <string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ କରନ୍ତୁ"</string>
<string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string>
<string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ଆଉଟପୁଟ ବଦଳାନ୍ତୁ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ଅଜଣା"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0ca2cde2b9ef..d41e43c3c935 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"ਡੀਵਾਈਸ ਲਾਕ ਹੈ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ਚਿਹਰਾ ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ਭੇਜੋ"</string>
- <string name="phone_label" msgid="5715229948920451352">"ਫ਼ੋਨ ਖੋਲ੍ਹੋ"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਖੋਲ੍ਹੋ"</string>
- <string name="camera_label" msgid="8253821920931143699">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string>
<string name="cancel" msgid="1089011503403416730">"ਰੱਦ ਕਰੋ"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"ਤਸਦੀਕ ਕਰੋ"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ।"</string>
@@ -365,7 +364,7 @@
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ਸ਼ਾਂਤ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
- <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
+ <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ਅਗਿਆਤ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0da22d55da3e..36bbbc4ccbc0 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Urządzenie zablokowane"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanowanie twarzy"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Wyślij"</string>
- <string name="phone_label" msgid="5715229948920451352">"otwórz telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"otwórz pomoc głosową"</string>
- <string name="camera_label" msgid="8253821920931143699">"otwórz aparat"</string>
<string name="cancel" msgid="1089011503403416730">"Anuluj"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potwierdź"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Spróbuj jeszcze raz"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Kliknij jeszcze raz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Aby otworzyć, kliknij ikonę odblokowywania"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odblokowano skanem twarzy. Aby otworzyć, kliknij ikonę odblokowywania."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odblokowano rozpoznawaniem twarzy. Naciśnij, by otworzyć."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Twarz rozpoznana. Naciśnij, by otworzyć."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmisja aplikacji <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmień dane wyjściowe"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Brak informacji"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d166901ace8d..0cb7420785ba 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
- <string name="phone_label" msgid="5715229948920451352">"abrir telefone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistência de voz"</string>
- <string name="camera_label" msgid="8253821920931143699">"abrir câmera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 8c5369869806..9702b9759793 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"A analisar o rosto…"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
- <string name="phone_label" msgid="5715229948920451352">"abrir telemóvel"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistente de voz"</string>
- <string name="camera_label" msgid="8253821920931143699">"abrir câmara"</string>
<string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Prima o ícone de desbloqueio para abrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueio com a face. Prima ícone de desbloqueio p/ abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado com o rosto. Prima para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Prima para abrir."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmita a app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Altere a saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecida"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d166901ace8d..0cb7420785ba 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispositivo bloqueado"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
- <string name="phone_label" msgid="5715229948920451352">"abrir telefone"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"abrir assistência de voz"</string>
- <string name="camera_label" msgid="8253821920931143699">"abrir câmera"</string>
<string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pressione o ícone de desbloqueio para abrir"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Desbloqueado pelo rosto. Toque no ícone do cadeado para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Desbloqueado pelo rosto. Pressione para abrir."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Rosto reconhecido. Pressione para abrir."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d de MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 88f9963615c4..99d2f06b2970 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Dispozitiv blocat"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanarea chipului"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Trimiteți"</string>
- <string name="phone_label" msgid="5715229948920451352">"deschideți telefonul"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"deschideți asistentul vocal"</string>
- <string name="camera_label" msgid="8253821920931143699">"deschideți camera foto"</string>
<string name="cancel" msgid="1089011503403416730">"Anulați"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmați"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Încercați din nou"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Atingeți din nou"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Apăsați pictograma de deblocare pentru a deschide"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"S-a deblocat cu ajutorul feței. Apăsați pictograma de deblocare pentru a deschide"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"S-a deblocat cu ajutorul feței. Apăsați pentru a deschide."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Chipul a fost recunoscut. Apăsați pentru a deschide."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și e conectat la internet prin <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dispozitivul aparține organizației dvs."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin rețele VPN."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Schimbați rezultatul"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Necunoscută"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EE, z LLL"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index fefdd81d3533..817fdc0e275d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Устройство заблокировано"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканирование лица"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Отправить"</string>
- <string name="phone_label" msgid="5715229948920451352">"Открыть телефон."</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"включить аудиоподсказки"</string>
- <string name="camera_label" msgid="8253821920931143699">"Открыть камеру."</string>
<string name="cancel" msgid="1089011503403416730">"Отмена"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Подтвердить"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторить попытку"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Нажмите на значок разблокировки."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Разблокировано сканированием лица. Нажмите, чтобы открыть."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лицо распознано. Нажмите, чтобы открыть."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\"."</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Это устройство принадлежит вашей организации и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устр-во принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Это устройство принадлежит вашей организации"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Это устройство принадлежит вашей организации и подключено к интернету через сети VPN"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Транслировать на другое устройство"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM EEEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 3c0d8392f829..8c7b85cbe287 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"උපාංගය අගුලු දමා ඇත"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"මුහුණ ස්කෑන් කිරීම"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"යවන්න"</string>
- <string name="phone_label" msgid="5715229948920451352">"දුරකථනය විවෘත කරන්න"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"විවෘත හඬ සහාය"</string>
- <string name="camera_label" msgid="8253821920931143699">"කැමරාව විවෘත කරන්න"</string>
<string name="cancel" msgid="1089011503403416730">"අවලංගු කරන්න"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"තහවුරු කරන්න"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"නැවත උත්සාහ කරන්න"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"මුහුණ මගින් අගුලු හරින ලදි. විවෘත කිරීමට ඔබන්න."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට ඔබන්න."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ප්‍රතිදානය වෙනස් කරන්න"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"නොදනී"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index cbd4559b5e68..4bdd20601559 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Zariadenie je uzamknuté"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenovanie tváre"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odoslať"</string>
- <string name="phone_label" msgid="5715229948920451352">"otvoriť telefón"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"otvoriť hlasového asistenta"</string>
- <string name="camera_label" msgid="8253821920931143699">"spustiť fotoaparát"</string>
<string name="cancel" msgid="1089011503403416730">"Zrušiť"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdiť"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Skúsiť znova"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Klepnite znova"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Otvorte klepnutím na ikonu odomknutia"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odomknuté tvárou. Otvorte klepnutím na ikonu odomknutia."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odomknuté tvárou. Otvorte stlačením."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Tvár bola rozpoznaná. Otvorte stlačením."</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlastní toto zariadenie a môže sledovať sieťovú premávku"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zariadenie poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené cez aplikáciu <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zariadenie patrí vašej organizácii"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zariadení patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom sietí VPN"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysielanie aplikácie <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmena výstupu"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznáme"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e723b1b10055..c1afc12ccc54 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Naprava je zaklenjena."</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Optično branje obraza"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošlji"</string>
- <string name="phone_label" msgid="5715229948920451352">"odpri telefon"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"odpri glasovnega pomočnika"</string>
- <string name="camera_label" msgid="8253821920931143699">"odpri fotoaparat"</string>
<string name="cancel" msgid="1089011503403416730">"Prekliči"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potrdite"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Poskusi znova"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Znova se dotaknite možnosti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Za odpiranje pritisnite ikono za odklepanje."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Odklenjeno z obrazom. Za odpiranje pritisnite ikono za odklepanje."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Odklenjeno z obrazom. Pritisnite za odpiranje."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Obraz je prepoznan. Pritisnite za odpiranje."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Sprememba izhoda"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznano"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d. MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4b19b367642a..c3cdf21857c3 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Pajisja është e kyçur"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Po skanon fytyrën"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Dërgo"</string>
- <string name="phone_label" msgid="5715229948920451352">"hap telefonin"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"hap ndihmën zanore"</string>
- <string name="camera_label" msgid="8253821920931143699">"hap kamerën"</string>
<string name="cancel" msgid="1089011503403416730">"Anulo"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmo"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Provo përsëri"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Trokit sërish"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Shtyp ikonën e shkyçjes për ta hapur"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për ta hapur."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"U shkyç me fytyrë. Shtyp për ta hapur."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Fytyra u njoh. Shtyp për ta hapur."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmeto <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ndrysho daljen"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"I panjohur"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 15d31bd073f0..ef5993bd9fdd 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Уређај је закључан"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string>
- <string name="phone_label" msgid="5715229948920451352">"отвори телефон"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"отвори гласовну помоћ"</string>
- <string name="camera_label" msgid="8253821920931143699">"отвори камеру"</string>
<string name="cancel" msgid="1089011503403416730">"Откажи"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Пробај поново"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Притисните икону откључавања да бисте отворили."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Откључано је лицем. Притисните икону откључавања да бисте отворили."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Откључано је лицем. Притисните да бисте отворили."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Лице је препознато. Притисните да бисте отворили."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"ДДД, д. МММ"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"с:мин"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"ч:мин"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index effe9e539ed4..20bc29fc77ce 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Enheten är låst"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Registrerar ansikte"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Skicka"</string>
- <string name="phone_label" msgid="5715229948920451352">"öppna mobilen"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"öppna röstassistenten"</string>
- <string name="camera_label" msgid="8253821920931143699">"öppna kameran"</string>
<string name="cancel" msgid="1089011503403416730">"Avbryt"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekräfta"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Försök igen"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Tryck igen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Tryck på ikonen lås upp för att öppna"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att öppna."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Upplåst med ansiktslås. Tryck för att öppna."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ansiktet har identifierats. Tryck för att öppna."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sänd från <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Byt ljudutgång"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Okänt"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h.mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk.mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 6c8e02f3de8e..418b88eede96 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Kifaa kimefungwa"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Inachanganua uso"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Tuma"</string>
- <string name="phone_label" msgid="5715229948920451352">"fungua simu"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"fungua mapendekezo ya sauti"</string>
- <string name="camera_label" msgid="8253821920931143699">"fungua kamera"</string>
<string name="cancel" msgid="1089011503403416730">"Ghairi"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Thibitisha"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Jaribu tena"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Gusa tena"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Bonyeza aikoni ya kufungua ili ufungue"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili ufungue."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili ufungue."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Uso umetambuliwa. Bonyeza ili ufungue."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Tangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Badilisha maudhui"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Haijulikani"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"saa:dk"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dk"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 36767ea2d407..34cb0cf9de5b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"சாதனம் பூட்டப்பட்டுள்ளது"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"முகத்தை ஸ்கேன் செய்கிறது"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"அனுப்பு"</string>
- <string name="phone_label" msgid="5715229948920451352">"ஃபோனைத் திற"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"குரல் உதவியைத் திற"</string>
- <string name="camera_label" msgid="8253821920931143699">"கேமராவைத் திற"</string>
<string name="cancel" msgid="1089011503403416730">"ரத்துசெய்"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"உறுதிப்படுத்துக"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"மீண்டும் முயல்க"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"திறக்க, அன்லாக் ஐகானை அழுத்தவும்"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க, அன்லாக் ஐகானை அழுத்துக."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. திறக்க அழுத்தவும்."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அழுத்தவும்."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பு"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"அவுட்புட்டை மாற்று"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"தெரியவில்லை"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 4d124f5ed6e7..720c909b5223 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -50,7 +50,7 @@
<string name="usb_debugging_title" msgid="8274884945238642726">"USB డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
<string name="usb_debugging_message" msgid="5794616114463921773">"ఇది కంప్యూటర్ యొక్క RSA కీ వేలిముద్ర:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="4003121804294739548">"ఈ కంప్యూటర్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
- <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించు"</string>
+ <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించండి"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
<string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"మీరు సిస్టమ్ భాషను <xliff:g id="LANGUAGE">%1$s</xliff:g> భాషకు మార్చాలనుకుంటున్నారా?"</string>
@@ -60,7 +60,7 @@
<string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్‌వర్క్ ద్వారా వైర్‌లెస్ డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
<string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్‌వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi అడ్రస్ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
<string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
- <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించు"</string>
+ <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించండి"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"వైర్‌లెస్ డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
<string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన యూజర్, వైర్‌లెస్ డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక యూజర్ కి స్విచ్ అవ్వండి."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"USB పోర్ట్‌ నిలిపివేయబడింది"</string>
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"పరికరం లాక్ చేయబడింది"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ముఖాన్ని స్కాన్ చేస్తోంది"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"పంపు"</string>
- <string name="phone_label" msgid="5715229948920451352">"ఫోన్‌ను తెరువు"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"వాయిస్ అసిస్టెంట్‌ను తెరువు"</string>
- <string name="camera_label" msgid="8253821920931143699">"కెమెరాను తెరవండి"</string>
<string name="cancel" msgid="1089011503403416730">"రద్దు చేయండి"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"నిర్ధారించు"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"మళ్లీ ప్రయత్నించు"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. తెరవడానికి నొక్కండి."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"ముఖం గుర్తించబడింది. తెరవడానికి నొక్కండి."</string>
@@ -480,7 +479,7 @@
<string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"హాట్‌స్పాట్"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ఆఫీస్ ప్రొఫైల్‌"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string>
- <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్‌ఫేస్‌ను మెరుగుపరచడానికి మరియు అనుకూలీకరించడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
+ <string name="tuner_warning" msgid="1861736288458481650">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్‌ఫేస్‌ను మెరుగుపరచడానికి మరియు అనుకూలంగా మార్చడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string>
<string name="got_it" msgid="477119182261892069">"అర్థమైంది"</string>
<string name="tuner_toast" msgid="3812684836514766951">"అభినందనలు! సెట్టింగ్‌లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string>
@@ -715,7 +714,7 @@
<string name="slice_permission_text_1" msgid="6675965177075443714">"- ఇది <xliff:g id="APP">%1$s</xliff:g> నుండి సమాచారాన్ని చదువుతుంది"</string>
<string name="slice_permission_text_2" msgid="6758906940360746983">"- ఇది <xliff:g id="APP">%1$s</xliff:g> లోపల చర్యలు తీసుకుంటుంది"</string>
<string name="slice_permission_checkbox" msgid="4242888137592298523">"ఏ యాప్ నుండి అయినా స్లైస్‌లను చూపించడానికి <xliff:g id="APP">%1$s</xliff:g>ని అనుమతించండి"</string>
- <string name="slice_permission_allow" msgid="6340449521277951123">"అనుమతించు"</string>
+ <string name="slice_permission_allow" msgid="6340449521277951123">"అనుమతించండి"</string>
<string name="slice_permission_deny" msgid="6870256451658176895">"తిరస్కరించు"</string>
<string name="auto_saver_title" msgid="6873691178754086596">"బ్యాటరీ సేవర్‌ని షెడ్యూల్ చేయడానికి నొక్కండి"</string>
<string name="auto_saver_text" msgid="3214960308353838764">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string>
@@ -750,7 +749,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్‌ను మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్‌లో భాగాన్ని మాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string>
- <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"యాక్సెసిబిలిటీ ఫీచర్‌లను తెరవడానికి ట్యాప్ చేయండి. సెట్టింగ్‌లలో ఈ బటన్‌ను అనుకూలీకరించండి లేదా రీప్లేస్ చేయండి.\n\n"<annotation id="link">"వీక్షణ సెట్టింగ్‌లు"</annotation></string>
+ <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"యాక్సెసిబిలిటీ ఫీచర్‌లను తెరవడానికి ట్యాప్ చేయండి. సెట్టింగ్‌లలో ఈ బటన్‌ను అనుకూలంగా మార్చండి లేదా రీప్లేస్ చేయండి.\n\n"<annotation id="link">"వీక్షణ సెట్టింగ్‌లు"</annotation></string>
<string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"తాత్కాలికంగా దానిని దాచడానికి బటన్‌ను చివరకు తరలించండి"</string>
<string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ఎగువ ఎడమ వైపునకు తరలించు"</string>
<string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ఎగువ కుడి వైపునకు తరలించు"</string>
@@ -821,7 +820,7 @@
<string name="controls_error_timeout" msgid="794197289772728958">"ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
<string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string>
- <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ను యాక్సెస్ చేయడం సాధ్యపడలేదు. <xliff:g id="APPLICATION">%2$s</xliff:g> యాప్‌ను తనిఖీ చేసి, కంట్రోల్ ఇప్పటికీ అందుబాటులో ఉందని, యాప్ సెట్టింగ్‌లు మారలేదని నిర్ధారించుకోండి."</string>
+ <string name="controls_error_removed_message" msgid="2885911717034750542">"<xliff:g id="DEVICE">%1$s</xliff:g>ను యాక్సెస్ చేయడం సాధ్యపడలేదు. <xliff:g id="APPLICATION">%2$s</xliff:g> యాప్‌ను చెక్ చేసి, కంట్రోల్ ఇప్పటికీ అందుబాటులో ఉందని, యాప్ సెట్టింగ్‌లు మారలేదని నిర్ధారించుకోండి."</string>
<string name="controls_open_app" msgid="483650971094300141">"యాప్‌ను తెరువు"</string>
<string name="controls_error_generic" msgid="352500456918362905">"స్టేటస్ లోడ్ చేయడం సాధ్యపడలేదు"</string>
<string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"అవుట్‌పుట్‌ను మార్చండి"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"తెలియదు"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 94f6c3952e06..375bd394bb4c 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -22,7 +22,7 @@
<resources>
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" translatable="false">
- com.android.systemui.tv.TvSystemUIFactory
+ com.android.systemui.tv.TvSystemUIInitializer
</string>
<!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8daf4b58e747..8958be0ea95a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"อุปกรณ์ถูกล็อก"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"กำลังสแกนใบหน้า"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ส่ง"</string>
- <string name="phone_label" msgid="5715229948920451352">"เปิดโทรศัพท์"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"เปิดตัวช่วยเสียง"</string>
- <string name="camera_label" msgid="8253821920931143699">"เปิดกล้อง"</string>
<string name="cancel" msgid="1089011503403416730">"ยกเลิก"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"ยืนยัน"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"ลองอีกครั้ง"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"กดไอคอนปลดล็อกเพื่อเปิด"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อเปิด"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อเปิด"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"จดจำใบหน้าได้ กดเพื่อเปิด"</string>
@@ -915,12 +914,12 @@
<string name="wifi_scan_notify_message" msgid="3753839537448621794">"เพื่อปรับปรุงประสบการณ์การใช้อุปกรณ์ แอปและบริการต่างๆ จะยังคงสแกนหาเครือข่าย Wi‑Fi ได้ทุกเมื่อแม้ว่า Wi‑Fi จะปิดอยู่ คุณเปลี่ยนตัวเลือกนี้ได้ในการตั้งค่าการสแกนหา Wi-Fi "<annotation id="link">"เปลี่ยนการตั้งค่า"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"ปิดโหมดบนเครื่องบิน"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ต้องการเพิ่มองค์ประกอบต่อไปนี้ในการตั้งค่าด่วน"</string>
- <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มชิ้นส่วน"</string>
- <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่ต้องเพิ่มชิ้นส่วน"</string>
+ <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มองค์ประกอบ"</string>
+ <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่เพิ่มองค์ประกอบ"</string>
<string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"เลือกผู้ใช้"</string>
<string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{ทำงานอยู่ # แอป}other{ทำงานอยู่ # แอป}}"</string>
<string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string>
- <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</string>
+ <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ทำงานอยู่"</string>
<string name="fgs_manager_dialog_message" msgid="2670045017200730076">"แอปเหล่านี้กำลังทำงานแม้ว่าคุณจะไม่ได้ใช้งานอยู่ก็ตาม วิธีนี้ช่วยให้ฟังก์ชันการทำงานของแอปมีประสิทธิภาพมากขึ้น แต่ก็อาจส่งผลต่ออายุการใช้งานแบตเตอรี่ด้วย"</string>
<string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"หยุด"</string>
<string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"หยุดแล้ว"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"เปลี่ยนเอาต์พุต"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ไม่ทราบ"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"HH:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e8c191b91633..134005c85545 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Naka-lock ang device"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Sina-scan ang mukha"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ipadala"</string>
- <string name="phone_label" msgid="5715229948920451352">"buksan ang telepono"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"buksan ang voice assist"</string>
- <string name="camera_label" msgid="8253821920931143699">"buksan ang camera"</string>
<string name="cancel" msgid="1089011503403416730">"Kanselahin"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kumpirmahin"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Subukang muli"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"I-tap ulit"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Pindutin ang icon ng unlock para buksan"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para buksan."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Na-unlock gamit ang mukha. Pindutin para buksan."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Nakilala ang mukha. Pindutin para buksan."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Baguhin ang output"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Hindi alam"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index adb3fb4c40a5..fb928b2f5c4a 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Cihaz kilitlendi"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Yüz taranıyor"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gönder"</string>
- <string name="phone_label" msgid="5715229948920451352">"telefonu aç"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"sesli yardımı aç"</string>
- <string name="camera_label" msgid="8253821920931143699">"kamerayı aç"</string>
<string name="cancel" msgid="1089011503403416730">"İptal"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Onayla"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tekrar dene"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Tekrar dokunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Açmak için Kilit açma simgesine basın"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Cihazın kilidini yüzünüzle açtınız. Açmak için basın."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yüzünüz tanındı. Açmak için basın."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapın"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Çıkışı değiştirme"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Bilinmiyor"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"d MMM, EEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:dd"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 66fb209fb9df..3df26f662787 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Пристрій заблоковано"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканування обличчя"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Надіслати"</string>
- <string name="phone_label" msgid="5715229948920451352">"відкрити телефон"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"запустити голосові підказки"</string>
- <string name="camera_label" msgid="8253821920931143699">"відкрити камеру"</string>
<string name="cancel" msgid="1089011503403416730">"Скасувати"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Підтвердити"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторити спробу"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Щоб відкрити, натисніть значок розблокування."</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Розблоковано (фейсконтроль). Натисніть, щоб відкрити."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Обличчя розпізнано. Натисніть, щоб відкрити."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Змінити додаток для трансляції на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змінити аудіовихід"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невідомо"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, d MMM"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index c40927e28208..40e0bb3e3148 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"آلہ مقفل کر دیا گیا"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"اسکیننگ چہرہ"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"بھیجیں"</string>
- <string name="phone_label" msgid="5715229948920451352">"فون کھولیں"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"صوتی معاون کھولیں"</string>
- <string name="camera_label" msgid="8253821920931143699">"کیمرا کھولیں"</string>
<string name="cancel" msgid="1089011503403416730">"منسوخ کريں"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"تصدیق کریں"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"دوبارہ کوشش کریں"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"کھولنے کیلئے انلاک آئیکن دبائیں"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"چہرے سے انلاک کیا گیا۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"چہرے سے انلاک کیا گیا۔ کھولنے کے لیے دبائیں۔"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"چہرے کی شناخت ہو گئی۔ کھولنے کے لیے دبائیں۔"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> پر براڈکاسٹ کریں"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"آؤٹ پٹ تبدیل کریں"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامعلوم"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index f9ad0b73e700..a6490f429742 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Qurilma qulflandi"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Yuzni skanerlash"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Yuborish"</string>
- <string name="phone_label" msgid="5715229948920451352">"telefonni ochish"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"ovozli yordamni yoqish"</string>
- <string name="camera_label" msgid="8253821920931143699">"kamerani ochish"</string>
<string name="cancel" msgid="1089011503403416730">"Bekor qilish"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"OK"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Qayta urinish"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Yana bosing"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Ochish uchun ochish belgisini bosing"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Yuz orqali ochilgan. Ochish uchun ochish belgisini bosing."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Yuz orqali ochildi. Ochish uchun bosing."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Yuz aniqlandi. Ochish uchun bosing."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ovoz chiqishini oʻzgartirish"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Noaniq"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"s:dd"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 7df433910076..3a579f15ead4 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Đã khóa thiết bị"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Quét tìm khuôn mặt"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gửi"</string>
- <string name="phone_label" msgid="5715229948920451352">"mở điện thoại"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"mở trợ lý thoại"</string>
- <string name="camera_label" msgid="8253821920931143699">"mở máy ảnh"</string>
<string name="cancel" msgid="1089011503403416730">"Hủy"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Xác nhận"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Thử lại"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Nhấn lại"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Nhấn biểu tượng mở khoá để mở"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Đã mở khoá bằng khuôn mặt. Nhấn vào biểu tượng mở khoá để mở."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Đã mở khoá bằng khuôn mặt. Nhấn để mở."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Đã nhận diện khuôn mặt. Nhấn để mở."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Phát <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Thay đổi đầu ra"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Không xác định"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 62b1bd87bca5..b46406e9d31e 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"设备已锁定"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"正在扫描面孔"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"发送"</string>
- <string name="phone_label" msgid="5715229948920451352">"打开电话"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"打开语音助理"</string>
- <string name="camera_label" msgid="8253821920931143699">"打开相机"</string>
<string name="cancel" msgid="1089011503403416730">"取消"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"确认"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"重试"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"按下解锁图标即可打开"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已通过面孔识别解锁。按下解锁图标即可打开。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已通过面孔识别解锁。点按即可打开。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"识别出面孔。点按即可打开。"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"更改输出来源"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"未知"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 2ac494a20db5..1958d0df7401 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已上鎖"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"掃瞄緊面孔"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
- <string name="phone_label" msgid="5715229948920451352">"開啟電話"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"開啟語音助手"</string>
- <string name="camera_label" msgid="8253821920931143699">"開啟相機"</string>
<string name="cancel" msgid="1089011503403416730">"取消"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"請再試一次"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"再次輕按"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"按解鎖圖示即可開啟"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"已使用面孔解鎖。按解鎖圖示即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"已使用面孔解鎖。按下即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"已識別面孔。按下即可開啟。"</string>
@@ -374,7 +373,7 @@
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
<string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此裝置屬於您的機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
- <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置由「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」所有,並透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於您的機構"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」"</string>
<string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此裝置屬於您的機構,並已透過 VPN 連接至互聯網"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index a0fe941eb5a6..22d0544f3314 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"裝置已鎖定"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"掃描臉孔"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
- <string name="phone_label" msgid="5715229948920451352">"開啟電話"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"開啟語音小幫手"</string>
- <string name="camera_label" msgid="8253821920931143699">"開啟攝影機"</string>
<string name="cancel" msgid="1089011503403416730">"取消"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試一次"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"按下「解鎖」圖示即可開啟"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"裝置已透過人臉解鎖,按下「解鎖」圖示即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"裝置已透過你的臉解鎖,按下即可開啟。"</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"臉孔辨識完成,按下即可開啟。"</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"MMM d EEE"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 47de98eadb9a..4000ce00de59 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -124,9 +124,6 @@
<string name="accessibility_lock_icon" msgid="661492842417875775">"Idivayisi ikhiyiwe"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"Ukuskena ubuso"</string>
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Thumela"</string>
- <string name="phone_label" msgid="5715229948920451352">"vula ifoni"</string>
- <string name="voice_assist_label" msgid="3725967093735929020">"vula isilekeleli sezwi"</string>
- <string name="camera_label" msgid="8253821920931143699">"vula ikhamera"</string>
<string name="cancel" msgid="1089011503403416730">"Khansela"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Qinisekisa"</string>
<string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zama futhi"</string>
@@ -310,6 +307,8 @@
<string name="tap_again" msgid="1315420114387908655">"Thepha futhi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
<string name="keyguard_unlock_press" msgid="9140109453735019209">"Cindezela isithonjana sokuvula ukuze uvule"</string>
+ <!-- no translation found for keyguard_face_successful_unlock_swipe (6180997591385846073) -->
+ <skip />
<string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uvule."</string>
<string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"Vula ngobuso. Cindezela ukuze uvule."</string>
<string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"Ubuso buyaziwa. Cindezela ukuze uvule."</string>
@@ -953,4 +952,7 @@
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Shintsha okuphumayo"</string>
<string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Akwaziwa"</string>
+ <string name="dream_date_complication_date_format" msgid="8191225366513860104">"EEE, MMM d"</string>
+ <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
+ <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index ccf18d2a0bb1..1eece4cee179 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -129,7 +129,6 @@
<color name="smart_reply_button_stroke">@*android:color/accent_device_default</color>
<!-- Biometric dialog colors -->
- <color name="biometric_dialog_dim_color">#80000000</color> <!-- 50% black -->
<color name="biometric_dialog_gray">#ff757575</color>
<color name="biometric_dialog_accent">@color/material_dynamic_primary40</color>
<color name="biometric_dialog_error">#ffd93025</color> <!-- red 600 -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 771973c36053..82a3b58a5155 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -286,7 +286,7 @@
<bool name="config_enableFullscreenUserSwitcher">false</bool>
<!-- SystemUIFactory component -->
- <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
+ <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIInitializerImpl</string>
<!-- QS tile shape store width. negative implies fill configuration instead of stroke-->
<dimen name="config_qsTileStrokeWidthActive">-1dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 13250c879d5d..ec69d720413f 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1443,6 +1443,7 @@
@*android:dimen/status_bar_system_icon_size</dimen>
<dimen name="dream_overlay_camera_mic_off_indicator_size">8dp</dimen>
<dimen name="dream_overlay_notification_indicator_size">6dp</dimen>
+ <dimen name="dream_overlay_grey_chip_width">56dp</dimen>
<!-- Dream overlay complications related dimensions -->
<dimen name="dream_overlay_complication_clock_time_text_size">100sp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ef672f3a6213..9c2542cbd05f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -802,6 +802,8 @@
<!-- Message shown when lock screen is unlocked (ie: by trust agent) and the user taps the empty space on the lock screen and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
<string name="keyguard_unlock_press">Press the unlock icon to open</string>
+ <!-- Message shown when non-bypass face authentication succeeds. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
+ <string name="keyguard_face_successful_unlock_swipe">Unlocked by face. Swipe up to open.</string>
<!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
<string name="keyguard_face_successful_unlock_press">Unlocked by face. Press the unlock icon to open.</string>
<!-- Message shown when non-bypass face authentication succeeds and UDFPS is supported. Provides extra instructions for how the user can enter their device [CHAR LIMIT=60] -->
@@ -2295,8 +2297,8 @@
<string name="media_output_dialog_disconnected">(disconnected)</string>
<!-- Summary for connecting error message [CHAR LIMIT=NONE] -->
<string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string>
- <!-- Title for pairing item [CHAR LIMIT=60] -->
- <string name="media_output_dialog_pairing_new">Pair new device</string>
+ <!-- Title for connecting item [CHAR LIMIT=60] -->
+ <string name="media_output_dialog_pairing_new">Connect a device</string>
<!-- Title for launch app [CHAR LIMIT=60] -->
<string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
<!-- App name when can't get app name [CHAR LIMIT=60] -->
@@ -2553,6 +2555,10 @@
<string name="dream_overlay_status_bar_priority_mode">Priority mode</string>
<!-- Content description for the alarm set icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
<string name="dream_overlay_status_bar_alarm_set">Alarm set</string>
+ <!-- Content description for the camera off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
+ <string name="dream_overlay_status_bar_camera_off">Camera is off</string>
+ <!-- Content description for the mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
+ <string name="dream_overlay_status_bar_mic_off">Mic is off</string>
<!-- Content description for the camera and mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
<string name="dream_overlay_status_bar_camera_mic_off">Camera and mic are off</string>
<!-- Content description for the notifications indicator icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
@@ -2560,6 +2566,10 @@
=1 {# notification}
other {# notifications}
}</string>
+ <!-- Accessibility label for weather complication on dreams with weather condition and temperature [CHAR_LIMIT=200] -->
+ <string name="dream_overlay_weather_complication_desc">
+ <xliff:g id="weather_condition" example="Partly cloudy">%1$s</xliff:g>, <xliff:g id="temperature" example="7°C">%2$s</xliff:g>
+ </string>
<!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is broadcasting -->
<string name="broadcasting_description_is_broadcasting">Broadcasting</string>
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index eab7defe1e52..9115d42fc42d 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -19,7 +19,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<Constraint
- android:id="@+id/media_action_barrier"
+ android:id="@+id/media_action_barrier_start"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/media_seamless"
@@ -91,12 +91,16 @@
app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/media_seamless"
- app:layout_constraintLeft_toRightOf="@id/media_action_barrier" />
+ app:layout_constraintLeft_toRightOf="@id/media_action_barrier_start" />
<!-- Showing time while scrubbing isn't available in collapsed mode. -->
<Constraint
android:id="@+id/media_scrubbing_elapsed_time"
- android:visibility="gone" />
+ android:visibility="gone"
+ app:layout_constraintRight_toLeftOf="@id/media_progress_bar"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/media_seamless"
+ app:layout_constraintLeft_toRightOf="@id/media_action_barrier_start" />
<Constraint
android:id="@+id/media_progress_bar"
@@ -124,7 +128,12 @@
<!-- Showing time while scrubbing isn't available in collapsed mode. -->
<Constraint
android:id="@+id/media_scrubbing_total_time"
- android:visibility="gone" />
+ android:visibility="gone"
+ app:layout_constraintVertical_bias="1"
+ app:layout_constraintLeft_toRightOf="@id/media_progress_bar"
+ app:layout_constraintRight_toLeftOf="@id/action0"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/media_seamless" />
<Constraint
android:id="@+id/action0"
diff --git a/packages/SystemUI/screenshot/Android.bp b/packages/SystemUI/screenshot/Android.bp
index a79fd9040db3..601e92fe20ea 100644
--- a/packages/SystemUI/screenshot/Android.bp
+++ b/packages/SystemUI/screenshot/Android.bp
@@ -26,11 +26,7 @@ android_library {
manifest: "AndroidManifest.xml",
srcs: [
- // All files in this library should be in Kotlin besides some exceptions.
"src/**/*.kt",
-
- // This file was forked from google3, so exceptionally it can be in Java.
- "src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java",
],
resource_dirs: [
diff --git a/packages/SystemUI/screenshot/AndroidManifest.xml b/packages/SystemUI/screenshot/AndroidManifest.xml
index 3b703be34e5d..a405836bd77f 100644
--- a/packages/SystemUI/screenshot/AndroidManifest.xml
+++ b/packages/SystemUI/screenshot/AndroidManifest.xml
@@ -23,6 +23,4 @@
android:exported="true"
android:theme="@style/Theme.SystemUI.Screenshot" />
</application>
-
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
</manifest>
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
new file mode 100644
index 000000000000..3d26cdab891d
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/Bitmap.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.os.Build
+import android.view.View
+import platform.test.screenshot.matchers.MSSIMMatcher
+import platform.test.screenshot.matchers.PixelPerfectMatcher
+
+/** Draw this [View] into a [Bitmap]. */
+fun View.drawIntoBitmap(): Bitmap {
+ val bitmap =
+ Bitmap.createBitmap(
+ measuredWidth,
+ measuredHeight,
+ Bitmap.Config.ARGB_8888,
+ )
+ val canvas = Canvas(bitmap)
+ draw(canvas)
+ return bitmap
+}
+
+/**
+ * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
+ * screenshot *unit* tests.
+ */
+val UnitTestBitmapMatcher =
+ if (Build.CPU_ABI == "x86_64") {
+ // Different CPU architectures can sometimes end up rendering differently, so we can't do
+ // pixel-perfect matching on different architectures using the same golden. Given that our
+ // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the
+ // x86_64 architecture and use the Structural Similarity Index on others.
+ // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can
+ // do pixel perfect matching both at presubmit time and at development time with actual
+ // devices.
+ PixelPerfectMatcher()
+ } else {
+ MSSIMMatcher()
+ }
+
+/**
+ * The [BitmapMatcher][platform.test.screenshot.matchers.BitmapMatcher] that should be used for
+ * screenshot *unit* tests.
+ *
+ * We use the Structural Similarity Index for integration tests because they usually contain
+ * additional information and noise that shouldn't break the test.
+ */
+val IntegrationTestBitmapMatcher = MSSIMMatcher()
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
deleted file mode 100644
index 96ec4c543474..000000000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import android.app.UiAutomation;
-import android.content.Context;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.ColorRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.core.content.ContextCompat;
-import androidx.test.espresso.Espresso;
-import androidx.test.espresso.IdlingRegistry;
-import androidx.test.espresso.IdlingResource;
-
-import org.json.JSONObject;
-import org.junit.function.ThrowingRunnable;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/*
- * Note: This file was forked from
- * google3/third_party/java_src/android_libs/material_components/screenshot_tests/java/android/
- * support/design/scuba/color/DynamicColorsTestUtils.java.
- */
-
-/** Utility that helps change the dynamic system colors for testing. */
-@RequiresApi(32)
-public class DynamicColorsTestUtils {
-
- private static final String TAG = DynamicColorsTestUtils.class.getSimpleName();
-
- private static final String THEME_CUSTOMIZATION_KEY = "theme_customization_overlay_packages";
- private static final String THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY =
- "android.theme.customization.system_palette";
-
- private static final int ORANGE_SYSTEM_SEED_COLOR = 0xA66800;
- private static final int ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR = -8235756;
-
- private DynamicColorsTestUtils() {
- }
-
- /**
- * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on an orange
- * seed color, and then wait for the change to propagate to the app by comparing
- * android.R.color.system_accent1_600 to the expected orange value.
- */
- public static void updateSystemColorsToOrange() {
- updateSystemColors(ORANGE_SYSTEM_SEED_COLOR, ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR);
- }
-
- /**
- * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
- * {@code seedColor}, and then wait for the change to propagate to the app by comparing
- * android.R.color.system_accent1_600 to {@code expectedSystemAccent1600}.
- */
- public static void updateSystemColors(
- @ColorInt int seedColor, @ColorInt int expectedSystemAccent1600) {
- Context context = getInstrumentation().getTargetContext();
-
- int actualSystemAccent1600 =
- ContextCompat.getColor(context, android.R.color.system_accent1_600);
-
- if (expectedSystemAccent1600 == actualSystemAccent1600) {
- String expectedColorString = Integer.toHexString(expectedSystemAccent1600);
- Log.d(
- TAG,
- "Skipped updating system colors since system_accent1_600 is already equal to "
- + "expected: "
- + expectedColorString);
- return;
- }
-
- updateSystemColors(seedColor);
- }
-
- /**
- * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
- * {@code seedColor}, and then wait for the change to propagate to the app by checking
- * android.R.color.system_accent1_600 for any change.
- */
- public static void updateSystemColors(@ColorInt int seedColor) {
- Context context = getInstrumentation().getTargetContext();
-
- // Initialize system color idling resource with original system_accent1_600 value.
- ColorChangeIdlingResource systemColorIdlingResource =
- new ColorChangeIdlingResource(context, android.R.color.system_accent1_600);
-
- // Update system theme color setting to trigger fabricated resource overlay.
- runWithShellPermissionIdentity(
- () ->
- Settings.Secure.putString(
- context.getContentResolver(),
- THEME_CUSTOMIZATION_KEY,
- buildThemeCustomizationString(seedColor)));
-
- // Wait for system color update to propagate to app.
- IdlingRegistry idlingRegistry = IdlingRegistry.getInstance();
- idlingRegistry.register(systemColorIdlingResource);
- Espresso.onIdle();
- idlingRegistry.unregister(systemColorIdlingResource);
-
- Log.d(TAG,
- Settings.Secure.getString(context.getContentResolver(), THEME_CUSTOMIZATION_KEY));
- }
-
- private static String buildThemeCustomizationString(@ColorInt int seedColor) {
- String seedColorHex = Integer.toHexString(seedColor);
- Map<String, String> themeCustomizationMap = new HashMap<>();
- themeCustomizationMap.put(THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY, seedColorHex);
- return new JSONObject(themeCustomizationMap).toString();
- }
-
- private static void runWithShellPermissionIdentity(@NonNull ThrowingRunnable runnable) {
- UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
- uiAutomation.adoptShellPermissionIdentity();
- try {
- runnable.run();
- } catch (Throwable e) {
- throw new RuntimeException(e);
- } finally {
- uiAutomation.dropShellPermissionIdentity();
- }
- }
-
- private static class ColorChangeIdlingResource implements IdlingResource {
-
- private final Context mContext;
- private final int mColorResId;
- private final int mInitialColorInt;
-
- private ResourceCallback mResourceCallback;
- private boolean mIdleNow;
-
- ColorChangeIdlingResource(Context context, @ColorRes int colorResId) {
- this.mContext = context;
- this.mColorResId = colorResId;
- this.mInitialColorInt = ContextCompat.getColor(context, colorResId);
- }
-
- @Override
- public String getName() {
- return ColorChangeIdlingResource.class.getName();
- }
-
- @Override
- public boolean isIdleNow() {
- if (mIdleNow) {
- return true;
- }
-
- int currentColorInt = ContextCompat.getColor(mContext, mColorResId);
-
- String initialColorString = Integer.toHexString(mInitialColorInt);
- String currentColorString = Integer.toHexString(currentColorInt);
- Log.d(TAG, String.format("Initial=%s, Current=%s", initialColorString,
- currentColorString));
-
- mIdleNow = currentColorInt != mInitialColorInt;
- Log.d(TAG, String.format("idleNow=%b", mIdleNow));
-
- if (mIdleNow) {
- mResourceCallback.onTransitionToIdle();
- }
- return mIdleNow;
- }
-
- @Override
- public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
- this.mResourceCallback = resourceCallback;
- }
- }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
deleted file mode 100644
index 564901c2a773..000000000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-import android.app.UiModeManager
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Canvas
-import android.os.Build
-import android.os.UserHandle
-import android.view.Display
-import android.view.View
-import android.view.WindowManagerGlobal
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-import platform.test.screenshot.GoldenImagePathManager
-import platform.test.screenshot.PathConfig
-import platform.test.screenshot.PathElementNoContext
-import platform.test.screenshot.ScreenshotTestRule
-import platform.test.screenshot.matchers.MSSIMMatcher
-import platform.test.screenshot.matchers.PixelPerfectMatcher
-
-/**
- * A base rule for screenshot diff tests.
- *
- * This rules takes care of setting up the activity according to [testSpec] by:
- * - emulating the display size and density.
- * - setting the dark/light mode.
- * - setting the system (Material You) colors to a fixed value.
- *
- * @see ComposeScreenshotTestRule
- * @see ViewScreenshotTestRule
- */
-class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule {
- private var currentDisplay: DisplaySpec? = null
- private var currentGoldenIdentifier: String? = null
-
- private val pathConfig =
- PathConfig(
- PathElementNoContext("model", isDir = true) {
- currentDisplay?.name ?: error("currentDisplay is null")
- },
- )
- private val matcher = if (shouldUsePerfectMatching()) {
- PixelPerfectMatcher()
- } else {
- MSSIMMatcher()
- }
-
- private val screenshotRule =
- ScreenshotTestRule(
- SystemUIGoldenImagePathManager(
- pathConfig,
- currentGoldenIdentifier = {
- currentGoldenIdentifier ?: error("currentGoldenIdentifier is null")
- },
- )
- )
-
- private fun shouldUsePerfectMatching(): Boolean {
- // Different CPU architectures can sometimes end up rendering differently, so we can't do
- // pixel-perfect matching on different architectures using the same golden. Given that our
- // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the
- // x86_64 architecture and use the Structural Similarity Index on others.
- // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can
- // do pixel perfect matching both at presubmit time and at development time with actual
- // devices.
- return Build.CPU_ABI == "x86_64"
- }
-
- override fun apply(base: Statement, description: Description): Statement {
- // The statement which call beforeTest() before running the test and afterTest() afterwards.
- val statement =
- object : Statement() {
- override fun evaluate() {
- try {
- beforeTest()
- base.evaluate()
- } finally {
- afterTest()
- }
- }
- }
-
- return screenshotRule.apply(statement, description)
- }
-
- private fun beforeTest() {
- // Update the system colors to a fixed color, so that tests don't depend on the host device
- // extracted colors. Note that we don't restore the default device colors at the end of the
- // test because changing the colors (and waiting for them to be applied) is costly and makes
- // the screenshot tests noticeably slower.
- DynamicColorsTestUtils.updateSystemColorsToOrange()
-
- // Emulate the display size and density.
- val display = testSpec.display
- val density = display.densityDpi
- val wm = WindowManagerGlobal.getWindowManagerService()
- val (width, height) = getEmulatedDisplaySize()
- wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density, UserHandle.myUserId())
- wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, width, height)
-
- // Force the dark/light theme.
- val uiModeManager =
- InstrumentationRegistry.getInstrumentation()
- .targetContext
- .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
- uiModeManager.setApplicationNightMode(
- if (testSpec.isDarkTheme) {
- UiModeManager.MODE_NIGHT_YES
- } else {
- UiModeManager.MODE_NIGHT_NO
- }
- )
- }
-
- private fun afterTest() {
- // Reset the density and display size.
- val wm = WindowManagerGlobal.getWindowManagerService()
- wm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, UserHandle.myUserId())
- wm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY)
-
- // Reset the dark/light theme.
- val uiModeManager =
- InstrumentationRegistry.getInstrumentation()
- .targetContext
- .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
- uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_AUTO)
- }
-
- /**
- * Compare the content of [view] with the golden image identified by [goldenIdentifier] in the
- * context of [testSpec].
- */
- fun screenshotTest(goldenIdentifier: String, view: View) {
- val bitmap = drawIntoBitmap(view)
-
- // Compare bitmap against golden asset.
- val isDarkTheme = testSpec.isDarkTheme
- val isLandscape = testSpec.isLandscape
- val identifierWithSpec = buildString {
- append(goldenIdentifier)
- if (isDarkTheme) append("_dark")
- if (isLandscape) append("_landscape")
- }
-
- // TODO(b/230832101): Provide a way to pass a PathConfig and override the file name on
- // device to assertBitmapAgainstGolden instead?
- currentDisplay = testSpec.display
- currentGoldenIdentifier = goldenIdentifier
- screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, matcher)
- currentDisplay = null
- currentGoldenIdentifier = goldenIdentifier
- }
-
- /** Draw [view] into a [Bitmap]. */
- private fun drawIntoBitmap(view: View): Bitmap {
- val bitmap =
- Bitmap.createBitmap(
- view.measuredWidth,
- view.measuredHeight,
- Bitmap.Config.ARGB_8888,
- )
- val canvas = Canvas(bitmap)
- view.draw(canvas)
- return bitmap
- }
-
- /** Get the emulated display size for [testSpec]. */
- private fun getEmulatedDisplaySize(): Pair<Int, Int> {
- val display = testSpec.display
- val isPortraitNaturalPosition = display.width < display.height
- return if (testSpec.isLandscape) {
- if (isPortraitNaturalPosition) {
- display.height to display.width
- } else {
- display.width to display.height
- }
- } else {
- if (isPortraitNaturalPosition) {
- display.width to display.height
- } else {
- display.height to display.width
- }
- }
- }
-}
-
-private class SystemUIGoldenImagePathManager(
- pathConfig: PathConfig,
- private val currentGoldenIdentifier: () -> String,
-) :
- GoldenImagePathManager(
- appContext = InstrumentationRegistry.getInstrumentation().context,
- deviceLocalPath =
- InstrumentationRegistry.getInstrumentation()
- .targetContext
- .filesDir
- .absolutePath
- .toString() + "/sysui_screenshots",
- pathConfig = pathConfig,
- ) {
- // This string is appended to all actual/expected screenshots on the device. We append the
- // golden identifier so that our pull_golden.py scripts can map a screenshot on device to its
- // asset (and automatically update it, if necessary).
- override fun toString() = currentGoldenIdentifier()
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
deleted file mode 100644
index 7fc624554738..000000000000
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.testing.screenshot
-
-/** The specification of a device display to be used in a screenshot test. */
-data class DisplaySpec(
- val name: String,
- val width: Int,
- val height: Int,
- val densityDpi: Int,
-)
-
-/** The specification of a screenshot diff test. */
-class ScreenshotTestSpec(
- val display: DisplaySpec,
- val isDarkTheme: Boolean = false,
- val isLandscape: Boolean = false,
-) {
- companion object {
- /**
- * Return a list of [ScreenshotTestSpec] for each of the [displays].
- *
- * If [isDarkTheme] is null, this will create a spec for both light and dark themes, for
- * each of the orientation.
- *
- * If [isLandscape] is null, this will create a spec for both portrait and landscape, for
- * each of the light/dark themes.
- */
- fun forDisplays(
- vararg displays: DisplaySpec,
- isDarkTheme: Boolean? = null,
- isLandscape: Boolean? = null,
- ): List<ScreenshotTestSpec> {
- return displays.flatMap { display ->
- buildList {
- fun addDisplay(isLandscape: Boolean) {
- if (isDarkTheme != true) {
- add(ScreenshotTestSpec(display, isDarkTheme = false, isLandscape))
- }
-
- if (isDarkTheme != false) {
- add(ScreenshotTestSpec(display, isDarkTheme = true, isLandscape))
- }
- }
-
- if (isLandscape != true) {
- addDisplay(isLandscape = false)
- }
-
- if (isLandscape != false) {
- addDisplay(isLandscape = true)
- }
- }
- }
- }
- }
-
- override fun toString(): String = buildString {
- // This string is appended to PNGs stored in the device, so let's keep it simple.
- append(display.name)
- if (isDarkTheme) append("_dark")
- if (isLandscape) append("_landscape")
- }
-}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
new file mode 100644
index 000000000000..cbab0a75061e
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/SystemUIGoldenImagePathManager.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import androidx.test.platform.app.InstrumentationRegistry
+import platform.test.screenshot.GoldenImagePathManager
+import platform.test.screenshot.PathConfig
+
+/** A [GoldenImagePathManager] that should be used for all SystemUI screenshot tests. */
+class SystemUIGoldenImagePathManager(
+ pathConfig: PathConfig,
+) :
+ GoldenImagePathManager(
+ appContext = InstrumentationRegistry.getInstrumentation().context,
+ deviceLocalPath =
+ InstrumentationRegistry.getInstrumentation()
+ .targetContext
+ .filesDir
+ .absolutePath
+ .toString() + "/sysui_screenshots",
+ pathConfig = pathConfig,
+ ) {
+ override fun toString(): String {
+ // This string is appended to all actual/expected screenshots on the device, so make sure
+ // it is a static value.
+ return "SystemUIGoldenImagePathManager"
+ }
+}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
index 6a80c486d515..3209c8bb1f8a 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.systemui.testing.screenshot
import android.app.Activity
@@ -11,21 +27,35 @@ import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
+import platform.test.screenshot.DeviceEmulationRule
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.MaterialYouColorsRule
+import platform.test.screenshot.ScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
-/** A rule for View screenshot diff tests. */
-class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
+/** A rule for View screenshot diff unit tests. */
+class ViewScreenshotTestRule(emulationSpec: DeviceEmulationSpec) : TestRule {
+ private val colorsRule = MaterialYouColorsRule()
+ private val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
+ private val screenshotRule =
+ ScreenshotTestRule(
+ SystemUIGoldenImagePathManager(getEmulatedDevicePathConfig(emulationSpec))
+ )
private val activityRule = ActivityScenarioRule(ScreenshotActivity::class.java)
- private val screenshotRule = ScreenshotTestRule(testSpec)
-
- private val delegate = RuleChain.outerRule(screenshotRule).around(activityRule)
+ private val delegateRule =
+ RuleChain.outerRule(colorsRule)
+ .around(deviceEmulationRule)
+ .around(screenshotRule)
+ .around(activityRule)
+ private val matcher = UnitTestBitmapMatcher
override fun apply(base: Statement, description: Description): Statement {
- return delegate.apply(base, description)
+ return delegateRule.apply(base, description)
}
/**
* Compare the content of the view provided by [viewProvider] with the golden image identified
- * by [goldenIdentifier] in the context of [testSpec].
+ * by [goldenIdentifier] in the context of [emulationSpec].
*/
fun screenshotTest(
goldenIdentifier: String,
@@ -46,13 +76,17 @@ class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
// Check that the content is what we expected.
val content = activity.requireViewById<ViewGroup>(android.R.id.content)
assertEquals(1, content.childCount)
- screenshotRule.screenshotTest(goldenIdentifier, content.getChildAt(0))
+ screenshotRule.assertBitmapAgainstGolden(
+ content.getChildAt(0).drawIntoBitmap(),
+ goldenIdentifier,
+ matcher
+ )
}
}
/**
* Compare the content of the dialog provided by [dialogProvider] with the golden image
- * identified by [goldenIdentifier] in the context of [testSpec].
+ * identified by [goldenIdentifier] in the context of [emulationSpec].
*/
fun dialogScreenshotTest(
goldenIdentifier: String,
@@ -81,7 +115,11 @@ class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
// Check that the content is what we expected.
val dialog = dialog ?: error("dialog is null")
try {
- screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView)
+ screenshotRule.assertBitmapAgainstGolden(
+ dialog.window.decorView.drawIntoBitmap(),
+ goldenIdentifier,
+ matcher,
+ )
} finally {
dialog.dismiss()
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index b02088acbb1b..3d72f15492c5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -22,11 +22,11 @@ import android.view.LayoutInflater
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.Clock
import com.android.systemui.plugins.ClockAnimations
-import com.android.systemui.plugins.ClockDarkness
import com.android.systemui.plugins.ClockEvents
import com.android.systemui.plugins.ClockId
import com.android.systemui.plugins.ClockMetadata
import com.android.systemui.plugins.ClockProvider
+import com.android.systemui.plugins.RegionDarkness
import com.android.systemui.shared.R
import java.io.PrintWriter
import java.util.Locale
@@ -84,13 +84,17 @@ class DefaultClock(
resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale_burmese)
private val defaultLineSpacing = resources.getFloat(R.dimen.keyguard_clock_line_spacing_scale)
- private fun updateClockColor(clock: AnimatableClockView, darkValue: ClockDarkness) {
- val color = if (darkValue.isDark) {
- resources.getColor(android.R.color.system_accent2_600)
+ private var smallRegionDarkness = RegionDarkness.DEFAULT
+ private var largeRegionDarkness = RegionDarkness.DEFAULT
+
+ private fun updateClockColor(clock: AnimatableClockView, isRegionDark: RegionDarkness) {
+ val color = if (isRegionDark.isDark) {
+ resources.getColor(android.R.color.system_accent2_100)
} else {
- resources.getColor(android.R.color.system_accent1_100)
+ resources.getColor(android.R.color.system_accent1_600)
}
clock.setColors(DOZE_COLOR, color)
+ clock.animateAppearOnLockscreen()
}
override val events = object : ClockEvents {
@@ -116,11 +120,17 @@ class DefaultClock(
override fun onColorPaletteChanged(
resources: Resources,
- smallClockIsDark: ClockDarkness,
- largeClockIsDark: ClockDarkness
+ smallClockIsDark: RegionDarkness,
+ largeClockIsDark: RegionDarkness
) {
- updateClockColor(smallClock, smallClockIsDark)
- updateClockColor(largeClock, largeClockIsDark)
+ if (smallRegionDarkness != smallClockIsDark) {
+ smallRegionDarkness = smallClockIsDark
+ updateClockColor(smallClock, smallClockIsDark)
+ }
+ if (largeRegionDarkness != largeClockIsDark) {
+ largeRegionDarkness = largeClockIsDark
+ updateClockColor(largeClock, largeClockIsDark)
+ }
}
override fun onLocaleChanged(locale: Locale) {
@@ -198,13 +208,17 @@ class DefaultClock(
clocks.forEach { it.setColors(DOZE_COLOR, DOZE_COLOR) }
}
- override fun initialize(resources: Resources, dozeFraction: Float, foldFraction: Float) {
+ override fun initialize(
+ resources: Resources,
+ dozeFraction: Float,
+ foldFraction: Float
+ ) {
recomputePadding()
animations = DefaultClockAnimations(dozeFraction, foldFraction)
events.onColorPaletteChanged(
resources,
- ClockDarkness.DEFAULT,
- ClockDarkness.DEFAULT
+ RegionDarkness.DEFAULT,
+ RegionDarkness.DEFAULT
)
events.onTimeTick()
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
new file mode 100644
index 000000000000..f8f7c24c7c14
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shared.regionsampling
+
+import android.content.res.Resources
+import android.graphics.Rect
+import android.view.View
+import com.android.systemui.plugins.Clock
+import com.android.systemui.plugins.RegionDarkness
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper.SamplingCallback
+import java.io.PrintWriter
+import java.util.concurrent.Executor
+
+/**
+ * Class for instance of RegionSamplingHelper
+ */
+class RegionSamplingInstance(
+ sampledView: View?,
+ mainExecutor: Executor?,
+ bgExecutor: Executor?,
+ regionSamplingEnabled: Boolean,
+ clock: Clock?,
+ resources: Resources
+) {
+ private var isDark = RegionDarkness.DEFAULT
+ private var samplingBounds = Rect()
+ private var regionSampler: RegionSamplingHelper? = null
+
+ private fun convertToClockDarkness(isRegionDark: Boolean): RegionDarkness {
+ return if (isRegionDark) {
+ RegionDarkness.DARK
+ } else {
+ RegionDarkness.LIGHT
+ }
+ }
+
+ fun currentClockDarkness(): RegionDarkness {
+ return isDark
+ }
+
+ /**
+ * Start region sampler
+ */
+ fun startRegionSampler() {
+ regionSampler?.start(samplingBounds)
+ }
+
+ /**
+ * Stop region sampler
+ */
+ fun stopRegionSampler() {
+ regionSampler?.stop()
+ }
+
+ /**
+ * Dump region sampler
+ */
+ fun dump(pw: PrintWriter) {
+ regionSampler?.dump(pw)
+ }
+
+ /**
+ * Restart
+ */
+ fun restart(sampledView: View?) {
+ regionSampler?.onViewAttachedToWindow(sampledView)
+ }
+
+ init {
+ if (regionSamplingEnabled && sampledView != null) {
+ regionSampler = RegionSamplingHelper(sampledView,
+ object : SamplingCallback {
+ override fun onRegionDarknessChanged(isRegionDark: Boolean) {
+ isDark = convertToClockDarkness(isRegionDark)
+ clock?.events?.onColorPaletteChanged(resources, isDark, isDark)
+ }
+
+ override fun getSampledRegion(sampledView: View): Rect {
+ samplingBounds = Rect(sampledView.left, sampledView.top,
+ sampledView.right, sampledView.bottom)
+ return samplingBounds
+ }
+
+ override fun isSamplingEnabled(): Boolean {
+ return regionSamplingEnabled
+ }
+ }, mainExecutor, bgExecutor)
+ }
+ regionSampler?.setWindowVisible(true)
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index c5beaa7ee0b1..916526d0efac 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -130,13 +130,6 @@ public class ActivityManagerWrapper {
}
/**
- * @return a list of the recents tasks.
- */
- public List<RecentTaskInfo> getRecentTasks(int numTasks, int userId) {
- return mAtm.getRecentTasks(numTasks, RECENT_IGNORE_UNAVAILABLE, userId);
- }
-
- /**
* @return a {@link ThumbnailData} with {@link TaskSnapshot} for the given {@param taskId}.
* The snapshot will be triggered if no cached {@link TaskSnapshot} exists.
*/
@@ -247,25 +240,6 @@ public class ActivityManagerWrapper {
}
/**
- * Starts a task from Recents.
- *
- * @param resultCallback The result success callback
- * @param resultCallbackHandler The handler to receive the result callback
- */
- public void startActivityFromRecentsAsync(Task.TaskKey taskKey, ActivityOptions options,
- Consumer<Boolean> resultCallback, Handler resultCallbackHandler) {
- final boolean result = startActivityFromRecents(taskKey, options);
- if (resultCallback != null) {
- resultCallbackHandler.post(new Runnable() {
- @Override
- public void run() {
- resultCallback.accept(result);
- }
- });
- }
- }
-
- /**
* Starts a task from Recents synchronously.
*/
public boolean startActivityFromRecents(Task.TaskKey taskKey, ActivityOptions options) {
@@ -286,20 +260,6 @@ public class ActivityManagerWrapper {
}
/**
- * @deprecated use {@link TaskStackChangeListeners#registerTaskStackListener}
- */
- public void registerTaskStackListener(TaskStackChangeListener listener) {
- TaskStackChangeListeners.getInstance().registerTaskStackListener(listener);
- }
-
- /**
- * @deprecated use {@link TaskStackChangeListeners#unregisterTaskStackListener}
- */
- public void unregisterTaskStackListener(TaskStackChangeListener listener) {
- TaskStackChangeListeners.getInstance().unregisterTaskStackListener(listener);
- }
-
- /**
* Requests that the system close any open system windows (including other SystemUI).
*/
public void closeSystemWindows(final String reason) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
index add2d022e893..be99b270c09a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
@@ -28,14 +28,6 @@ import android.os.Handler;
public abstract class ActivityOptionsCompat {
/**
- * @Deprecated
- * @return ActivityOptions for starting a task in split screen as the primary window.
- */
- public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft) {
- return ActivityOptions.makeBasic();
- }
-
- /**
* @return ActivityOptions for starting a task in freeform.
*/
public static ActivityOptions makeFreeformOptions() {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 630fb360cc14..97e024238778 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -204,28 +204,6 @@ public class QuickStepContract {
}
/**
- * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
- * home button press/long press over are ignored and will start to drag when exceeded and the
- * touch slop is when the respected operation will occur when exceeded. Touch slop must be
- * larger than the drag slop.
- */
- public static int getQuickStepDragSlopPx() {
- return convertDpToPixel(10);
- }
-
- public static int getQuickStepTouchSlopPx() {
- return convertDpToPixel(24);
- }
-
- public static int getQuickScrubTouchSlopPx() {
- return convertDpToPixel(24);
- }
-
- private static int convertDpToPixel(float dp) {
- return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
- }
-
- /**
* Returns whether the specified sysui state is such that the assistant gesture should be
* disabled.
*/
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 a66dc7743792..ff2a7a132288 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
@@ -224,6 +224,7 @@ public class RemoteTransitionCompat implements Parcelable {
private WindowContainerToken mRecentsTask = null;
private TransitionInfo mInfo = null;
private ArrayList<SurfaceControl> mOpeningLeashes = null;
+ private boolean mOpeningHome = false;
private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
private PictureInPictureSurfaceTransaction mPipTransaction = null;
private IBinder mTransition = null;
@@ -321,6 +322,7 @@ public class RemoteTransitionCompat implements Parcelable {
}
final int layer = mInfo.getChanges().size() * 3;
mOpeningLeashes = new ArrayList<>();
+ mOpeningHome = cancelRecents;
final RemoteAnimationTargetCompat[] targets =
new RemoteAnimationTargetCompat[openingTasks.size()];
for (int i = 0; i < openingTasks.size(); ++i) {
@@ -406,6 +408,26 @@ public class RemoteTransitionCompat implements Parcelable {
if (!mKeyguardLocked && mRecentsTask != null) {
wct.restoreTransientOrder(mRecentsTask);
}
+ } else if (toHome && mOpeningHome && mPausingTasks != null) {
+ // Special situaition where 3p launcher was changed during recents (this happens
+ // during tapltests...). Here we get both "return to home" AND "home opening".
+ // This is basically going home, but we have to restore recents order and also
+ // treat the home "pausing" task properly.
+ for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = mInfo.getChange(mPausingTasks.get(i));
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // Treat as opening (see above)
+ wct.reorder(mPausingTasks.get(i), true /* onTop */);
+ t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash());
+ } else {
+ // Treat as hiding (see below)
+ t.hide(mInfo.getChange(mPausingTasks.get(i)).getLeash());
+ }
+ }
+ if (!mKeyguardLocked && mRecentsTask != null) {
+ wct.restoreTransientOrder(mRecentsTask);
+ }
} else {
for (int i = 0; i < mPausingTasks.size(); ++i) {
if (!sendUserLeaveHint) {
@@ -444,6 +466,7 @@ public class RemoteTransitionCompat implements Parcelable {
mPausingTasks = null;
mInfo = null;
mOpeningLeashes = null;
+ mOpeningHome = false;
mLeashMap = null;
mTransition = null;
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
deleted file mode 100644
index 359d36939b31..000000000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.system;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.SurfaceView;
-
-/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */
-public final class UniversalSmartspaceUtils {
- public static final String ACTION_REQUEST_SMARTSPACE_VIEW =
- "com.android.systemui.REQUEST_SMARTSPACE_VIEW";
- public static final String INTENT_BUNDLE_KEY = "bundle_key";
-
- private static final String SYSUI_PACKAGE = "com.android.systemui";
-
- /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */
- public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) {
- Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);
-
- Bundle bundle = SurfaceViewRequestUtils.createSurfaceBundle(surfaceView);
- return intent
- .putExtra(INTENT_BUNDLE_KEY, bundle)
- .setPackage(SYSUI_PACKAGE)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
- | Intent.FLAG_RECEIVER_FOREGROUND);
- }
-
- private UniversalSmartspaceUtils() {}
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index b894b10ff073..5577513f4c3c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -114,30 +114,6 @@ public class WindowManagerWrapper {
}
/**
- * Sets if app requested fixed orientation should be ignored for given displayId.
- */
- public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
- try {
- WindowManagerGlobal.getWindowManagerService().setIgnoreOrientationRequest(
- displayId, ignoreOrientationRequest);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to setIgnoreOrientationRequest()", e);
- }
- }
-
- /**
- * @return the stable insets for the primary display.
- */
- public void getStableInsets(Rect outStableInsets) {
- try {
- WindowManagerGlobal.getWindowManagerService().getStableInsets(DEFAULT_DISPLAY,
- outStableInsets);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to get stable insets", e);
- }
- }
-
- /**
* Overrides a pending app transition.
*/
public void overridePendingAppTransitionMultiThumbFuture(
@@ -153,16 +129,6 @@ public class WindowManagerWrapper {
}
}
- public void overridePendingAppTransitionRemote(
- RemoteAnimationAdapterCompat remoteAnimationAdapter, int displayId) {
- try {
- WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionRemote(
- remoteAnimationAdapter.getWrapped(), displayId);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to override pending app transition (remote): ", e);
- }
- }
-
/**
* Enable or disable haptic feedback on the navigation bar buttons.
*/
@@ -175,19 +141,6 @@ public class WindowManagerWrapper {
}
}
- public void setRecentsVisibility(boolean visible) {
- try {
- WindowManagerGlobal.getWindowManagerService().setRecentsVisibility(visible);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to set recents visibility");
- }
- }
-
- @Deprecated
- public void setPipVisibility(final boolean visible) {
- // To be removed
- }
-
/**
* @param displayId the id of display to check if there is a software navigation bar.
*
@@ -202,22 +155,6 @@ public class WindowManagerWrapper {
}
/**
- * @return The side of the screen where navigation bar is positioned.
- * @see #NAV_BAR_POS_RIGHT
- * @see #NAV_BAR_POS_LEFT
- * @see #NAV_BAR_POS_BOTTOM
- * @see #NAV_BAR_POS_INVALID
- */
- public int getNavBarPosition(int displayId) {
- try {
- return WindowManagerGlobal.getWindowManagerService().getNavBarPosition(displayId);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to get nav bar position");
- }
- return NAV_BAR_POS_INVALID;
- }
-
- /**
* Mirrors a specified display. The SurfaceControl returned is the root of the mirrored
* hierarchy.
*
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 1e62b9c3abb3..bc1c10af5065 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -20,17 +20,14 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Resources
-import android.graphics.Rect
import android.text.format.DateFormat
-import android.view.View
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.plugins.Clock
-import com.android.systemui.plugins.ClockDarkness
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper
+import com.android.systemui.shared.regionsampling.RegionSamplingInstance
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -61,6 +58,7 @@ class ClockEventController @Inject constructor(
field = value
if (value != null) {
value.initialize(resources, dozeAmount, 0f)
+ updateRegionSamplers(value)
}
}
@@ -71,94 +69,68 @@ class ClockEventController @Inject constructor(
private var dozeAmount = 0f
private var isKeyguardShowing = false
- private var smallClockIsDark = ClockDarkness.DEFAULT
- private var largeClockIsDark = ClockDarkness.DEFAULT
- private var smallSamplingBounds = Rect()
- private var largeSamplingBounds = Rect()
-
private val regionSamplingEnabled =
featureFlags.isEnabled(com.android.systemui.flags.Flags.REGION_SAMPLING)
- private fun setClockDarkness(isRegionDark: Boolean): ClockDarkness {
- return if (isRegionDark) {
- ClockDarkness.DARK
- } else {
- ClockDarkness.LIGHT
- }
- }
+ private fun updateColors(currentClock: Clock?) {
+ smallClockIsDark = smallRegionSamplingInstance.currentClockDarkness()
+ largeClockIsDark = largeRegionSamplingInstance.currentClockDarkness()
- // TODO: Abstract out the creation of RegionSampler and its fields
- var smallRegionSampling: RegionSamplingHelper? =
- if (!regionSamplingEnabled || clock == null) {
- null
- } else {
- RegionSamplingHelper(clock?.smallClock,
- object : RegionSamplingHelper.SamplingCallback {
- override fun onRegionDarknessChanged(isRegionDark: Boolean) {
- smallClockIsDark = setClockDarkness(isRegionDark)
- clock?.events?.onColorPaletteChanged(
- resources,
- smallClockIsDark,
- largeClockIsDark
- )
- }
+ currentClock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
+ }
- override fun getSampledRegion(sampledView: View): Rect {
- smallSamplingBounds = Rect(
- sampledView.left,
- sampledView.top,
- sampledView.right,
- sampledView.bottom
- )
- return smallSamplingBounds
- }
+ fun updateRegionSamplers(currentClock: Clock?) {
+ smallRegionSamplingInstance.stopRegionSampler()
+ largeRegionSamplingInstance.stopRegionSampler()
+
+ smallRegionSamplingInstance = RegionSamplingInstance(
+ currentClock?.smallClock,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ currentClock,
+ resources
+ )
- override fun isSamplingEnabled(): Boolean {
- return regionSamplingEnabled
- }
- },
- mainExecutor, bgExecutor)
- }
+ largeRegionSamplingInstance = RegionSamplingInstance(
+ currentClock?.largeClock,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ currentClock,
+ resources
+ )
- var largeRegionSampling: RegionSamplingHelper? =
- if (!regionSamplingEnabled || clock == null) {
- null
- } else {
- RegionSamplingHelper(clock?.largeClock,
- object : RegionSamplingHelper.SamplingCallback {
- override fun onRegionDarknessChanged(isRegionDark: Boolean) {
- largeClockIsDark = setClockDarkness(isRegionDark)
- clock?.events?.onColorPaletteChanged(
- resources,
- smallClockIsDark,
- largeClockIsDark
- )
- }
+ smallRegionSamplingInstance.startRegionSampler()
+ largeRegionSamplingInstance.startRegionSampler()
- override fun getSampledRegion(sampledView: View): Rect {
- largeSamplingBounds = Rect(
- sampledView.left,
- sampledView.top,
- sampledView.right,
- sampledView.bottom
- )
- return largeSamplingBounds
- }
+ updateColors(currentClock)
+ }
- override fun isSamplingEnabled(): Boolean {
- return regionSamplingEnabled
- }
- },
- mainExecutor, bgExecutor)
- }
+ var smallRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance(
+ clock?.smallClock,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ clock,
+ resources
+ )
+
+ var largeRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance(
+ clock?.largeClock,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ clock,
+ resources
+ )
+
+ private var smallClockIsDark = smallRegionSamplingInstance.currentClockDarkness()
+ private var largeClockIsDark = largeRegionSamplingInstance.currentClockDarkness()
private val configListener = object : ConfigurationController.ConfigurationListener {
override fun onThemeChanged() {
- clock?.events?.onColorPaletteChanged(
- resources,
- smallClockIsDark,
- largeClockIsDark
- )
+ updateColors(clock)
}
}
@@ -209,8 +181,6 @@ class ClockEventController @Inject constructor(
init {
isDozing = statusBarStateController.isDozing
- smallRegionSampling?.setWindowVisible(true)
- largeRegionSampling?.setWindowVisible(true)
clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark)
}
@@ -226,8 +196,8 @@ class ClockEventController @Inject constructor(
batteryController.addCallback(batteryCallback)
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
statusBarStateController.addCallback(statusBarStateListener)
- smallRegionSampling?.start(smallSamplingBounds)
- largeRegionSampling?.start(largeSamplingBounds)
+ smallRegionSamplingInstance.startRegionSampler()
+ largeRegionSamplingInstance.startRegionSampler()
}
fun unregisterListeners() {
@@ -236,8 +206,8 @@ class ClockEventController @Inject constructor(
batteryController.removeCallback(batteryCallback)
keyguardUpdateMonitor.removeCallback(keyguardUpdateMonitorCallback)
statusBarStateController.removeCallback(statusBarStateListener)
- smallRegionSampling?.stop()
- largeRegionSampling?.stop()
+ smallRegionSamplingInstance.stopRegionSampler()
+ largeRegionSamplingInstance.stopRegionSampler()
}
/**
@@ -246,8 +216,8 @@ class ClockEventController @Inject constructor(
fun dump(pw: PrintWriter) {
pw.println(this)
clock?.dump(pw)
- smallRegionSampling?.dump(pw)
- largeRegionSampling?.dump(pw)
+ smallRegionSamplingInstance.dump(pw)
+ largeRegionSamplingInstance.dump(pw)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 12fa401d7fea..d32219a9817f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -336,6 +336,11 @@ public class KeyguardHostViewController extends ViewController<KeyguardHostView>
mKeyguardSecurityContainerController.onStartingToHide();
}
+ /** Called when bouncer visibility changes. */
+ public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility);
+ }
+
public boolean hasDismissActions() {
return mDismissAction != null || mCancelAction != null;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
index db2b4ac2c669..58e0fb968204 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
@@ -58,7 +58,6 @@ data class KeyguardFaceListenModel(
val keyguardAwake: Boolean,
val keyguardGoingAway: Boolean,
val listeningForFaceAssistant: Boolean,
- val lockIconPressed: Boolean,
val occludingAppRequestingFaceAuth: Boolean,
val primaryUser: Boolean,
val scanningAllowedByStrongAuth: Boolean,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 61e262440607..5ee659be6dd2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC;
import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS;
@@ -32,11 +33,13 @@ import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
+import android.hardware.biometrics.BiometricSourceType;
import android.metrics.LogMaker;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.view.MotionEvent;
+import android.view.View;
import androidx.annotation.Nullable;
@@ -55,6 +58,7 @@ import com.android.keyguard.dagger.KeyguardBouncerScope;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
+import com.android.systemui.biometrics.SidefpsController;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -67,6 +71,8 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.settings.GlobalSettings;
+import java.util.Optional;
+
import javax.inject.Inject;
/** Controller for {@link KeyguardSecurityContainer} */
@@ -93,6 +99,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
private final GlobalSettings mGlobalSettings;
private final FeatureFlags mFeatureFlags;
private final SessionTracker mSessionTracker;
+ private final Optional<SidefpsController> mSidefpsController;
private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
@@ -236,13 +243,27 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
reloadColors();
}
};
+ private boolean mBouncerVisible = false;
private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
- @Override
- public void onDevicePolicyManagerStateChanged() {
- showPrimarySecurityScreen(false);
- }
- };
+ @Override
+ public void onDevicePolicyManagerStateChanged() {
+ showPrimarySecurityScreen(false);
+ }
+
+ @Override
+ public void onBiometricRunningStateChanged(boolean running,
+ BiometricSourceType biometricSourceType) {
+ if (biometricSourceType == FINGERPRINT) {
+ updateSideFpsVisibility();
+ }
+ }
+
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ updateSideFpsVisibility();
+ }
+ };
private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
@@ -260,7 +281,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
UserSwitcherController userSwitcherController,
FeatureFlags featureFlags,
GlobalSettings globalSettings,
- SessionTracker sessionTracker) {
+ SessionTracker sessionTracker,
+ Optional<SidefpsController> sidefpsController) {
super(view);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = keyguardUpdateMonitor;
@@ -280,6 +302,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mFeatureFlags = featureFlags;
mGlobalSettings = globalSettings;
mSessionTracker = sessionTracker;
+ mSidefpsController = sidefpsController;
}
@Override
@@ -311,8 +334,23 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
getCurrentSecurityController().onPause();
}
mView.onPause();
+ // It might happen that onStartingToHide is not called when the device is locked while on
+ // bouncer.
+ setBouncerVisible(false);
}
+ private void updateSideFpsVisibility() {
+ if (!mSidefpsController.isPresent()) {
+ return;
+ }
+ if (mBouncerVisible && mView.isSidedSecurityMode()
+ && mUpdateMonitor.isFingerprintDetectionRunning()
+ && !mUpdateMonitor.userNeedsStrongAuth()) {
+ mSidefpsController.get().show();
+ } else {
+ mSidefpsController.get().hide();
+ }
+ }
/**
* Shows the primary security screen for the user. This will be either the multi-selector
@@ -397,6 +435,17 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
if (mCurrentSecurityMode != SecurityMode.None) {
getCurrentSecurityController().onStartingToHide();
}
+ setBouncerVisible(false);
+ }
+
+ /** Called when the bouncer changes visibility. */
+ public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
+ setBouncerVisible(visibility == View.VISIBLE);
+ }
+
+ private void setBouncerVisible(boolean visible) {
+ mBouncerVisible = visible;
+ updateSideFpsVisibility();
}
/**
@@ -655,6 +704,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
private final FeatureFlags mFeatureFlags;
private final UserSwitcherController mUserSwitcherController;
private final SessionTracker mSessionTracker;
+ private final Optional<SidefpsController> mSidefpsController;
@Inject
Factory(KeyguardSecurityContainer view,
@@ -673,7 +723,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
UserSwitcherController userSwitcherController,
FeatureFlags featureFlags,
GlobalSettings globalSettings,
- SessionTracker sessionTracker) {
+ SessionTracker sessionTracker,
+ Optional<SidefpsController> sidefpsController) {
mView = view;
mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
mLockPatternUtils = lockPatternUtils;
@@ -690,6 +741,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mGlobalSettings = globalSettings;
mUserSwitcherController = userSwitcherController;
mSessionTracker = sessionTracker;
+ mSidefpsController = sidefpsController;
}
public KeyguardSecurityContainerController create(
@@ -699,7 +751,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
mConfigurationController, mFalsingCollector, mFalsingManager,
- mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker);
+ mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker,
+ mSidefpsController);
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index de5de32168e7..9693886cf456 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -41,7 +41,6 @@ import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AlarmManager;
-import android.app.PendingIntent;
import android.app.UserSwitchObserver;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
@@ -149,11 +148,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private static final boolean DEBUG_SPEW = false;
private static final int BIOMETRIC_LOCKOUT_RESET_DELAY_MS = 600;
- private static final String ACTION_FACE_UNLOCK_STARTED
- = "com.android.facelock.FACE_UNLOCK_STARTED";
- private static final String ACTION_FACE_UNLOCK_STOPPED
- = "com.android.facelock.FACE_UNLOCK_STOPPED";
-
// Callback messages
private static final int MSG_TIME_UPDATE = 301;
private static final int MSG_BATTERY_UPDATE = 302;
@@ -164,13 +158,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private static final int MSG_USER_SWITCHING = 310;
private static final int MSG_KEYGUARD_RESET = 312;
private static final int MSG_USER_SWITCH_COMPLETE = 314;
- private static final int MSG_USER_INFO_CHANGED = 317;
private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
private static final int MSG_STARTED_WAKING_UP = 319;
private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
- private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
private static final int MSG_SERVICE_STATE_CHANGE = 330;
@@ -234,7 +226,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final Context mContext;
private final boolean mIsPrimaryUser;
- private final boolean mIsAutomotive;
private final AuthController mAuthController;
private final StatusBarStateController mStatusBarStateController;
private int mStatusBarState;
@@ -312,8 +303,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private final LatencyTracker mLatencyTracker;
private boolean mLogoutEnabled;
private boolean mIsFaceEnrolled;
- // If the user long pressed the lock icon, disabling face auth for the current session.
- private boolean mLockIconPressed;
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private final Executor mBackgroundExecutor;
private SensorPrivacyManager mSensorPrivacyManager;
@@ -392,7 +381,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray();
- private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
private Map<Integer, Intent> mSecondaryLockscreenRequirement = new HashMap<Integer, Intent>();
@VisibleForTesting
@@ -1119,21 +1107,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- private void handleFaceUnlockStateChanged(boolean running, int userId) {
- Assert.isMainThread();
- mUserFaceUnlockRunning.put(userId, running);
- for (int i = 0; i < mCallbacks.size(); i++) {
- KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onFaceUnlockStateChanged(running, userId);
- }
- }
- }
-
- public boolean isFaceUnlockRunning(int userId) {
- return mUserFaceUnlockRunning.get(userId);
- }
-
public boolean isFingerprintDetectionRunning() {
return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
}
@@ -1357,16 +1330,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- static class DisplayClientState {
- public int clientGeneration;
- public boolean clearing;
- public PendingIntent intent;
- public int playbackState;
- public long playbackEventTime;
- }
-
- private DisplayClientState mDisplayClientState = new DisplayClientState();
-
@VisibleForTesting
protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -1440,19 +1403,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
final String action = intent.getAction();
if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
- } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
- intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
- } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
- Trace.beginSection(
- "KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive "
- + "ACTION_FACE_UNLOCK_STARTED");
- mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
- getSendingUserId()));
- Trace.endSection();
- } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
- getSendingUserId()));
} else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED,
@@ -1751,7 +1701,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
protected void handleStartedGoingToSleep(int arg1) {
Assert.isMainThread();
- mLockIconPressed = false;
clearBiometricRecognized();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1799,16 +1748,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- private void handleUserInfoChanged(int userId) {
- Assert.isMainThread();
- for (int i = 0; i < mCallbacks.size(); i++) {
- KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onUserInfoChanged(userId);
- }
- }
- }
-
private void handleUserUnlocked(int userId) {
Assert.isMainThread();
mUserIsUnlocked.put(userId, true);
@@ -1926,9 +1865,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
case MSG_KEYGUARD_BOUNCER_CHANGED:
handleKeyguardBouncerChanged(msg.arg1, msg.arg2);
break;
- case MSG_USER_INFO_CHANGED:
- handleUserInfoChanged(msg.arg1);
- break;
case MSG_REPORT_EMERGENCY_CALL_ACTION:
handleReportEmergencyCallAction();
break;
@@ -1943,12 +1879,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
handleStartedWakingUp();
Trace.endSection();
break;
- case MSG_FACE_UNLOCK_STATE_CHANGED:
- Trace.beginSection(
- "KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
- handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
- Trace.endSection();
- break;
case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
handleSimSubscriptionInfoChanged();
break;
@@ -2036,24 +1966,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
.getServiceStateForSubscriber(subId);
mHandler.sendMessage(
mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
-
- // Get initial state. Relying on Sticky behavior until API for getting info.
- if (mBatteryStatus == null) {
- Intent intent = mContext.registerReceiver(
- null,
- new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
- );
- if (intent != null && mBatteryStatus == null) {
- mBroadcastReceiver.onReceive(mContext, intent);
- }
- }
});
final IntentFilter allUserFilter = new IntentFilter();
- allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
- allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
- allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
allUserFilter.addAction(ACTION_USER_UNLOCKED);
allUserFilter.addAction(ACTION_USER_STOPPED);
@@ -2111,8 +2027,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
}
- mIsAutomotive = isAutomotive();
-
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
mUserManager = context.getSystemService(UserManager.class);
mIsPrimaryUser = mUserManager.isPrimaryUser();
@@ -2613,7 +2527,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|| mAuthController.isUdfpsFingerDown()
|| mUdfpsBouncerShowing)
&& !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer
- && !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed
+ && !mKeyguardGoingAway && biometricEnabledForUser
&& strongAuthAllowsScanning && mIsPrimaryUser
&& (!mSecureCameraLaunched || mOccludingAppRequestingFace)
&& !faceAuthenticated
@@ -2636,7 +2550,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
awakeKeyguard,
mKeyguardGoingAway,
shouldListenForFaceAssistant,
- mLockIconPressed,
mOccludingAppRequestingFace,
mIsPrimaryUser,
strongAuthAllowsScanning,
@@ -2681,18 +2594,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- /**
- * Whenever the lock icon is long pressed, disabling trust agents.
- * This means that we cannot auth passively (face) until the user presses power.
- */
- public void onLockIconPressed() {
- mLockIconPressed = true;
- final int userId = getCurrentUser();
- mUserFaceAuthenticated.put(userId, null);
- updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
- mStrongAuthTracker.onStrongAuthRequiredChanged(userId);
- }
-
private void startListeningForFingerprint() {
final int userId = getCurrentUser();
final boolean unlockPossible = isUnlockWithFingerprintPossible(userId);
@@ -3163,20 +3064,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
}
- /** Notifies that the occluded state changed. */
- public void onKeyguardOccludedChanged(boolean occluded) {
- Assert.isMainThread();
- if (DEBUG) {
- Log.d(TAG, "onKeyguardOccludedChanged(" + occluded + ")");
- }
- for (int i = 0; i < mCallbacks.size(); i++) {
- KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onKeyguardOccludedChanged(occluded);
- }
- }
- }
-
/**
* Handle {@link #MSG_KEYGUARD_RESET}
*/
@@ -3331,10 +3218,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
return false;
}
- private boolean isAutomotive() {
- return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
- }
-
/**
* Remove the given observer's callback.
*
@@ -3397,8 +3280,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
callback.onTimeChanged();
callback.onPhoneStateChanged(mPhoneState);
callback.onRefreshCarrierInfo();
- callback.onClockVisibilityChanged();
- callback.onKeyguardOccludedChanged(mKeyguardOccluded);
callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
callback.onTelephonyCapable(mTelephonyCapable);
@@ -3575,10 +3456,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|| state == TelephonyManager.SIM_STATE_PERM_DISABLED);
}
- public DisplayClientState getCachedDisplayClientState() {
- return mDisplayClientState;
- }
-
// TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
// (KeyguardViewMediator, KeyguardHostView)
public void dispatchStartedWakingUp() {
@@ -3807,9 +3684,5 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
pw.println(" mNeedsSlowUnlockTransition=" + mNeedsSlowUnlockTransition);
}
mListenModels.print(pw);
-
- if (mIsAutomotive) {
- pw.println(" Running on Automotive build");
- }
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 051b81e484d8..99e0ce29a8c2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -80,12 +80,6 @@ public class KeyguardUpdateMonitorCallback {
*/
public void onKeyguardVisibilityChanged(boolean showing) { }
- /**
- * Called when the keyguard occluded state changes.
- * @param occluded Indicates if the keyguard is now occluded.
- */
- public void onKeyguardOccludedChanged(boolean occluded) { }
-
public void onKeyguardVisibilityChangedRaw(boolean showing) {
final long now = SystemClock.elapsedRealtime();
if (showing == mShowing
@@ -117,12 +111,6 @@ public class KeyguardUpdateMonitorCallback {
public void onKeyguardDismissAnimationFinished() { }
/**
- * Called when visibility of lockscreen clock changes, such as when
- * obscured by a widget.
- */
- public void onClockVisibilityChanged() { }
-
- /**
* Called when the device becomes provisioned
*/
public void onDeviceProvisioned() { }
@@ -151,11 +139,6 @@ public class KeyguardUpdateMonitorCallback {
public void onSimStateChanged(int subId, int slotId, int simState) { }
/**
- * Called when the user's info changed.
- */
- public void onUserInfoChanged(int userId) { }
-
- /**
* Called when a user got unlocked.
*/
public void onUserUnlocked() { }
@@ -260,11 +243,6 @@ public class KeyguardUpdateMonitorCallback {
BiometricSourceType biometricSourceType) { }
/**
- * Called when the state of face unlock changed.
- */
- public void onFaceUnlockStateChanged(boolean running, int userId) { }
-
- /**
* Called when biometric running state changed.
*/
public void onBiometricRunningStateChanged(boolean running,
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 43e737823692..06e1828ef9f4 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -650,7 +650,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
Process.myUid(),
getContext().getOpPackageName(),
UdfpsController.EFFECT_CLICK,
- "lock-icon-device-entry",
+ "lock-screen-lock-icon-longpress",
TOUCH_VIBRATION_ATTRIBUTES);
mKeyguardViewController.showBouncer(/* scrim */ true);
@@ -675,6 +675,12 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
private boolean isActionable() {
+ if (mIsBouncerShowing) {
+ Log.v(TAG, "lock icon long-press ignored, bouncer already showing.");
+ // a long press gestures from AOD may have already triggered the bouncer to show,
+ // so this touch is no longer actionable
+ return false;
+ }
return mUdfpsSupported || mShowUnlockIcon;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
index b3c11584bcf8..49e97836b18b 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -16,6 +16,10 @@
package com.android.keyguard.dagger;
+import static com.android.systemui.biometrics.SidefpsControllerKt.hasSideFpsSensor;
+
+import android.annotation.Nullable;
+import android.hardware.fingerprint.FingerprintManager;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -23,9 +27,14 @@ import com.android.keyguard.KeyguardHostView;
import com.android.keyguard.KeyguardSecurityContainer;
import com.android.keyguard.KeyguardSecurityViewFlipper;
import com.android.systemui.R;
+import com.android.systemui.biometrics.SidefpsController;
import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import java.util.Optional;
+
+import javax.inject.Provider;
+
import dagger.Module;
import dagger.Provides;
@@ -60,4 +69,16 @@ public interface KeyguardBouncerModule {
KeyguardSecurityContainer containerView) {
return containerView.findViewById(R.id.view_flipper);
}
+
+ /** Provides {@link SidefpsController} if the device has the side fingerprint sensor. */
+ @Provides
+ @KeyguardBouncerScope
+ static Optional<SidefpsController> providesOptionalSidefpsController(
+ @Nullable FingerprintManager fingerprintManager,
+ Provider<SidefpsController> sidefpsControllerProvider) {
+ if (!hasSideFpsSensor(fingerprintManager)) {
+ return Optional.empty();
+ }
+ return Optional.of(sidefpsControllerProvider.get());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
index b2d5c216dcd1..74d7a8b03b7d 100644
--- a/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
+++ b/packages/SystemUI/src/com/android/systemui/Gefingerpoken.java
@@ -20,6 +20,13 @@ import android.view.MotionEvent;
// ACHTUNG!
public interface Gefingerpoken {
- boolean onInterceptTouchEvent(MotionEvent ev);
- boolean onTouchEvent(MotionEvent ev);
+ /** Called when a touch is being intercepted in a ViewGroup. */
+ default boolean onInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ /** Called when a touch is being handled by a view. */
+ default boolean onTouchEvent(MotionEvent ev) {
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index aaaa3f77924a..4c400a81024f 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -839,7 +839,8 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS
| WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
index 714d267bb07d..527ce127820e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -16,160 +16,22 @@
package com.android.systemui;
-import android.app.Activity;
-import android.app.Application;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.ContentProvider;
import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.AppComponentFactory;
-
-import com.android.systemui.dagger.ContextComponentHelper;
-import com.android.systemui.dagger.SysUIComponent;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.inject.Inject;
/**
- * Implementation of AppComponentFactory that injects into constructors.
+ * Starts up SystemUI using the AOSP {@link SystemUIInitializerImpl}.
*
- * This class sets up dependency injection when creating our application.
+ * This initializer relies on reflection to start everything up and should be considered deprecated.
+ * Instead, create your own {@link SystemUIAppComponentFactoryBase}, specify it in your
+ * AndroidManifest.xml and construct your own {@link SystemUIInitializer} directly.
*
- * Services support dependency injection into their constructors.
- *
- * ContentProviders support injection into member variables - _not_ constructors.
+ * @deprecated Define your own SystemUIAppComponentFactoryBase implementation and use that. This
+ * implementation may be changed or removed in future releases.
*/
-public class SystemUIAppComponentFactory extends AppComponentFactory {
-
- private static final String TAG = "AppComponentFactory";
- @Inject
- public ContextComponentHelper mComponentHelper;
-
- public SystemUIAppComponentFactory() {
- super();
- }
-
- @NonNull
+@Deprecated
+public class SystemUIAppComponentFactory extends SystemUIAppComponentFactoryBase {
@Override
- public Application instantiateApplicationCompat(
- @NonNull ClassLoader cl, @NonNull String className)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- Application app = super.instantiateApplicationCompat(cl, className);
- if (app instanceof ContextInitializer) {
- ((ContextInitializer) app).setContextAvailableCallback(
- context -> {
- SystemUIFactory.createFromConfig(context);
- SystemUIFactory.getInstance().getSysUIComponent().inject(
- SystemUIAppComponentFactory.this);
- }
- );
- }
-
- return app;
- }
-
- @NonNull
- @Override
- public ContentProvider instantiateProviderCompat(
- @NonNull ClassLoader cl, @NonNull String className)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-
- ContentProvider contentProvider = super.instantiateProviderCompat(cl, className);
- if (contentProvider instanceof ContextInitializer) {
- ((ContextInitializer) contentProvider).setContextAvailableCallback(
- context -> {
- SystemUIFactory.createFromConfig(context);
- SysUIComponent rootComponent =
- SystemUIFactory.getInstance().getSysUIComponent();
- try {
- Method injectMethod = rootComponent.getClass()
- .getMethod("inject", contentProvider.getClass());
- injectMethod.invoke(rootComponent, contentProvider);
- } catch (NoSuchMethodException
- | IllegalAccessException
- | InvocationTargetException e) {
- Log.w(TAG, "No injector for class: " + contentProvider.getClass(), e);
- }
- }
- );
- }
-
- return contentProvider;
- }
-
- @NonNull
- @Override
- public Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className,
- @Nullable Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- if (mComponentHelper == null) {
- // This shouldn't happen, but is seen on occasion.
- // Bug filed against framework to take a look: http://b/141008541
- SystemUIFactory.getInstance().getSysUIComponent().inject(
- SystemUIAppComponentFactory.this);
- }
- Activity activity = mComponentHelper.resolveActivity(className);
- if (activity != null) {
- return activity;
- }
- return super.instantiateActivityCompat(cl, className, intent);
- }
-
- @NonNull
- @Override
- public Service instantiateServiceCompat(
- @NonNull ClassLoader cl, @NonNull String className, Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- if (mComponentHelper == null) {
- // This shouldn't happen, but does when a device is freshly formatted.
- // Bug filed against framework to take a look: http://b/141008541
- SystemUIFactory.getInstance().getSysUIComponent().inject(
- SystemUIAppComponentFactory.this);
- }
- Service service = mComponentHelper.resolveService(className);
- if (service != null) {
- return service;
- }
- return super.instantiateServiceCompat(cl, className, intent);
- }
-
- @NonNull
- @Override
- public BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl,
- @NonNull String className, @Nullable Intent intent)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- if (mComponentHelper == null) {
- // This shouldn't happen, but does when a device is freshly formatted.
- // Bug filed against framework to take a look: http://b/141008541
- SystemUIFactory.getInstance().getSysUIComponent().inject(
- SystemUIAppComponentFactory.this);
- }
- BroadcastReceiver receiver = mComponentHelper.resolveBroadcastReceiver(className);
- if (receiver != null) {
- return receiver;
- }
-
- return super.instantiateReceiverCompat(cl, className, intent);
- }
-
- /**
- * A callback that receives a Context when one is ready.
- */
- public interface ContextAvailableCallback {
- void onContextAvailable(Context context);
- }
-
- /**
- * Implemented in classes that get started by the system before a context is available.
- */
- public interface ContextInitializer {
- void setContextAvailableCallback(ContextAvailableCallback callback);
+ protected SystemUIInitializer createSystemUIInitializer(Context context) {
+ return SystemUIInitializerFactory.createWithContext(context);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
new file mode 100644
index 000000000000..12108b01ab28
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui
+
+import android.app.Activity
+import android.app.Application
+import android.app.Service
+import android.content.BroadcastReceiver
+import android.content.ContentProvider
+import android.content.Context
+import android.content.Intent
+import android.util.Log
+import androidx.core.app.AppComponentFactory
+import com.android.systemui.dagger.ContextComponentHelper
+import java.lang.reflect.InvocationTargetException
+import java.util.concurrent.ExecutionException
+import javax.inject.Inject
+
+/**
+ * Implementation of AppComponentFactory that injects into constructors.
+ *
+ * This class sets up dependency injection when creating our application.
+ *
+ * Activities, Services, and BroadcastReceivers support dependency injection into
+ * their constructors.
+ *
+ * ContentProviders support injection into member variables - _not_ constructors.
+ */
+abstract class SystemUIAppComponentFactoryBase : AppComponentFactory() {
+ companion object {
+ private const val TAG = "AppComponentFactory"
+ // Must be static due to http://b/141008541.
+ var systemUIInitializer: SystemUIInitializer? = null
+ }
+
+ @set:Inject
+ lateinit var componentHelper: ContextComponentHelper
+
+ /**
+ * Returns a new [SystemUIInitializer].
+ *
+ * The returned implementation should be specific to your build.
+ */
+ protected abstract fun createSystemUIInitializer(context: Context): SystemUIInitializer
+
+ private fun createSystemUIInitializerInternal(context: Context): SystemUIInitializer {
+ return systemUIInitializer ?: run {
+ val initializer = createSystemUIInitializer(context.applicationContext)
+ try {
+ initializer.init(false)
+ } catch (exception: ExecutionException) {
+ throw RuntimeException("Failed to initialize SysUI", exception)
+ } catch (exception: InterruptedException) {
+ throw RuntimeException("Failed to initialize SysUI", exception)
+ }
+ initializer.sysUIComponent.inject(
+ this@SystemUIAppComponentFactoryBase
+ )
+
+ systemUIInitializer = initializer
+ return initializer
+ }
+ }
+
+ override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application {
+ val app = super.instantiateApplicationCompat(cl, className)
+ if (app !is ContextInitializer) {
+ throw RuntimeException("App must implement ContextInitializer")
+ } else {
+ app.setContextAvailableCallback { context ->
+ createSystemUIInitializerInternal(context)
+ }
+ }
+
+ return app
+ }
+
+ override fun instantiateProviderCompat(cl: ClassLoader, className: String): ContentProvider {
+ val contentProvider = super.instantiateProviderCompat(cl, className)
+ if (contentProvider is ContextInitializer) {
+ contentProvider.setContextAvailableCallback { context ->
+ val initializer = createSystemUIInitializerInternal(context)
+ val rootComponent = initializer.sysUIComponent
+ try {
+ val injectMethod = rootComponent.javaClass
+ .getMethod("inject", contentProvider.javaClass)
+ injectMethod.invoke(rootComponent, contentProvider)
+ } catch (e: NoSuchMethodException) {
+ Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
+ } catch (e: IllegalAccessException) {
+ Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
+ } catch (e: InvocationTargetException) {
+ Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
+ }
+ initializer
+ }
+ }
+ return contentProvider
+ }
+
+ override fun instantiateActivityCompat(
+ cl: ClassLoader,
+ className: String,
+ intent: Intent?
+ ): Activity {
+ if (!this::componentHelper.isInitialized) {
+ // This shouldn't happen, but is seen on occasion.
+ // Bug filed against framework to take a look: http://b/141008541
+ systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
+ }
+ return componentHelper.resolveActivity(className)
+ ?: super.instantiateActivityCompat(cl, className, intent)
+ }
+
+ override fun instantiateServiceCompat(
+ cl: ClassLoader,
+ className: String,
+ intent: Intent?
+ ): Service {
+ if (!this::componentHelper.isInitialized) {
+ // This shouldn't happen, but does when a device is freshly formatted.
+ // Bug filed against framework to take a look: http://b/141008541
+ systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
+ }
+ return componentHelper.resolveService(className)
+ ?: super.instantiateServiceCompat(cl, className, intent)
+ }
+
+ override fun instantiateReceiverCompat(
+ cl: ClassLoader,
+ className: String,
+ intent: Intent?
+ ): BroadcastReceiver {
+ if (!this::componentHelper.isInitialized) {
+ // This shouldn't happen, but does when a device is freshly formatted.
+ // Bug filed against framework to take a look: http://b/141008541
+ systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
+ }
+ return componentHelper.resolveBroadcastReceiver(className)
+ ?: super.instantiateReceiverCompat(cl, className, intent)
+ }
+
+ /**
+ * An Interface for classes that can be notified when an Application Context becomes available.
+ *
+ * An instance of this will be passed to implementers of [ContextInitializer].
+ */
+ fun interface ContextAvailableCallback {
+ /** Notifies when the Application Context is available. */
+ fun onContextAvailable(context: Context): SystemUIInitializer
+ }
+
+ /**
+ * Interface for classes that can be constructed by the system before a context is available.
+ *
+ * This is intended for [Application] and [ContentProvider] implementations that
+ * either may not have a Context until some point after construction or are themselves
+ * a [Context].
+ *
+ * Implementers will be passed a [ContextAvailableCallback] that they should call as soon
+ * as an Application Context is ready.
+ */
+ interface ContextInitializer {
+ /**
+ * Called to supply the [ContextAvailableCallback] that should be called when an
+ * Application [Context] is available.
+ */
+ fun setContextAvailableCallback(callback: ContextAvailableCallback)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 6d3fd503dff6..9138b2346ab8 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -42,7 +42,6 @@ import android.view.SurfaceControl;
import android.view.ThreadedRenderer;
import com.android.internal.protolog.common.ProtoLog;
-import com.android.systemui.dagger.ContextComponentHelper;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dump.DumpManager;
@@ -65,7 +64,6 @@ public class SystemUIApplication extends Application implements
public static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
- private ContextComponentHelper mComponentHelper;
private BootCompleteCacheImpl mBootCompleteCache;
private DumpManager mDumpManager;
@@ -80,8 +78,8 @@ public class SystemUIApplication extends Application implements
private CoreStartable[] mServices;
private boolean mServicesStarted;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
- private GlobalRootComponent mRootComponent;
private SysUIComponent mSysUIComponent;
+ private SystemUIInitializer mInitializer;
public SystemUIApplication() {
super();
@@ -90,6 +88,10 @@ public class SystemUIApplication extends Application implements
ProtoLog.REQUIRE_PROTOLOGTOOL = false;
}
+ protected GlobalRootComponent getRootComponent() {
+ return mInitializer.getRootComponent();
+ }
+
@Override
public void onCreate() {
super.onCreate();
@@ -99,10 +101,8 @@ public class SystemUIApplication extends Application implements
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin("DependencyInjection");
- mContextAvailableCallback.onContextAvailable(this);
- mRootComponent = SystemUIFactory.getInstance().getRootComponent();
- mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
- mComponentHelper = mSysUIComponent.getContextComponentHelper();
+ mInitializer = mContextAvailableCallback.onContextAvailable(this);
+ mSysUIComponent = mInitializer.getSysUIComponent();
mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
log.traceEnd();
@@ -189,15 +189,14 @@ public class SystemUIApplication extends Application implements
*/
public void startServicesIfNeeded() {
- final String vendorComponent = SystemUIFactory.getInstance()
- .getVendorComponent(getResources());
+ final String vendorComponent = mInitializer.getVendorComponent(getResources());
// Sort the startables so that we get a deterministic ordering.
// TODO: make #start idempotent and require users of CoreStartable to call it.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
- sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents());
- sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
+ sortedStartables.putAll(mSysUIComponent.getStartables());
+ sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}
@@ -212,7 +211,7 @@ public class SystemUIApplication extends Application implements
// Sort the startables so that we get a deterministic ordering.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
- sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
+ sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
startServicesIfNeeded(
sortedStartables, "StartSecondaryServices", null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index ca94b8cd05b7..5100c09912c8 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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;
@@ -22,8 +22,6 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.DaggerGlobalRootComponent;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.WMComponent;
@@ -31,66 +29,47 @@ import com.android.systemui.util.InitializationChecker;
import com.android.wm.shell.dagger.WMShellConcurrencyModule;
import com.android.wm.shell.transition.ShellTransitions;
-import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
-import javax.inject.Provider;
-
/**
- * Class factory to provide customizable SystemUI components.
+ * Initializer that stands up SystemUI.
+ *
+ * Implementations should override {@link #getGlobalRootComponentBuilder()} to fill in their own
+ * Dagger root component.
*/
-public class SystemUIFactory {
+public abstract class SystemUIInitializer {
private static final String TAG = "SystemUIFactory";
- static SystemUIFactory mFactory;
+ private final Context mContext;
+
private GlobalRootComponent mRootComponent;
private WMComponent mWMComponent;
private SysUIComponent mSysUIComponent;
private InitializationChecker mInitializationChecker;
- public static <T extends SystemUIFactory> T getInstance() {
- return (T) mFactory;
+ public SystemUIInitializer(Context context) {
+ mContext = context;
}
- public static void createFromConfig(Context context) {
- createFromConfig(context, false);
- }
-
- @VisibleForTesting
- public static void createFromConfig(Context context, boolean fromTest) {
- if (mFactory != null) {
- return;
- }
-
- final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
- if (clsName == null || clsName.length() == 0) {
- throw new RuntimeException("No SystemUIFactory component configured");
- }
-
- try {
- Class<?> cls = null;
- cls = context.getClassLoader().loadClass(clsName);
- mFactory = (SystemUIFactory) cls.newInstance();
- mFactory.init(context, fromTest);
- } catch (Throwable t) {
- Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);
- throw new RuntimeException(t);
- }
- }
+ protected abstract GlobalRootComponent.Builder getGlobalRootComponentBuilder();
- @VisibleForTesting
- static void cleanup() {
- mFactory = null;
+ /**
+ * Prepares the SysUIComponent builder before it is built.
+ * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
+ * @param wm the built WMComponent from the root component's getWMComponent() method
+ */
+ protected SysUIComponent.Builder prepareSysUIComponentBuilder(
+ SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
+ return sysUIBuilder;
}
- public SystemUIFactory() {}
-
- @VisibleForTesting
- public void init(Context context, boolean fromTest)
- throws ExecutionException, InterruptedException {
+ /**
+ * Starts the initialization process. This stands up the Dagger graph.
+ */
+ public void init(boolean fromTest) throws ExecutionException, InterruptedException {
mRootComponent = getGlobalRootComponentBuilder()
- .context(context)
+ .context(mContext)
.instrumentationTest(fromTest)
.build();
@@ -98,7 +77,7 @@ public class SystemUIFactory {
boolean initializeComponents = mInitializationChecker.initializeComponents();
// Stand up WMComponent
- setupWmComponent(context);
+ setupWmComponent(mContext);
if (initializeComponents) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
@@ -188,20 +167,6 @@ public class SystemUIFactory {
}
}
- /**
- * Prepares the SysUIComponent builder before it is built.
- * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
- * @param wm the built WMComponent from the root component's getWMComponent() method
- */
- protected SysUIComponent.Builder prepareSysUIComponentBuilder(
- SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
- return sysUIBuilder;
- }
-
- protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
- return DaggerGlobalRootComponent.builder();
- }
-
public GlobalRootComponent getRootComponent() {
return mRootComponent;
}
@@ -215,23 +180,9 @@ public class SystemUIFactory {
}
/**
- * Returns the list of {@link CoreStartable} components that should be started at startup.
- */
- public Map<Class<?>, Provider<CoreStartable>> getStartableComponents() {
- return mSysUIComponent.getStartables();
- }
-
- /**
* Returns the list of additional system UI components that should be started.
*/
public String getVendorComponent(Resources resources) {
return resources.getString(R.string.config_systemUIVendorServiceComponent);
}
-
- /**
- * Returns the list of {@link CoreStartable} components that should be started per user.
- */
- public Map<Class<?>, Provider<CoreStartable>> getStartableComponentsPerUser() {
- return mSysUIComponent.getPerUserStartables();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
new file mode 100644
index 000000000000..b9454e8c3be8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.Log
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.util.Assert
+
+/**
+ * Factory to reflectively lookup a [SystemUIInitializer] to start SystemUI with.
+ */
+@Deprecated("Provide your own {@link SystemUIAppComponentFactoryBase} that doesn't need this.")
+object SystemUIInitializerFactory {
+ private const val TAG = "SysUIInitializerFactory"
+ @SuppressLint("StaticFieldLeak")
+ private var initializer: SystemUIInitializer? = null
+
+ /**
+ * Instantiate a [SystemUIInitializer] reflectively.
+ */
+ @JvmStatic
+ fun createWithContext(context: Context): SystemUIInitializer {
+ return createFromConfig(context)
+ }
+
+ /**
+ * Instantiate a [SystemUIInitializer] reflectively.
+ */
+ @JvmStatic
+ private fun createFromConfig(context: Context): SystemUIInitializer {
+ Assert.isMainThread()
+
+ return createFromConfigNoAssert(context)
+ }
+
+ @JvmStatic
+ @VisibleForTesting
+ fun createFromConfigNoAssert(context: Context): SystemUIInitializer {
+
+ return initializer ?: run {
+ val className = context.getString(R.string.config_systemUIFactoryComponent)
+ if (className.isEmpty()) {
+ throw RuntimeException("No SystemUIFactory component configured")
+ }
+ try {
+ val cls = context.classLoader.loadClass(className)
+ val constructor = cls.getConstructor(Context::class.java)
+ (constructor.newInstance(context) as SystemUIInitializer).apply {
+ initializer = this
+ }
+ } catch (t: Throwable) {
+ Log.w(TAG, "Error creating SystemUIInitializer component: $className", t)
+ throw t
+ }
+ }
+ }
+}
diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.aidl b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
index 731c907f6837..8920c928da09 100644
--- a/core/java/android/app/timedetector/NetworkTimeSuggestion.aidl
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,17 @@
* limitations under the License.
*/
-package android.app.timedetector;
+package com.android.systemui
-parcelable NetworkTimeSuggestion;
+import android.content.Context
+import com.android.systemui.dagger.DaggerGlobalRootComponent
+import com.android.systemui.dagger.GlobalRootComponent
+
+/**
+ * {@link SystemUIInitializer} that stands up AOSP SystemUI.
+ */
+class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) {
+ override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder {
+ return DaggerGlobalRootComponent.builder()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index d2703f5e73a2..aff0b1fe287c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -353,6 +353,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
}
mIsShowing = false;
+ mDragAnimator.cancel();
mWindowManager.removeView(this);
setOnApplyWindowInsetsListener(null);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index bc1c5f4baceb..84e1c3d4c8f0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -90,6 +90,8 @@ public class AuthContainerView extends LinearLayout
private static final int STATE_ANIMATING_OUT = 4;
private static final int STATE_GONE = 5;
+ private static final float BACKGROUND_DIM_AMOUNT = 0.5f;
+
/** Shows biometric prompt dialog animation. */
private static final String SHOW = "show";
/** Dismiss biometric prompt dialog animation. */
@@ -247,13 +249,13 @@ public class AuthContainerView extends LinearLayout
break;
case AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN:
mFailedModalities.clear();
- mConfig.mCallback.onTryAgainPressed();
+ mConfig.mCallback.onTryAgainPressed(getRequestId());
break;
case AuthBiometricView.Callback.ACTION_ERROR:
animateAway(AuthDialogCallback.DISMISSED_ERROR);
break;
case AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL:
- mConfig.mCallback.onDeviceCredentialPressed();
+ mConfig.mCallback.onDeviceCredentialPressed(getRequestId());
mHandler.postDelayed(() -> {
addCredentialView(false /* animatePanel */, true /* animateContents */);
}, mConfig.mSkipAnimation ? 0 : AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS);
@@ -371,7 +373,7 @@ public class AuthContainerView extends LinearLayout
void sendEarlyUserCanceled() {
mConfig.mCallback.onSystemEvent(
- BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL);
+ BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL, getRequestId());
}
@Override
@@ -754,6 +756,16 @@ public class AuthContainerView extends LinearLayout
.setDuration(animateDuration)
.setInterpolator(mLinearOutSlowIn)
.setListener(getJankListener(this, DISMISS, animateDuration))
+ .setUpdateListener(animation -> {
+ if (mWindowManager == null || getViewRootImpl() == null) {
+ Log.w(TAG, "skip updateViewLayout() for dim animation.");
+ return;
+ }
+ final WindowManager.LayoutParams lp = getViewRootImpl().mWindowAttributes;
+ lp.dimAmount = (1.0f - (Float) animation.getAnimatedValue())
+ * BACKGROUND_DIM_AMOUNT;
+ mWindowManager.updateViewLayout(this, lp);
+ })
.withLayer()
.start();
});
@@ -762,7 +774,8 @@ public class AuthContainerView extends LinearLayout
private void sendPendingCallbackIfNotNull() {
Log.d(TAG, "pendingCallback: " + mPendingCallbackReason);
if (mPendingCallbackReason != null) {
- mConfig.mCallback.onDismissed(mPendingCallbackReason, mCredentialAttestation);
+ mConfig.mCallback.onDismissed(mPendingCallbackReason,
+ mCredentialAttestation, getRequestId());
mPendingCallbackReason = null;
}
}
@@ -792,7 +805,7 @@ public class AuthContainerView extends LinearLayout
}
mContainerState = STATE_SHOWING;
if (mBiometricView != null) {
- mConfig.mCallback.onDialogAnimatedIn();
+ mConfig.mCallback.onDialogAnimatedIn(getRequestId());
mBiometricView.onDialogAnimatedIn();
}
}
@@ -800,7 +813,8 @@ public class AuthContainerView extends LinearLayout
@VisibleForTesting
static WindowManager.LayoutParams getLayoutParams(IBinder windowToken, CharSequence title) {
final int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
- | WindowManager.LayoutParams.FLAG_SECURE;
+ | WindowManager.LayoutParams.FLAG_SECURE
+ | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -811,6 +825,7 @@ public class AuthContainerView extends LinearLayout
lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime());
lp.setTitle("BiometricPrompt");
lp.accessibilityTitle = title;
+ lp.dimAmount = BACKGROUND_DIM_AMOUNT;
lp.token = windowToken;
return lp;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index a097c5e76149..47ff59cfc281 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -340,11 +340,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
@Override
- public void onTryAgainPressed() {
+ public void onTryAgainPressed(long requestId) {
if (mReceiver == null) {
Log.e(TAG, "onTryAgainPressed: Receiver is null");
return;
}
+
+ if (requestId != mCurrentDialog.getRequestId()) {
+ Log.w(TAG, "requestId doesn't match, skip onTryAgainPressed");
+ return;
+ }
+
try {
mReceiver.onTryAgainPressed();
} catch (RemoteException e) {
@@ -353,11 +359,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
@Override
- public void onDeviceCredentialPressed() {
+ public void onDeviceCredentialPressed(long requestId) {
if (mReceiver == null) {
Log.e(TAG, "onDeviceCredentialPressed: Receiver is null");
return;
}
+
+ if (requestId != mCurrentDialog.getRequestId()) {
+ Log.w(TAG, "requestId doesn't match, skip onDeviceCredentialPressed");
+ return;
+ }
+
try {
mReceiver.onDeviceCredentialPressed();
} catch (RemoteException e) {
@@ -366,11 +378,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
@Override
- public void onSystemEvent(int event) {
+ public void onSystemEvent(int event, long requestId) {
if (mReceiver == null) {
Log.e(TAG, "onSystemEvent(" + event + "): Receiver is null");
return;
}
+
+ if (requestId != mCurrentDialog.getRequestId()) {
+ Log.w(TAG, "requestId doesn't match, skip onSystemEvent");
+ return;
+ }
+
try {
mReceiver.onSystemEvent(event);
} catch (RemoteException e) {
@@ -379,12 +397,17 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
@Override
- public void onDialogAnimatedIn() {
+ public void onDialogAnimatedIn(long requestId) {
if (mReceiver == null) {
Log.e(TAG, "onDialogAnimatedIn: Receiver is null");
return;
}
+ if (requestId != mCurrentDialog.getRequestId()) {
+ Log.w(TAG, "requestId doesn't match, skip onDialogAnimatedIn");
+ return;
+ }
+
try {
mReceiver.onDialogAnimatedIn();
} catch (RemoteException e) {
@@ -393,7 +416,14 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
}
@Override
- public void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation) {
+ public void onDismissed(@DismissedReason int reason,
+ @Nullable byte[] credentialAttestation, long requestId) {
+
+ if (mCurrentDialog != null && requestId != mCurrentDialog.getRequestId()) {
+ Log.w(TAG, "requestId doesn't match, skip onDismissed");
+ return;
+ }
+
switch (reason) {
case AuthDialogCallback.DISMISSED_USER_CANCELED:
sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_USER_CANCEL,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
index a7d2901b21c3..bbe461aaf6d9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
@@ -47,27 +47,28 @@ public interface AuthDialogCallback {
* @param reason
* @param credentialAttestation the HAT received from LockSettingsService upon verification
*/
- void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation);
+ void onDismissed(@DismissedReason int reason,
+ @Nullable byte[] credentialAttestation, long requestId);
/**
* Invoked when the "try again" button is clicked
*/
- void onTryAgainPressed();
+ void onTryAgainPressed(long requestId);
/**
* Invoked when the "use password" button is clicked
*/
- void onDeviceCredentialPressed();
+ void onDeviceCredentialPressed(long requestId);
/**
* See {@link android.hardware.biometrics.BiometricPrompt.Builder
* #setReceiveSystemEvents(boolean)}
* @param event
*/
- void onSystemEvent(int event);
+ void onSystemEvent(int event, long requestId);
/**
* Notifies when the dialog has finished animating.
*/
- void onDialogAnimatedIn();
+ void onDialogAnimatedIn(long requestId);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
index 04e2dccda528..bbffb73b7503 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
@@ -34,16 +34,16 @@ import android.hardware.fingerprint.ISidefpsController
import android.os.Handler
import android.util.Log
import android.util.RotationUtils
-import android.view.View.AccessibilityDelegate
-import android.view.accessibility.AccessibilityEvent
import android.view.Display
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Surface
import android.view.View
+import android.view.View.AccessibilityDelegate
import android.view.ViewPropertyAnimator
import android.view.WindowInsets
import android.view.WindowManager
+import android.view.accessibility.AccessibilityEvent
import androidx.annotation.RawRes
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieProperty
@@ -70,13 +70,12 @@ class SidefpsController @Inject constructor(
private val activityTaskManager: ActivityTaskManager,
overviewProxyService: OverviewProxyService,
displayManager: DisplayManager,
- @Main mainExecutor: DelayableExecutor,
+ @Main private val mainExecutor: DelayableExecutor,
@Main private val handler: Handler
) {
@VisibleForTesting
val sensorProps: FingerprintSensorPropertiesInternal = fingerprintManager
- ?.sensorPropertiesInternal
- ?.firstOrNull { it.isAnySidefpsType }
+ ?.sideFpsSensorProperties
?: throw IllegalStateException("no side fingerprint sensor")
@VisibleForTesting
@@ -135,25 +134,34 @@ class SidefpsController @Inject constructor(
}
init {
- fingerprintManager?.setSidefpsController(object : ISidefpsController.Stub() {
- override fun show(
- sensorId: Int,
- @BiometricOverlayConstants.ShowReason reason: Int
- ) = if (reason.isReasonToShow(activityTaskManager)) doShow() else hide(sensorId)
-
- private fun doShow() = mainExecutor.execute {
- if (overlayView == null) {
- createOverlayForDisplay()
- } else {
- Log.v(TAG, "overlay already shown")
- }
- }
+ fingerprintManager?.setSidefpsController(
+ object : ISidefpsController.Stub() {
+ override fun show(
+ sensorId: Int,
+ @BiometricOverlayConstants.ShowReason reason: Int
+ ) = if (reason.isReasonToShow(activityTaskManager)) show() else hide()
- override fun hide(sensorId: Int) = mainExecutor.execute { overlayView = null }
- })
+ override fun hide(sensorId: Int) = hide()
+ })
overviewProxyService.addCallback(overviewProxyListener)
}
+ /** Shows the side fps overlay if not already shown. */
+ fun show() {
+ mainExecutor.execute {
+ if (overlayView == null) {
+ createOverlayForDisplay()
+ } else {
+ Log.v(TAG, "overlay already shown")
+ }
+ }
+ }
+
+ /** Hides the fps overlay if shown. */
+ fun hide() {
+ mainExecutor.execute { overlayView = null }
+ }
+
private fun onOrientationChanged() {
if (overlayView != null) {
createOverlayForDisplay()
@@ -266,6 +274,12 @@ class SidefpsController @Inject constructor(
}
}
+private val FingerprintManager?.sideFpsSensorProperties: FingerprintSensorPropertiesInternal?
+ get() = this?.sensorPropertiesInternal?.firstOrNull { it.isAnySidefpsType }
+
+/** Returns [True] when the device has a side fingerprint sensor. */
+fun FingerprintManager?.hasSideFpsSensor(): Boolean = this?.sideFpsSensorProperties != null
+
@BiometricOverlayConstants.ShowReason
private fun Int.isReasonToShow(activityTaskManager: ActivityTaskManager): Boolean = when (this) {
REASON_AUTH_KEYGUARD -> false
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index e5564b7f1f26..fb502e5b72cc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -20,6 +20,7 @@ import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPR
import static android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.systemui.classifier.Classifier.LOCK_ICON;
import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
import android.annotation.NonNull;
@@ -167,11 +168,16 @@ public class UdfpsController implements DozeReceiver {
private final Set<Callback> mCallbacks = new HashSet<>();
@VisibleForTesting
- public static final VibrationAttributes VIBRATION_ATTRIBUTES =
+ public static final VibrationAttributes UDFPS_VIBRATION_ATTRIBUTES =
new VibrationAttributes.Builder()
// vibration will bypass battery saver mode:
.setUsage(VibrationAttributes.USAGE_COMMUNICATION_REQUEST)
.build();
+ @VisibleForTesting
+ public static final VibrationAttributes LOCK_ICON_VIBRATION_ATTRIBUTES =
+ new VibrationAttributes.Builder()
+ .setUsage(VibrationAttributes.USAGE_TOUCH)
+ .build();
// haptic to use for successful device entry
public static final VibrationEffect EFFECT_CLICK =
@@ -671,7 +677,7 @@ public class UdfpsController implements DozeReceiver {
mContext.getOpPackageName(),
EFFECT_CLICK,
"udfps-onStart-click",
- VIBRATION_ATTRIBUTES);
+ UDFPS_VIBRATION_ATTRIBUTES);
}
}
@@ -748,7 +754,19 @@ public class UdfpsController implements DozeReceiver {
}
if (!mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
+ if (mFalsingManager.isFalseTouch(LOCK_ICON)) {
+ Log.v(TAG, "aod lock icon long-press rejected by the falsing manager.");
+ return;
+ }
mKeyguardViewManager.showBouncer(true);
+
+ // play the same haptic as the LockIconViewController longpress
+ mVibrator.vibrate(
+ Process.myUid(),
+ mContext.getOpPackageName(),
+ UdfpsController.EFFECT_CLICK,
+ "aod-lock-icon-longpress",
+ LOCK_ICON_VIBRATION_ATTRIBUTES);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index 3f78f97ba563..1fa9ac574c7e 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -74,6 +74,7 @@ public class EditTextActivity extends Activity
}
mEditText.setText(clip.getItemAt(0).getText());
mEditText.requestFocus();
+ mEditText.setSelection(0);
mSensitive = clip.getDescription().getExtras() != null
&& clip.getDescription().getExtras()
.getBoolean(ClipDescription.EXTRA_IS_SENSITIVE);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 3a1b12955647..550af7cafc75 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -21,7 +21,7 @@ import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dependency;
import com.android.systemui.InitController;
-import com.android.systemui.SystemUIAppComponentFactory;
+import com.android.systemui.SystemUIAppComponentFactoryBase;
import com.android.systemui.dagger.qualifiers.PerUser;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
@@ -241,7 +241,7 @@ public interface SysUIComponent {
/**
* Member injection into the supplied argument.
*/
- void inject(SystemUIAppComponentFactory factory);
+ void inject(SystemUIAppComponentFactoryBase factory);
/**
* Member injection into the supplied argument.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index a9f340854689..6db3e82a77b0 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -33,6 +33,7 @@ import com.android.systemui.log.SessionTracker
import com.android.systemui.media.RingtonePlayer
import com.android.systemui.power.PowerUI
import com.android.systemui.recents.Recents
+import com.android.systemui.settings.dagger.MultiUserUtilsModule
import com.android.systemui.shortcut.ShortcutKeyDispatcher
import com.android.systemui.statusbar.notification.InstantAppNotifier
import com.android.systemui.statusbar.phone.KeyguardLiftController
@@ -51,7 +52,7 @@ import dagger.multibindings.IntoMap
/**
* Collection of {@link CoreStartable}s that should be run on AOSP.
*/
-@Module
+@Module(includes = [MultiUserUtilsModule::class])
abstract class SystemUICoreStartableModule {
/** Inject into AuthController. */
@Binds
@@ -205,4 +206,4 @@ abstract class SystemUICoreStartableModule {
@IntoMap
@ClassKey(KeyguardLiftController::class)
abstract fun bindKeyguardLiftController(sysui: KeyguardLiftController): CoreStartable
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 137e28888728..664374886df4 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -26,7 +26,6 @@ import com.android.keyguard.clock.ClockModule;
import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
@@ -50,7 +49,7 @@ import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.privacy.PrivacyModule;
import com.android.systemui.recents.Recents;
import com.android.systemui.screenshot.dagger.ScreenshotModule;
-import com.android.systemui.settings.dagger.SettingsModule;
+import com.android.systemui.settings.dagger.MultiUserUtilsModule;
import com.android.systemui.smartspace.dagger.SmartspaceModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -82,6 +81,7 @@ import com.android.systemui.unfold.SysUIUnfoldModule;
import com.android.systemui.user.UserModule;
import com.android.systemui.util.concurrency.SysUIConcurrencyModule;
import com.android.systemui.util.dagger.UtilModule;
+import com.android.systemui.util.kotlin.CoroutinesModule;
import com.android.systemui.util.sensors.SensorModule;
import com.android.systemui.util.settings.SettingsUtilModule;
import com.android.systemui.util.time.SystemClock;
@@ -114,6 +114,7 @@ import dagger.Provides;
AssistModule.class,
BiometricsModule.class,
ClockModule.class,
+ CoroutinesModule.class,
DreamModule.class,
ControlsModule.class,
DemoModeModule.class,
@@ -127,7 +128,7 @@ import dagger.Provides;
QsFrameTranslateModule.class,
ScreenshotModule.class,
SensorModule.class,
- SettingsModule.class,
+ MultiUserUtilsModule.class,
SettingsUtilModule.class,
SmartRepliesInflationModule.class,
SmartspaceModule.class,
@@ -198,11 +199,6 @@ public abstract class SystemUIModule {
@Binds
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
- @Provides
- static SystemUIFactory getSystemUIFactory() {
- return SystemUIFactory.getInstance();
- }
-
// TODO: This should provided by the WM component
/** Provides Optional of BubbleManager */
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index 1570a7ebc0c4..f2f1798c94f6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -21,7 +21,7 @@ import android.os.HandlerThread;
import androidx.annotation.Nullable;
-import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SystemUIInitializerFactory;
import com.android.systemui.tv.TvWMComponent;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.ShellInit;
@@ -52,7 +52,7 @@ import dagger.Subcomponent;
/**
* Dagger Subcomponent for WindowManager. This class explicitly describes the interfaces exported
* from the WM component into the SysUI component (in
- * {@link SystemUIFactory#init(Context, boolean)}), and references the specific dependencies
+ * {@link SystemUIInitializerFactory#init(Context, boolean)}), and references the specific dependencies
* provided by its particular device/form-factor SystemUI implementation.
*
* ie. {@link WMComponent} includes {@link WMShellModule}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 70e4fa3aa27f..7c816cec08f2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -26,8 +26,6 @@ import android.os.SystemClock;
import android.text.format.Formatter;
import android.util.Log;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -44,8 +42,6 @@ import javax.inject.Inject;
*/
@DozeScope
public class DozeUi implements DozeMachine.Part {
- // if enabled, calls dozeTimeTick() whenever the time changes:
- private static final boolean BURN_IN_TESTING_ENABLED = false;
private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
private final Context mContext;
private final DozeHost mHost;
@@ -57,26 +53,13 @@ public class DozeUi implements DozeMachine.Part {
private final DozeParameters mDozeParameters;
private final DozeLog mDozeLog;
private final StatusBarStateController mStatusBarStateController;
- private final KeyguardUpdateMonitorCallback mKeyguardVisibilityCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onTimeChanged() {
- if (BURN_IN_TESTING_ENABLED && mStatusBarStateController.isDozing()) {
- // update whenever the time changes for manual burn in testing
- mHost.dozeTimeTick();
-
- // Keep wakelock until a frame has been pushed.
- mHandler.post(mWakeLock.wrap(() -> {}));
- }
- }
- };
private long mLastTimeTickElapsed = 0;
@Inject
public DozeUi(Context context, AlarmManager alarmManager,
WakeLock wakeLock, DozeHost host, @Main Handler handler,
- DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor,
+ DozeParameters params,
StatusBarStateController statusBarStateController,
DozeLog dozeLog) {
mContext = context;
@@ -86,7 +69,6 @@ public class DozeUi implements DozeMachine.Part {
mCanAnimateTransition = !params.getDisplayNeedsBlanking();
mDozeParameters = params;
mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
- keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
mDozeLog = dozeLog;
mStatusBarStateController = statusBarStateController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index 59a17bad5069..a25257d6cf42 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -43,6 +43,8 @@ public class DreamOverlayStatusBarView extends ConstraintLayout {
STATUS_ICON_NOTIFICATIONS,
STATUS_ICON_WIFI_UNAVAILABLE,
STATUS_ICON_ALARM_SET,
+ STATUS_ICON_CAMERA_DISABLED,
+ STATUS_ICON_MIC_DISABLED,
STATUS_ICON_MIC_CAMERA_DISABLED,
STATUS_ICON_PRIORITY_MODE_ON
})
@@ -50,8 +52,10 @@ public class DreamOverlayStatusBarView extends ConstraintLayout {
public static final int STATUS_ICON_NOTIFICATIONS = 0;
public static final int STATUS_ICON_WIFI_UNAVAILABLE = 1;
public static final int STATUS_ICON_ALARM_SET = 2;
- public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 3;
- public static final int STATUS_ICON_PRIORITY_MODE_ON = 4;
+ public static final int STATUS_ICON_CAMERA_DISABLED = 3;
+ public static final int STATUS_ICON_MIC_DISABLED = 4;
+ public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 5;
+ public static final int STATUS_ICON_PRIORITY_MODE_ON = 6;
private final Map<Integer, View> mStatusIcons = new HashMap<>();
@@ -80,6 +84,10 @@ public class DreamOverlayStatusBarView extends ConstraintLayout {
fetchStatusIconForResId(R.id.dream_overlay_wifi_status));
mStatusIcons.put(STATUS_ICON_ALARM_SET,
fetchStatusIconForResId(R.id.dream_overlay_alarm_set));
+ mStatusIcons.put(STATUS_ICON_CAMERA_DISABLED,
+ fetchStatusIconForResId(R.id.dream_overlay_camera_off));
+ mStatusIcons.put(STATUS_ICON_MIC_DISABLED,
+ fetchStatusIconForResId(R.id.dream_overlay_mic_off));
mStatusIcons.put(STATUS_ICON_MIC_CAMERA_DISABLED,
fetchStatusIconForResId(R.id.dream_overlay_camera_mic_off));
mStatusIcons.put(STATUS_ICON_NOTIFICATIONS,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index 250313d0aae8..de7bf28c01d6 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -214,9 +214,17 @@ public class DreamOverlayStatusBarViewController extends ViewController<DreamOve
.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE);
final boolean cameraBlocked = mSensorPrivacyController
.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA);
- showIcon(
- DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED,
- micBlocked && cameraBlocked);
+ @DreamOverlayStatusBarView.StatusIconType int iconType = Resources.ID_NULL;
+ if (micBlocked && cameraBlocked) {
+ iconType = DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED;
+ } else if (!micBlocked && cameraBlocked) {
+ iconType = DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED;
+ } else if (micBlocked && !cameraBlocked) {
+ iconType = DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED;
+ }
+ if (iconType != Resources.ID_NULL) {
+ showIcon(iconType, true);
+ }
}
private String buildNotificationsContentDescription(int notificationCount) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
index 4eae3b928c64..ce61b163dd17 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
@@ -24,6 +24,7 @@ import android.app.smartspace.SmartspaceAction;
import android.app.smartspace.SmartspaceTarget;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
@@ -133,16 +134,19 @@ public class DreamWeatherComplication implements Complication {
private final ActivityStarter mActivityStarter;
private final String mSmartspaceTrampolineActivityComponent;
private SmartspaceTargetListener mSmartspaceTargetListener;
+ private final Resources mResources;
@Inject
DreamWeatherViewController(
@Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
@Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline,
ActivityStarter activityStarter,
- DreamSmartspaceController smartspaceController
+ DreamSmartspaceController smartspaceController,
+ Resources resources
) {
super(view);
mActivityStarter = activityStarter;
+ mResources = resources;
mSmartSpaceController = smartspaceController;
mSmartspaceTrampolineActivityComponent = smartspaceTrampoline;
}
@@ -161,8 +165,10 @@ public class DreamWeatherComplication implements Complication {
return;
}
- String temperature = headerAction.getTitle().toString();
+ final CharSequence temperature = headerAction.getTitle();
mView.setText(temperature);
+ mView.setContentDescription(getFormattedContentDescription(temperature,
+ headerAction.getContentDescription()));
final Icon icon = headerAction.getIcon();
if (icon != null) {
final int iconSize =
@@ -174,7 +180,6 @@ public class DreamWeatherComplication implements Complication {
mView.setCompoundDrawablePadding(
getResources().getDimensionPixelSize(
R.dimen.smart_action_button_icon_padding));
-
}
mView.setOnClickListener(v -> {
final Intent intent = headerAction.getIntent();
@@ -196,5 +201,21 @@ public class DreamWeatherComplication implements Complication {
protected void onViewDetached() {
mSmartSpaceController.removeUnfilteredListener(mSmartspaceTargetListener);
}
+
+ /**
+ * Returns a formatted content description for accessibility of the weather condition and
+ * temperature.
+ */
+ private CharSequence getFormattedContentDescription(CharSequence temperature,
+ CharSequence weatherCondition) {
+ if (TextUtils.isEmpty(temperature)) {
+ return weatherCondition;
+ } else if (TextUtils.isEmpty(weatherCondition)) {
+ return temperature;
+ }
+
+ return mResources.getString(R.string.dream_overlay_weather_complication_desc,
+ weatherCondition, temperature);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
index 7ab3ad1a621a..f1a16897fdbc 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
@@ -19,12 +19,14 @@ package com.android.systemui.dreams.complication.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.internal.util.Preconditions;
import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.complication.ComplicationLayoutParams;
import com.android.systemui.dreams.complication.DreamWeatherComplication.DreamWeatherViewHolder;
@@ -34,6 +36,7 @@ import java.lang.annotation.Retention;
import javax.inject.Named;
import javax.inject.Scope;
+import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
@@ -106,5 +109,12 @@ public interface DreamWeatherComplicationComponent {
ComplicationLayoutParams.DIRECTION_END,
INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
}
+
+ /**
+ * Binds resources in the dream weather complication scope.
+ */
+ @Binds
+ @DreamWeatherComplicationScope
+ Resources getResources(@Main Resources resources);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index e73eaa1da4ae..15c17619a3bd 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -207,7 +207,8 @@ public class Flags {
public static final SysPropBooleanFlag WM_ALWAYS_ENFORCE_PREDICTIVE_BACK =
new SysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", false);
- public static final BooleanFlag NEW_BACK_AFFORDANCE = new BooleanFlag(1203, true);
+ public static final BooleanFlag NEW_BACK_AFFORDANCE =
+ new BooleanFlag(1203, false /* default */, true /* teamfood */);
// Pay no attention to the reflection behind the curtain.
// ========================== Curtain ==========================
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7abf2a8241bb..b28073c01177 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -556,15 +556,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
@Override
- public void onUserInfoChanged(int userId) {
- }
-
- @Override
- public void onClockVisibilityChanged() {
- adjustStatusBarLocked();
- }
-
- @Override
public void onDeviceProvisioned() {
sendUserPresentBroadcast();
synchronized (KeyguardViewMediator.this) {
@@ -1197,6 +1188,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mSystemReady = true;
doKeyguardLocked(null);
mUpdateMonitor.registerCallback(mUpdateCallback);
+ adjustStatusBarLocked();
mDreamOverlayStateController.addCallback(mDreamOverlayStateCallback);
}
// Most services aren't available until the system reaches the ready state, so we
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt
new file mode 100644
index 000000000000..55c7ac9fb0cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwner.kt
@@ -0,0 +1,114 @@
+package com.android.systemui.lifecycle
+
+import android.view.View
+import android.view.ViewTreeObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.LifecycleRegistry
+
+/**
+ * [LifecycleOwner] for Window-added Views.
+ *
+ * These are [View] instances that are added to a `Window` using the `WindowManager` API.
+ *
+ * This implementation goes to:
+ * * The <b>CREATED</b> `Lifecycle.State` when the view gets attached to the window but the window
+ * is not yet visible
+ * * The <b>STARTED</b> `Lifecycle.State` when the view is attached to the window and the window is
+ * visible
+ * * The <b>RESUMED</b> `Lifecycle.State` when the view is attached to the window and the window is
+ * visible and the window receives focus
+ *
+ * In table format:
+ * ```
+ * | ----------------------------------------------------------------------------- |
+ * | View attached to window | Window visible | Window has focus | Lifecycle state |
+ * | ----------------------------------------------------------------------------- |
+ * | not attached | Any | INITIALIZED |
+ * | ----------------------------------------------------------------------------- |
+ * | | not visible | Any | CREATED |
+ * | ----------------------------------------------------- |
+ * | attached | | not focused | STARTED |
+ * | | is visible |----------------------------------- |
+ * | | | has focus | RESUMED |
+ * | ----------------------------------------------------------------------------- |
+ * ```
+ * ### Notes
+ * * [dispose] must be invoked when the [LifecycleOwner] is done and won't be reused
+ * * It is always better for [LifecycleOwner] implementations to be more explicit than just
+ * listening to the state of the `Window`. E.g. if the code that added the `View` to the `Window`
+ * already has access to the correct state to know when that `View` should become visible and when
+ * it is ready to receive interaction from the user then it already knows when to move to `STARTED`
+ * and `RESUMED`, respectively. In that case, it's better to implement your own `LifecycleOwner`
+ * instead of relying on the `Window` callbacks.
+ */
+class WindowAddedViewLifecycleOwner
+@JvmOverloads
+constructor(
+ private val view: View,
+ registryFactory: (LifecycleOwner) -> LifecycleRegistry = { LifecycleRegistry(it) },
+) : LifecycleOwner {
+
+ private val windowAttachListener =
+ object : ViewTreeObserver.OnWindowAttachListener {
+ override fun onWindowAttached() {
+ updateCurrentState()
+ }
+
+ override fun onWindowDetached() {
+ updateCurrentState()
+ }
+ }
+ private val windowFocusListener =
+ ViewTreeObserver.OnWindowFocusChangeListener { updateCurrentState() }
+ private val windowVisibilityListener =
+ ViewTreeObserver.OnWindowVisibilityChangeListener { updateCurrentState() }
+
+ private val registry = registryFactory(this)
+
+ init {
+ setCurrentState(Lifecycle.State.INITIALIZED)
+
+ with(view.viewTreeObserver) {
+ addOnWindowAttachListener(windowAttachListener)
+ addOnWindowVisibilityChangeListener(windowVisibilityListener)
+ addOnWindowFocusChangeListener(windowFocusListener)
+ }
+
+ updateCurrentState()
+ }
+
+ override fun getLifecycle(): Lifecycle {
+ return registry
+ }
+
+ /**
+ * Disposes of this [LifecycleOwner], performing proper clean-up.
+ *
+ * <p>Invoke this when the instance is finished and won't be reused.
+ */
+ fun dispose() {
+ with(view.viewTreeObserver) {
+ removeOnWindowAttachListener(windowAttachListener)
+ removeOnWindowVisibilityChangeListener(windowVisibilityListener)
+ removeOnWindowFocusChangeListener(windowFocusListener)
+ }
+ }
+
+ private fun updateCurrentState() {
+ val state =
+ when {
+ !view.isAttachedToWindow -> Lifecycle.State.INITIALIZED
+ view.windowVisibility != View.VISIBLE -> Lifecycle.State.CREATED
+ !view.hasWindowFocus() -> Lifecycle.State.STARTED
+ else -> Lifecycle.State.RESUMED
+ }
+ setCurrentState(state)
+ }
+
+ private fun setCurrentState(state: Lifecycle.State) {
+ if (registry.currentState != state) {
+ registry.currentState = state
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 1ed65b31dbd0..aeff2d41bf92 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -1005,16 +1005,13 @@ public class MediaControlPanel {
private void bindScrubbingTime(MediaData data) {
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
- ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
int elapsedTimeId = mMediaViewHolder.getScrubbingElapsedTimeView().getId();
int totalTimeId = mMediaViewHolder.getScrubbingTotalTimeView().getId();
boolean visible = scrubbingTimeViewsEnabled(data.getSemanticActions()) && mIsScrubbing;
setVisibleAndAlpha(expandedSet, elapsedTimeId, visible);
setVisibleAndAlpha(expandedSet, totalTimeId, visible);
- // Never show in collapsed
- setVisibleAndAlpha(collapsedSet, elapsedTimeId, false);
- setVisibleAndAlpha(collapsedSet, totalTimeId, false);
+ // Collapsed view is always GONE as set in XML, so doesn't need to be updated dynamically
}
private boolean scrubbingTimeViewsEnabled(@Nullable MediaButton semanticActions) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index 83050503a18f..25186597e0e1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -188,24 +188,28 @@ class MediaDeviceManager @Inject constructor(
@AnyThread
fun start() = bgExecutor.execute {
- localMediaManager.registerCallback(this)
- localMediaManager.startScan()
- muteAwaitConnectionManager?.startListening()
- playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
- controller?.registerCallback(this)
- updateCurrent()
- started = true
- configurationController.addCallback(configListener)
+ if (!started) {
+ localMediaManager.registerCallback(this)
+ localMediaManager.startScan()
+ muteAwaitConnectionManager?.startListening()
+ playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
+ controller?.registerCallback(this)
+ updateCurrent()
+ started = true
+ configurationController.addCallback(configListener)
+ }
}
@AnyThread
fun stop() = bgExecutor.execute {
- started = false
- controller?.unregisterCallback(this)
- localMediaManager.stopScan()
- localMediaManager.unregisterCallback(this)
- muteAwaitConnectionManager?.stopListening()
- configurationController.removeCallback(configListener)
+ if (started) {
+ started = false
+ controller?.unregisterCallback(this)
+ localMediaManager.stopScan()
+ localMediaManager.unregisterCallback(this)
+ muteAwaitConnectionManager?.stopListening()
+ configurationController.removeCallback(configListener)
+ }
}
fun dump(pw: PrintWriter) {
@@ -265,7 +269,6 @@ class MediaDeviceManager @Inject constructor(
updateCurrent()
}
-
override fun onBroadcastStarted(reason: Int, broadcastId: Int) {
if (DEBUG) {
Log.d(TAG, "onBroadcastStarted(), reason = $reason , broadcastId = $broadcastId")
@@ -279,8 +282,10 @@ class MediaDeviceManager @Inject constructor(
}
}
- override fun onBroadcastMetadataChanged(broadcastId: Int,
- metadata: BluetoothLeBroadcastMetadata) {
+ override fun onBroadcastMetadataChanged(
+ broadcastId: Int,
+ metadata: BluetoothLeBroadcastMetadata
+ ) {
if (DEBUG) {
Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = $broadcastId , " +
"metadata = $metadata")
@@ -291,7 +296,6 @@ class MediaDeviceManager @Inject constructor(
override fun onBroadcastStopped(reason: Int, broadcastId: Int) {
if (DEBUG) {
Log.d(TAG, "onBroadcastStopped(), reason = $reason , broadcastId = $broadcastId")
-
}
updateCurrent()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index a617850ef0ae..f8f784ff948c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -112,7 +112,7 @@ public class NotificationPlayer implements OnCompletionListener, OnErrorListener
if (DEBUG) Log.d(mTag, "requesting AudioFocus");
int focusGain = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
if (mCmd.looping) {
- focusGain = AudioManager.AUDIOFOCUS_GAIN;
+ focusGain = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT;
}
mNotificationRampTimeMs = audioManager.getFocusRampTimeMs(
focusGain, mCmd.attributes);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index ec4c4e6b3363..e9b6af44ddf3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -60,7 +60,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
@Override
public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
final int size = mController.getMediaDevices().size();
- if (position == size && mController.isZeroMode()) {
+ if (position == size) {
viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
true /* bottomMargin */);
} else if (position < size) {
@@ -75,7 +75,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
@Override
public long getItemId(int position) {
final int size = mController.getMediaDevices().size();
- if (position == size && mController.isZeroMode()) {
+ if (position == size) {
return -1;
} else if (position < size) {
return ((List<MediaDevice>) (mController.getMediaDevices()))
@@ -88,11 +88,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
@Override
public int getItemCount() {
- if (mController.isZeroMode()) {
- // Add extra one for "pair new" or dynamic group
- return mController.getMediaDevices().size() + 1;
- }
- return mController.getMediaDevices().size();
+ // Add extra one for "pair new"
+ return mController.getMediaDevices().size() + 1;
}
class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 9b964a5cc09f..1d773a1984de 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -91,6 +91,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
private TextView mHeaderSubtitle;
private ImageView mHeaderIcon;
private ImageView mAppResourceIcon;
+ private ImageView mBroadcastIcon;
private RecyclerView mDevicesRecyclerView;
private LinearLayout mDeviceListLayout;
private LinearLayout mCastAppLayout;
@@ -239,6 +240,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
mAppButton = mDialogView.requireViewById(R.id.launch_app_button);
mAppResourceIcon = mDialogView.requireViewById(R.id.app_source_icon);
mCastAppLayout = mDialogView.requireViewById(R.id.cast_app_section);
+ mBroadcastIcon = mDialogView.requireViewById(R.id.broadcast_icon);
mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
mDeviceListLayoutListener);
@@ -366,6 +368,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
mStopButton.setEnabled(true);
mStopButton.setText(getStopButtonText());
mStopButton.setOnClickListener(v -> onStopButtonClick());
+
+ mBroadcastIcon.setVisibility(getBroadcastIconVisibility());
+ mBroadcastIcon.setOnClickListener(v -> onBroadcastIconClick());
}
private void updateButtonBackgroundColorFilter() {
@@ -490,6 +495,14 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
dismiss();
}
+ public int getBroadcastIconVisibility() {
+ return View.GONE;
+ }
+
+ public void onBroadcastIconClick() {
+ // Do nothing.
+ }
+
public boolean isBroadcastSupported() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 247ffa7c2ef9..7e3275da8c31 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -16,7 +16,7 @@
package com.android.systemui.media.dialog;
-import static android.provider.Settings.ACTION_BLUETOOTH_PAIRING_SETTINGS;
+import static android.provider.Settings.ACTION_BLUETOOTH_SETTINGS;
import android.annotation.CallbackExecutor;
import android.app.AlertDialog;
@@ -300,6 +300,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
return;
}
try {
+ synchronized (mMediaDevicesLock) {
+ mMediaDevices.removeIf(MediaDevice::isMutingExpectedDevice);
+ }
mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice());
} catch (Exception e) {
Log.d(TAG, "Unable to cancel mute await connection");
@@ -711,22 +714,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
return false;
}
- boolean isZeroMode() {
- synchronized (mMediaDevicesLock) {
- if (mMediaDevices.size() == 1) {
- final MediaDevice device = mMediaDevices.iterator().next();
- // Add "pair new" only when local output device exists
- final int type = device.getDeviceType();
- if (type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE
- || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE
- || type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE) {
- return true;
- }
- }
- return false;
- }
- }
-
void launchBluetoothPairing(View view) {
ActivityLaunchAnimator.Controller controller =
mDialogLaunchAnimator.createActivityLaunchController(view);
@@ -736,7 +723,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
}
Intent launchIntent =
- new Intent(ACTION_BLUETOOTH_PAIRING_SETTINGS)
+ new Intent(ACTION_BLUETOOTH_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
final Intent deepLinkIntent =
new Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index 0c9a8d7d1619..9fb96b56c32c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -134,6 +134,17 @@ public class MediaOutputDialog extends MediaOutputBaseDialog {
}
}
+ @Override
+ public int getBroadcastIconVisibility() {
+ return (isBroadcastSupported() && mMediaOutputController.isBluetoothLeBroadcastEnabled())
+ ? View.VISIBLE : View.GONE;
+ }
+
+ @Override
+ public void onBroadcastIconClick() {
+ startLeBroadcastDialog();
+ }
+
@VisibleForTesting
public enum MediaOutputEvent implements UiEventLogger.UiEventEnum {
@UiEvent(doc = "The MediaOutput dialog became visible on the screen.")
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index a83367059736..28ab83c83a42 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -30,6 +30,7 @@ import android.view.Gravity
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.View
+import android.view.ViewConfiguration
import android.view.WindowManager
import android.view.animation.DecelerateInterpolator
import android.view.animation.PathInterpolator
@@ -98,6 +99,7 @@ class BackPanelController private constructor(
context: Context,
private var backAnimation: BackAnimation?,
private val windowManager: WindowManager,
+ private val viewConfiguration: ViewConfiguration,
@Main private val mainHandler: Handler,
private val vibratorHelper: VibratorHelper,
private val configurationController: ConfigurationController,
@@ -112,6 +114,7 @@ class BackPanelController private constructor(
*/
class Factory @Inject constructor(
private val windowManager: WindowManager,
+ private val viewConfiguration: ViewConfiguration,
@Main private val mainHandler: Handler,
private val vibratorHelper: VibratorHelper,
private val configurationController: ConfigurationController,
@@ -123,6 +126,7 @@ class BackPanelController private constructor(
context,
backAnimation,
windowManager,
+ viewConfiguration,
mainHandler,
vibratorHelper,
configurationController,
@@ -164,6 +168,10 @@ class BackPanelController private constructor(
private var gestureStartTime = 0L
+ // Whether the current gesture has moved a sufficiently large amount,
+ // so that we can unambiguously start showing the ENTRY animation
+ private var hasPassedDragSlop = false
+
private val failsafeRunnable = Runnable { onFailsafe() }
private enum class GestureState {
@@ -304,18 +312,17 @@ class BackPanelController private constructor(
startX = event.x
startY = event.y
gestureStartTime = SystemClock.uptimeMillis()
-
- // Reset the arrow to the side
- updateArrowState(GestureState.ENTRY)
-
- windowManager.updateViewLayout(mView, layoutParams)
- mView.startTrackingShowBackArrowLatency()
}
- MotionEvent.ACTION_MOVE -> handleMoveEvent(event)
+ MotionEvent.ACTION_MOVE -> {
+ // only go to the ENTRY state after some minimum motion has occurred
+ if (dragSlopExceeded(event.x, startX)) {
+ handleMoveEvent(event)
+ }
+ }
MotionEvent.ACTION_UP -> {
if (currentState == GestureState.ACTIVE) {
updateArrowState(if (isFlung()) GestureState.FLUNG else GestureState.COMMITTED)
- } else {
+ } else if (currentState != GestureState.GONE) { // if invisible, skip animation
updateArrowState(GestureState.CANCELLED)
}
velocityTracker = null
@@ -330,6 +337,28 @@ class BackPanelController private constructor(
}
}
+ /**
+ * Returns false until the current gesture exceeds the touch slop threshold,
+ * and returns true thereafter (we reset on the subsequent back gesture).
+ * The moment it switches from false -> true is important,
+ * because that's when we switch state, from GONE -> ENTRY.
+ * @return whether the current gesture has moved past a minimum threshold.
+ */
+ private fun dragSlopExceeded(curX: Float, startX: Float): Boolean {
+ if (hasPassedDragSlop) return true
+
+ if (abs(curX - startX) > viewConfiguration.scaledTouchSlop) {
+ // Reset the arrow to the side
+ updateArrowState(GestureState.ENTRY)
+
+ windowManager.updateViewLayout(mView, layoutParams)
+ mView.startTrackingShowBackArrowLatency()
+
+ hasPassedDragSlop = true
+ }
+ return hasPassedDragSlop
+ }
+
private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) {
if (!currentState.isInteractive())
return
@@ -533,6 +562,7 @@ class BackPanelController private constructor(
}
private fun resetOnDown() {
+ hasPassedDragSlop = false
hasHapticPlayed = false
totalTouchDelta = 0f
vibrationTime = 0
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index bd6a5fc8661b..067f4cbb975e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -53,7 +53,6 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.WindowManager;
-import android.view.WindowMetrics;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.policy.GestureNavigationSettingsObserver;
@@ -133,7 +132,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
@Override
public void onPrioritizedRotation(@Surface.Rotation int rotation) {
mStartingQuickstepRotation = rotation;
- updateDisabledForQuickstep(mContext.getResources().getConfiguration());
+ updateDisabledForQuickstep(mLastReportedConfig);
}
};
@@ -183,6 +182,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
private final IWindowManager mWindowManagerService;
private final Optional<Pip> mPipOptional;
private final FalsingManager mFalsingManager;
+ private final Configuration mLastReportedConfig = new Configuration();
// Activities which should not trigger Back gesture.
private final List<ComponentName> mGestureBlockingActivities = new ArrayList<>();
@@ -338,6 +338,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
mLatencyTracker = latencyTracker;
mBackGestureTfClassifierProviderProvider = backGestureTfClassifierProviderProvider;
mFeatureFlags = featureFlags;
+ mLastReportedConfig.setTo(mContext.getResources().getConfiguration());
ComponentName recentsComponentName = ComponentName.unflattenFromString(
context.getString(com.android.internal.R.string.config_recentsComponentName));
if (recentsComponentName != null) {
@@ -886,12 +887,12 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
if (DEBUG_MISSING_GESTURE) {
Log.d(DEBUG_MISSING_GESTURE_TAG, "Config changed: config=" + newConfig);
}
+ mLastReportedConfig.updateFrom(newConfig);
updateDisplaySize();
}
private void updateDisplaySize() {
- WindowMetrics metrics = mWindowManager.getMaximumWindowMetrics();
- Rect bounds = metrics.getBounds();
+ Rect bounds = mLastReportedConfig.windowConfiguration.getMaxBounds();
mDisplaySize.set(bounds.width(), bounds.height());
if (DEBUG_MISSING_GESTURE) {
Log.d(DEBUG_MISSING_GESTURE_TAG, "Update display size: mDisplaySize=" + mDisplaySize);
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
index b55d86e8fb1c..0ba077eb0912 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
@@ -29,7 +29,8 @@ import android.os.UserHandle;
import android.util.Log;
import android.widget.RemoteViews;
-import com.android.systemui.SystemUIAppComponentFactory;
+import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback;
+import com.android.systemui.SystemUIAppComponentFactoryBase.ContextInitializer;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.shared.system.PeopleProviderUtils;
@@ -37,11 +38,11 @@ import javax.inject.Inject;
/** API that returns a People Tile preview. */
public class PeopleProvider extends ContentProvider implements
- SystemUIAppComponentFactory.ContextInitializer {
+ ContextInitializer {
private static final String TAG = "PeopleProvider";
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private static final String EMPTY_STRING = "";
- private SystemUIAppComponentFactory.ContextAvailableCallback mCallback;
+ private ContextAvailableCallback mCallback;
@Inject
PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
@@ -144,7 +145,7 @@ public class PeopleProvider extends ContentProvider implements
@Override
public void setContextAvailableCallback(
- SystemUIAppComponentFactory.ContextAvailableCallback callback) {
+ ContextAvailableCallback callback) {
mCallback = callback;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index ccec80db3ea5..86d4fa3002fc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -56,7 +56,6 @@ import dagger.Lazy;
/** Quick settings tile: Airplane mode **/
public class AirplaneModeTile extends QSTileImpl<BooleanState> {
- private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane);
private final SettingObserver mSetting;
private final BroadcastDispatcher mBroadcastDispatcher;
private final Lazy<ConnectivityManager> mLazyConnectivityManager;
@@ -129,11 +128,8 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> {
final boolean airplaneMode = value != 0;
state.value = airplaneMode;
state.label = mContext.getString(R.string.airplane_mode);
- state.icon = mIcon;
- if (state.slash == null) {
- state.slash = new SlashState();
- }
- state.slash.isSlashed = !airplaneMode;
+ state.icon = ResourceIcon.get(state.value
+ ? R.drawable.qs_airplane_icon_on : R.drawable.qs_airplane_icon_off);
state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.contentDescription = state.label;
state.expandedAccessibilityClassName = Switch.class.getName();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 1004fcae3827..ee49b294dfcd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -57,8 +57,6 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
private boolean mCharging;
private boolean mPluggedIn;
- private Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_battery_saver);
-
@Inject
public BatterySaverTile(
QSHost host,
@@ -145,7 +143,9 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
protected void handleUpdateState(BooleanState state, Object arg) {
state.state = mPluggedIn ? Tile.STATE_UNAVAILABLE
: mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
- state.icon = mIcon;
+ state.icon = ResourceIcon.get(mPowerSave
+ ? R.drawable.qs_battery_saver_icon_on
+ : R.drawable.qs_battery_saver_icon_off);
state.label = mContext.getString(R.string.battery_detail_switch_title);
state.secondaryLabel = "";
state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
index fa2d4447f26d..ee41f1d1077d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java
@@ -72,9 +72,9 @@ public class CameraToggleTile extends SensorPrivacyToggleTile {
@Override
public @DrawableRes int getIconRes(boolean isBlocked) {
if (isBlocked) {
- return com.android.internal.R.drawable.ic_camera_blocked;
+ return R.drawable.qs_camera_access_icon_off;
} else {
- return com.android.internal.R.drawable.ic_camera_allowed;
+ return R.drawable.qs_camera_access_icon_on;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 3dcfbc04c463..8b7f53fa5a3f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -226,16 +226,15 @@ public class DndTile extends QSTileImpl<BooleanState> {
if (mController == null) return;
final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
final boolean newValue = zen != ZEN_MODE_OFF;
- final boolean valueChanged = state.value != newValue;
- if (state.slash == null) state.slash = new SlashState();
state.dualTarget = true;
state.value = newValue;
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
- state.slash.isSlashed = !state.value;
+ state.icon = ResourceIcon.get(state.value
+ ? R.drawable.qs_dnd_icon_on
+ : R.drawable.qs_dnd_icon_off);
state.label = getTileLabel();
state.secondaryLabel = TextUtils.emptyIfNull(ZenModeConfig.getDescription(mContext,
zen != Global.ZEN_MODE_OFF, mController.getConfig(), false));
- state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd);
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
// Keeping the secondaryLabel in contentDescription instead of stateDescription is easier
// to understand.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index fc93f44a44aa..9466a694ea1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -48,8 +48,6 @@ import javax.inject.Inject;
/** Quick settings tile: Location **/
public class LocationTile extends QSTileImpl<BooleanState> {
- private final Icon mIcon = ResourceIcon.get(R.drawable.ic_location);
-
private final LocationController mController;
private final KeyguardStateController mKeyguard;
private final Callback mCallback = new Callback();
@@ -119,8 +117,8 @@ public class LocationTile extends QSTileImpl<BooleanState> {
if (state.disabledByPolicy == false) {
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_LOCATION);
}
- state.icon = mIcon;
- state.slash.isSlashed = !state.value;
+ state.icon = ResourceIcon.get(state.value
+ ? R.drawable.qs_location_icon_on : R.drawable.qs_location_icon_off);
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = state.label;
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
index f4f0b2cdc432..e54709562c10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java
@@ -72,9 +72,9 @@ public class MicrophoneToggleTile extends SensorPrivacyToggleTile {
@Override
public @DrawableRes int getIconRes(boolean isBlocked) {
if (isBlocked) {
- return com.android.internal.R.drawable.ic_mic_blocked;
+ return R.drawable.qs_mic_access_off;
} else {
- return com.android.internal.R.drawable.ic_mic_allowed;
+ return R.drawable.qs_mic_access_on;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
new file mode 100644
index 000000000000..aa218dbfdd43
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.settings
+
+import android.content.Context
+import android.content.SharedPreferences
+import java.io.File
+
+/**
+ * Interface for retrieving file paths for file storage of system and secondary users.
+ */
+interface UserFileManager {
+ /**
+ * Return the file based on current user.
+ */
+ fun getFile(fileName: String, userId: Int): File
+ /**
+ * Get shared preferences from user.
+ */
+ fun getSharedPreferences(
+ fileName: String,
+ @Context.PreferencesMode mode: Int,
+ userId: Int
+ ): SharedPreferences
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
new file mode 100644
index 000000000000..8c8f54fe9c3d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.settings
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.SharedPreferences
+import android.os.Environment
+import android.os.UserHandle
+import android.os.UserManager
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.CoreStartable
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.concurrency.DelayableExecutor
+import java.io.File
+import javax.inject.Inject
+
+/**
+ * Implementation for retrieving file paths for file storage of system and secondary users.
+ * Files lie in {File Directory}/UserFileManager/{User Id} for secondary user.
+ * For system user, we use the conventional {File Directory}
+ */
+@SysUISingleton
+class UserFileManagerImpl @Inject constructor(
+ // Context of system process and system user.
+ val context: Context,
+ val userManager: UserManager,
+ val broadcastDispatcher: BroadcastDispatcher,
+ @Background val backgroundExecutor: DelayableExecutor
+) : UserFileManager, CoreStartable(context) {
+ companion object {
+ private const val FILES = "files"
+ private const val SHARED_PREFS = "shared_prefs"
+ internal const val ID = "UserFileManager"
+ }
+
+ private val broadcastReceiver = object : BroadcastReceiver() {
+ /**
+ * Listen to Intent.ACTION_USER_REMOVED to clear user data.
+ */
+ override fun onReceive(context: Context, intent: Intent) {
+ if (intent.action == Intent.ACTION_USER_REMOVED) {
+ clearDeletedUserData()
+ }
+ }
+ }
+
+ /**
+ * Poll for user-specific directories to delete upon start up.
+ */
+ override fun start() {
+ clearDeletedUserData()
+ val filter = IntentFilter().apply {
+ addAction(Intent.ACTION_USER_REMOVED)
+ }
+ broadcastDispatcher.registerReceiver(broadcastReceiver, filter, backgroundExecutor)
+ }
+
+ /**
+ * Return the file based on current user.
+ */
+ override fun getFile(fileName: String, userId: Int): File {
+ return if (UserHandle(userId).isSystem) {
+ Environment.buildPath(
+ context.filesDir,
+ fileName
+ )
+ } else {
+ Environment.buildPath(
+ context.filesDir,
+ ID,
+ userId.toString(),
+ FILES,
+ fileName
+ )
+ }
+ }
+
+ /**
+ * Get shared preferences from user.
+ */
+ override fun getSharedPreferences(
+ fileName: String,
+ @Context.PreferencesMode mode: Int,
+ userId: Int
+ ): SharedPreferences {
+ if (UserHandle(userId).isSystem) {
+ return context.getSharedPreferences(fileName, mode)
+ }
+ val secondaryUserDir = Environment.buildPath(
+ context.filesDir,
+ ID,
+ userId.toString(),
+ SHARED_PREFS,
+ fileName
+ )
+
+ return context.getSharedPreferences(secondaryUserDir, mode)
+ }
+
+ /**
+ * Remove dirs for deleted users.
+ */
+ @VisibleForTesting
+ internal fun clearDeletedUserData() {
+ backgroundExecutor.execute {
+ val file = Environment.buildPath(context.filesDir, ID)
+ if (!file.exists()) return@execute
+ val aliveUsers = userManager.aliveUsers.map { it.id.toString() }
+ val dirsToDelete = file.list().filter { !aliveUsers.contains(it) }
+
+ dirsToDelete.forEach { dir ->
+ try {
+ val dirToDelete = Environment.buildPath(
+ file,
+ dir,
+ )
+ dirToDelete.deleteRecursively()
+ } catch (e: Exception) {
+ Log.e(ID, "Deletion failed.", e)
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java
index 7084d3ffc9ff..2f62e44ba4c4 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/MultiUserUtilsModule.java
@@ -21,25 +21,28 @@ import android.content.Context;
import android.os.Handler;
import android.os.UserManager;
+import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.settings.UserContentResolverProvider;
import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.settings.UserFileManager;
+import com.android.systemui.settings.UserFileManagerImpl;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.settings.UserTrackerImpl;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
/**
* Dagger Module for classes found within the com.android.systemui.settings package.
*/
@Module
-public abstract class SettingsModule {
-
-
+public abstract class MultiUserUtilsModule {
@Binds
@SysUISingleton
abstract UserContextProvider bindUserContextProvider(UserTracker tracker);
@@ -62,4 +65,12 @@ public abstract class SettingsModule {
tracker.initialize(startingUser);
return tracker;
}
+
+ @Binds
+ @IntoMap
+ @ClassKey(UserFileManagerImpl.class)
+ abstract CoreStartable bindUserFileManagerCoreStartable(UserFileManagerImpl sysui);
+
+ @Binds
+ abstract UserFileManager bindUserFileManager(UserFileManagerImpl impl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 9e029095ea6b..ca147286a301 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -900,16 +900,36 @@ public class KeyguardIndicationController {
mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
}
} else {
- if (!mAccessibilityManager.isEnabled()
- && !mAccessibilityManager.isTouchExplorationEnabled()
- && mKeyguardUpdateMonitor.isUdfpsSupported()
- && mKeyguardUpdateMonitor.getUserCanSkipBouncer(
- KeyguardUpdateMonitor.getCurrentUser())) {
- final int stringId = mKeyguardUpdateMonitor.getIsFaceAuthenticated()
- ? R.string.keyguard_face_successful_unlock_press
- : R.string.keyguard_unlock_press;
- showBiometricMessage(mContext.getString(stringId));
+ final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer(
+ KeyguardUpdateMonitor.getCurrentUser());
+ if (canSkipBouncer) {
+ final boolean faceAuthenticated = mKeyguardUpdateMonitor.getIsFaceAuthenticated();
+ final boolean udfpsSupported = mKeyguardUpdateMonitor.isUdfpsSupported();
+ final boolean a11yEnabled = mAccessibilityManager.isEnabled()
+ || mAccessibilityManager.isTouchExplorationEnabled();
+ if (udfpsSupported && faceAuthenticated) { // co-ex
+ if (a11yEnabled) {
+ showBiometricMessage(mContext.getString(
+ R.string.keyguard_face_successful_unlock_swipe));
+ } else {
+ showBiometricMessage(mContext.getString(
+ R.string.keyguard_face_successful_unlock_press));
+ }
+ } else if (faceAuthenticated) { // face-only
+ showBiometricMessage(mContext.getString(
+ R.string.keyguard_face_successful_unlock_swipe));
+ } else if (udfpsSupported) { // udfps-only
+ if (a11yEnabled) {
+ showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+ } else {
+ showBiometricMessage(mContext.getString(
+ R.string.keyguard_unlock_press));
+ }
+ } else { // no security or unlocked by a trust agent
+ showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
+ }
} else {
+ // suggest swiping up for the primary authentication bouncer
showBiometricMessage(mContext.getString(R.string.keyguard_unlock));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 587c23b39dd3..9e77dbc08c7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -68,6 +68,7 @@ import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBarIconList;
import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallFlags;
@@ -256,6 +257,16 @@ public interface CentralSurfacesDependenciesModule {
*/
@Provides
@SysUISingleton
+ static StatusBarIconList provideStatusBarIconList(Context context) {
+ return new StatusBarIconList(
+ context.getResources().getStringArray(
+ com.android.internal.R.array.config_statusBarIcons));
+ }
+
+ /**
+ */
+ @Provides
+ @SysUISingleton
static OngoingCallController provideOngoingCallController(
Context context,
CommonNotifCollection notifCollection,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
index a57440c95271..f662a040fae6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.notification.collection
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.NotifPipelineFlags
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener
@@ -250,4 +249,4 @@ class NotifPipeline @Inject constructor(
fun getInternalNotifUpdater(name: String?): InternalNotifUpdater {
return mNotifCollection.getInternalNotifUpdater(name)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
index 5a281b130347..657c394d4e30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
@@ -145,4 +145,4 @@ class ViewConfigCoordinator @Inject internal constructor(
private const val TAG = "ViewConfigCoordinator"
private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
index 7dd3672a6e30..a7719d3d82a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
@@ -23,6 +23,7 @@ import android.service.notification.NotificationStats;
import androidx.annotation.NonNull;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
@@ -33,10 +34,13 @@ import com.android.systemui.statusbar.notification.collection.render.Notificatio
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import javax.inject.Inject;
+
/**
* Callback for when a user interacts with a {@see ExpandableNotificationRow}. Sends relevant
* information about the interaction to the notification pipeline.
*/
+@SysUISingleton
public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback {
private final NotificationVisibilityProvider mVisibilityProvider;
private final NotifCollection mNotifCollection;
@@ -44,6 +48,7 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback
private final StatusBarStateController mStatusBarStateController;
private final VisualStabilityCoordinator mVisualStabilityCoordinator;
+ @Inject
public OnUserInteractionCallbackImpl(
NotificationVisibilityProvider visibilityProvider,
NotifCollection notifCollection,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
deleted file mode 100644
index bdbb0eb48e8a..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.legacy;
-
-import static com.android.systemui.statusbar.phone.CentralSurfaces.SPEW;
-
-import android.service.notification.StatusBarNotification;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.inject.Inject;
-
-/**
- * This is some logic extracted from the
- * {@link com.android.systemui.statusbar.phone.StatusBarNotificationPresenter}
- * into a class that implements a new-pipeline interface so that the new pipeline can implement it
- * correctly.
- *
- * Specifically, this is the logic which updates notifications when uiMode and screen properties
- * change, and which closes the shade when the last notification disappears.
- */
-public class LegacyNotificationPresenterExtensions implements NotifShadeEventSource {
- private static final String TAG = "LegacyNotifPresenter";
- private final NotificationEntryManager mEntryManager;
- private boolean mEntryListenerAdded;
- private Runnable mShadeEmptiedCallback;
- private Runnable mNotifRemovedByUserCallback;
-
- @Inject
- public LegacyNotificationPresenterExtensions(NotificationEntryManager entryManager) {
- mEntryManager = entryManager;
- }
-
- private void ensureEntryListenerAdded() {
- if (mEntryListenerAdded) return;
- mEntryListenerAdded = true;
- mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
- @Override
- public void onEntryRemoved(
- @NotNull NotificationEntry entry,
- NotificationVisibility visibility,
- boolean removedByUser,
- int reason) {
- StatusBarNotification old = entry.getSbn();
- if (SPEW) {
- Log.d(TAG, "removeNotification key=" + entry.getKey()
- + " old=" + old + " reason=" + reason);
- }
-
- if (old != null && !mEntryManager.hasActiveNotifications()) {
- if (mShadeEmptiedCallback != null) mShadeEmptiedCallback.run();
- }
- if (removedByUser) {
- if (mNotifRemovedByUserCallback != null) mNotifRemovedByUserCallback.run();
- }
- }
- });
- }
-
- @Override
- public void setNotifRemovedByUserCallback(@NonNull Runnable callback) {
- if (mNotifRemovedByUserCallback != null) {
- throw new IllegalStateException("mNotifRemovedByUserCallback already set");
- }
- mNotifRemovedByUserCallback = callback;
- ensureEntryListenerAdded();
- }
-
- @Override
- public void setShadeEmptiedCallback(@NonNull Runnable callback) {
- if (mShadeEmptiedCallback != null) {
- throw new IllegalStateException("mShadeEmptiedCallback already set");
- }
- mShadeEmptiedCallback = callback;
- ensureEntryListenerAdded();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
deleted file mode 100644
index 103b14b09e9c..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.legacy;
-
-import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
-
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationStats;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
-import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-
-/**
- * Callback for when a user interacts with a {@see ExpandableNotificationRow}.
- */
-public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCallback {
- private final NotificationEntryManager mNotificationEntryManager;
- private final NotificationVisibilityProvider mVisibilityProvider;
- private final HeadsUpManager mHeadsUpManager;
- private final StatusBarStateController mStatusBarStateController;
- private final VisualStabilityManager mVisualStabilityManager;
- private final GroupMembershipManager mGroupMembershipManager;
-
- public OnUserInteractionCallbackImplLegacy(
- NotificationEntryManager notificationEntryManager,
- NotificationVisibilityProvider visibilityProvider,
- HeadsUpManager headsUpManager,
- StatusBarStateController statusBarStateController,
- VisualStabilityManager visualStabilityManager,
- GroupMembershipManager groupMembershipManager
- ) {
- mNotificationEntryManager = notificationEntryManager;
- mVisibilityProvider = visibilityProvider;
- mHeadsUpManager = headsUpManager;
- mStatusBarStateController = statusBarStateController;
- mVisualStabilityManager = visualStabilityManager;
- mGroupMembershipManager = groupMembershipManager;
- }
-
- /**
- * Callback triggered when a user:
- * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
- * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
- * {@see StatusBarNotificationActivityStarter}
- *
- * @param groupSummaryToDismiss the group summary that should be dismissed
- * along with this dismissal. If null, does not additionally
- * dismiss any notifications.
- */
- private void onDismiss(
- NotificationEntry entry,
- @NotificationListenerService.NotificationCancelReason int cancellationReason,
- @Nullable NotificationEntry groupSummaryToDismiss
- ) {
- int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
- if (mHeadsUpManager.isAlerting(entry.getKey())) {
- dismissalSurface = NotificationStats.DISMISSAL_PEEK;
- } else if (mStatusBarStateController.isDozing()) {
- dismissalSurface = NotificationStats.DISMISSAL_AOD;
- }
-
- if (groupSummaryToDismiss != null) {
- onDismiss(groupSummaryToDismiss, cancellationReason, null);
- }
-
- mNotificationEntryManager.performRemoveNotification(
- entry.getSbn(),
- new DismissedByUserStats(
- dismissalSurface,
- DISMISS_SENTIMENT_NEUTRAL,
- mVisibilityProvider.obtain(entry, true)),
- cancellationReason
- );
-
- }
-
- @Override
- public void onImportanceChanged(NotificationEntry entry) {
- mVisualStabilityManager.temporarilyAllowReordering();
- }
-
- /**
- * @param entry that is being dismissed
- * @return the group summary to dismiss along with this entry if this is the last entry in
- * the group. Else, returns null.
- */
- @Nullable
- private NotificationEntry getGroupSummaryToDismiss(NotificationEntry entry) {
- if (mGroupMembershipManager.isOnlyChildInGroup(entry)) {
- NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry);
- return groupSummary.isDismissable() ? groupSummary : null;
- }
- return null;
- }
-
- @Override
- @NonNull
- public Runnable registerFutureDismissal(@NonNull NotificationEntry entry,
- @CancellationReason int cancellationReason) {
- NotificationEntry groupSummaryToDismiss = getGroupSummaryToDismiss(entry);
- return () -> onDismiss(entry, cancellationReason, groupSummaryToDismiss);
- }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
index 6a1e36f4f469..ec10aaf3cfe3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.provider
import com.android.internal.statusbar.NotificationVisibility
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -25,6 +26,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationLogger
import javax.inject.Inject
/** pipeline-agnostic implementation for getting [NotificationVisibility]. */
+@SysUISingleton
class NotificationVisibilityProviderImpl @Inject constructor(
private val notifDataStore: NotifLiveDataStore,
private val notifCollection: CommonNotifCollection
@@ -46,4 +48,4 @@ class NotificationVisibilityProviderImpl @Inject constructor(
NotificationLogger.getNotificationLocation(notifCollection.getEntry(key))
private fun getCount() = notifDataStore.activeNotifCount.value
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index a2cb9509a621..1b3f83d1892f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.collection.render;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -28,10 +29,13 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
+import javax.inject.Inject;
+
/**
* Provides grouping information for notification entries including information about a group's
* expanded state.
*/
+@SysUISingleton
public class GroupExpansionManagerImpl implements GroupExpansionManager, Coordinator {
private final GroupMembershipManager mGroupMembershipManager;
private final Set<OnGroupExpansionChangeListener> mOnGroupChangeListeners = new HashSet<>();
@@ -39,6 +43,7 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Coordin
// Set of summary keys whose groups are expanded
private final Set<NotificationEntry> mExpandedGroups = new HashSet<>();
+ @Inject
public GroupExpansionManagerImpl(GroupMembershipManager groupMembershipManager) {
mGroupMembershipManager = groupMembershipManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 27a7cd779405..d838252aa362 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -41,23 +41,19 @@ import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
-import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotifPipelineChoreographerModule;
import com.android.systemui.statusbar.notification.collection.coordinator.ShadeEventCoordinator;
-import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorsModule;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManagerImpl;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
-import com.android.systemui.statusbar.notification.collection.legacy.LegacyNotificationPresenterExtensions;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
-import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
@@ -90,7 +86,6 @@ import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotifPanelEventsModule;
import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.wmshell.BubblesManager;
@@ -116,12 +111,10 @@ import dagger.Provides;
})
public interface NotificationsModule {
@Binds
- StackScrollAlgorithm.SectionProvider bindSectionProvider(
- NotificationSectionsManager impl);
+ StackScrollAlgorithm.SectionProvider bindSectionProvider(NotificationSectionsManager impl);
@Binds
- StackScrollAlgorithm.BypassController bindBypassController(
- KeyguardBypassController impl);
+ StackScrollAlgorithm.BypassController bindBypassController(KeyguardBypassController impl);
/** Provides an instance of {@link NotificationEntryManager} */
@SysUISingleton
@@ -194,12 +187,8 @@ public interface NotificationsModule {
}
/** Provides an instance of {@link NotifGutsViewManager} */
- @SysUISingleton
- @Provides
- static NotifGutsViewManager provideNotifGutsViewManager(
- NotificationGutsManager notificationGutsManager) {
- return notificationGutsManager;
- }
+ @Binds
+ NotifGutsViewManager bindNotifGutsViewManager(NotificationGutsManager notificationGutsManager);
/** Provides an instance of {@link VisualStabilityManager} */
@SysUISingleton
@@ -253,25 +242,13 @@ public interface NotificationsModule {
/** Provides an instance of {@link GroupMembershipManager} */
@SysUISingleton
@Provides
- static GroupMembershipManager provideGroupMembershipManager(
- NotifPipelineFlags notifPipelineFlags,
- Lazy<NotificationGroupManagerLegacy> groupManagerLegacy) {
- return notifPipelineFlags.isNewPipelineEnabled()
- ? new GroupMembershipManagerImpl()
- : groupManagerLegacy.get();
+ static GroupMembershipManager provideGroupMembershipManager() {
+ return new GroupMembershipManagerImpl();
}
/** Provides an instance of {@link GroupExpansionManager} */
- @SysUISingleton
- @Provides
- static GroupExpansionManager provideGroupExpansionManager(
- NotifPipelineFlags notifPipelineFlags,
- Lazy<GroupMembershipManager> groupMembershipManager,
- Lazy<NotificationGroupManagerLegacy> groupManagerLegacy) {
- return notifPipelineFlags.isNewPipelineEnabled()
- ? new GroupExpansionManagerImpl(groupMembershipManager.get())
- : groupManagerLegacy.get();
- }
+ @Binds
+ GroupExpansionManager provideGroupExpansionManager(GroupExpansionManagerImpl impl);
/** Initializes the notification data pipeline (can be disabled via config). */
@SysUISingleton
@@ -290,69 +267,28 @@ public interface NotificationsModule {
/**
* Provide the active notification collection managing the notifications to render.
*/
- @Provides
- @SysUISingleton
- static CommonNotifCollection provideCommonNotifCollection(
- NotifPipelineFlags notifPipelineFlags,
- Lazy<NotifPipeline> pipeline,
- NotificationEntryManager entryManager) {
- return notifPipelineFlags.isNewPipelineEnabled()
- ? pipeline.get() : entryManager;
- }
+ @Binds
+ CommonNotifCollection provideCommonNotifCollection(NotifPipeline pipeline);
/**
* Provide the object which can be used to obtain NotificationVisibility objects.
*/
@Binds
- @SysUISingleton
NotificationVisibilityProvider provideNotificationVisibilityProvider(
- NotificationVisibilityProviderImpl newProvider);
+ NotificationVisibilityProviderImpl impl);
/**
* Provide the active implementation for presenting notifications.
*/
- @Provides
- @SysUISingleton
- static NotifShadeEventSource provideNotifShadeEventSource(
- NotifPipelineFlags notifPipelineFlags,
- Lazy<ShadeEventCoordinator> shadeEventCoordinatorLazy,
- Lazy<LegacyNotificationPresenterExtensions> legacyNotificationPresenterExtensionsLazy) {
- return notifPipelineFlags.isNewPipelineEnabled()
- ? shadeEventCoordinatorLazy.get()
- : legacyNotificationPresenterExtensionsLazy.get();
- }
+ @Binds
+ NotifShadeEventSource provideNotifShadeEventSource(ShadeEventCoordinator shadeEventCoordinator);
/**
* Provide a dismissal callback that's triggered when a user manually dismissed a notification
* from the notification shade or it gets auto-cancelled by click.
*/
- @Provides
- @SysUISingleton
- static OnUserInteractionCallback provideOnUserInteractionCallback(
- NotifPipelineFlags notifPipelineFlags,
- HeadsUpManager headsUpManager,
- StatusBarStateController statusBarStateController,
- Lazy<NotifCollection> notifCollection,
- Lazy<NotificationVisibilityProvider> visibilityProvider,
- Lazy<VisualStabilityCoordinator> visualStabilityCoordinator,
- NotificationEntryManager entryManager,
- VisualStabilityManager visualStabilityManager,
- Lazy<GroupMembershipManager> groupMembershipManagerLazy) {
- return notifPipelineFlags.isNewPipelineEnabled()
- ? new OnUserInteractionCallbackImpl(
- visibilityProvider.get(),
- notifCollection.get(),
- headsUpManager,
- statusBarStateController,
- visualStabilityCoordinator.get())
- : new OnUserInteractionCallbackImplLegacy(
- entryManager,
- visibilityProvider.get(),
- headsUpManager,
- statusBarStateController,
- visualStabilityManager,
- groupMembershipManagerLazy.get());
- }
+ @Binds
+ OnUserInteractionCallback provideOnUserInteractionCallback(OnUserInteractionCallbackImpl impl);
/** */
@Binds
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 2fd02d9f1cd9..defae5b6941f 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
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.stack;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL;
import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
import static com.android.systemui.util.DumpUtilsKt.println;
@@ -5246,6 +5247,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
setClearAllInProgress(true);
mShadeNeedsToClose = closeShade;
+ InteractionJankMonitor.getInstance().begin(this, CUJ_SHADE_CLEAR_ALL);
// Decrease the delay for every row we animate to give the sense of
// accelerating the swipes
final int rowDelayDecrement = 5;
@@ -6158,6 +6160,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private void onClearAllAnimationsEnd(
List<ExpandableNotificationRow> viewsToRemove,
@SelectedRows int selectedRows) {
+ InteractionJankMonitor.getInstance().end(CUJ_SHADE_CLEAR_ALL);
if (mClearAllAnimationListener != null) {
mClearAllAnimationListener.onAnimationEnd(viewsToRemove, selectedRows);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index b302ba6711f4..8d3ee74753dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -28,7 +28,6 @@ import static com.android.systemui.statusbar.notification.stack.NotificationStac
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows;
-import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.canChildBeCleared;
import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
import android.content.res.Configuration;
@@ -38,12 +37,10 @@ import android.graphics.PointF;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -53,20 +50,17 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.ExpandHelper;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.KeyguardMediaController;
@@ -85,9 +79,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -165,13 +157,10 @@ public class NotificationStackScrollLayoutController {
private final Resources mResources;
private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
private final ScrimController mScrimController;
- private final NotifPipelineFlags mNotifPipelineFlags;
private final NotifPipeline mNotifPipeline;
private final NotifCollection mNotifCollection;
private final NotificationEntryManager mNotificationEntryManager;
- private final IStatusBarService mIStatusBarService;
private final UiEventLogger mUiEventLogger;
- private final LayoutInflater mLayoutInflater;
private final NotificationRemoteInputManager mRemoteInputManager;
private final VisualStabilityManager mVisualStabilityManager;
private final ShadeController mShadeController;
@@ -208,8 +197,6 @@ public class NotificationStackScrollLayoutController {
@Nullable
private NotificationActivityStarter mNotificationActivityStarter;
- private ColorExtractor.OnColorsChangedListener mOnColorsChangedListener;
-
@VisibleForTesting
final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
new View.OnAttachStateChangeListener() {
@@ -258,10 +245,7 @@ public class NotificationStackScrollLayoutController {
mView.setAnimateBottomOnLayout(true);
}
// Let's update the footer once the notifications have been updated (in the next frame)
- mView.post(() -> {
- updateFooter();
- updateSectionBoundaries("dynamic privacy changed");
- });
+ mView.post(this::updateFooter);
};
@VisibleForTesting
@@ -636,7 +620,6 @@ public class NotificationStackScrollLayoutController {
KeyguardMediaController keyguardMediaController,
KeyguardBypassController keyguardBypassController,
ZenModeController zenModeController,
- SysuiColorExtractor colorExtractor,
NotificationLockscreenUserManager lockscreenUserManager,
MetricsLogger metricsLogger,
DumpManager dumpManager,
@@ -649,15 +632,12 @@ public class NotificationStackScrollLayoutController {
NotificationGroupManagerLegacy legacyGroupManager,
GroupExpansionManager groupManager,
@SilentHeader SectionHeaderController silentHeaderController,
- NotifPipelineFlags notifPipelineFlags,
NotifPipeline notifPipeline,
NotifCollection notifCollection,
NotificationEntryManager notificationEntryManager,
LockscreenShadeTransitionController lockscreenShadeTransitionController,
ShadeTransitionController shadeTransitionController,
- IStatusBarService iStatusBarService,
UiEventLogger uiEventLogger,
- LayoutInflater layoutInflater,
NotificationRemoteInputManager remoteInputManager,
VisualStabilityManager visualStabilityManager,
ShadeController shadeController,
@@ -700,14 +680,11 @@ public class NotificationStackScrollLayoutController {
mCentralSurfaces.requestNotificationUpdate("onGroupsChanged");
}
});
- mNotifPipelineFlags = notifPipelineFlags;
mSilentHeaderController = silentHeaderController;
mNotifPipeline = notifPipeline;
mNotifCollection = notifCollection;
mNotificationEntryManager = notificationEntryManager;
- mIStatusBarService = iStatusBarService;
mUiEventLogger = uiEventLogger;
- mLayoutInflater = layoutInflater;
mRemoteInputManager = remoteInputManager;
mVisualStabilityManager = visualStabilityManager;
mShadeController = shadeController;
@@ -747,21 +724,12 @@ public class NotificationStackScrollLayoutController {
.setOnMenuEventListener(mMenuEventListener)
.build();
- if (mNotifPipelineFlags.isNewPipelineEnabled()) {
- mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
- @Override
- public void onEntryUpdated(NotificationEntry entry) {
- mView.onEntryUpdated(entry);
- }
- });
- } else {
- mNotificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
- @Override
- public void onPreEntryUpdated(NotificationEntry entry) {
- mView.onEntryUpdated(entry);
- }
- });
- }
+ mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
+ @Override
+ public void onEntryUpdated(NotificationEntry entry) {
+ mView.onEntryUpdated(entry);
+ }
+ });
mView.initView(mView.getContext(), mSwipeHelper, mNotificationStackSizeCalculator);
mView.setKeyguardBypassEnabled(mKeyguardBypassController.getBypassEnabled());
@@ -1233,10 +1201,6 @@ public class NotificationStackScrollLayoutController {
Trace.endSection();
}
- public boolean areNotificationsHiddenInShade() {
- return mZenModeController.areNotificationsHiddenInShade();
- }
-
public boolean isShowingEmptyShadeView() {
return mShowEmptyShadeView;
}
@@ -1341,15 +1305,6 @@ public class NotificationStackScrollLayoutController {
};
}
- public void updateSectionBoundaries(String reason) {
- if (mNotifPipelineFlags.isNewPipelineEnabled()) {
- return;
- }
- Trace.beginSection("NSSLC.updateSectionBoundaries");
- mView.updateSectionBoundaries(reason);
- Trace.endSection();
- }
-
public void updateFooter() {
Trace.beginSection("NSSLC.updateFooter");
mView.updateFooter();
@@ -1465,39 +1420,18 @@ public class NotificationStackScrollLayoutController {
private void onAnimationEnd(List<ExpandableNotificationRow> viewsToRemove,
@SelectedRows int selectedRows) {
- if (mNotifPipelineFlags.isNewPipelineEnabled()) {
- if (selectedRows == ROWS_ALL) {
- mNotifCollection.dismissAllNotifications(
- mLockscreenUserManager.getCurrentUserId());
- } else {
- final List<Pair<NotificationEntry, DismissedByUserStats>>
- entriesWithRowsDismissedFromShade = new ArrayList<>();
- for (ExpandableNotificationRow row : viewsToRemove) {
- final NotificationEntry entry = row.getEntry();
- entriesWithRowsDismissedFromShade.add(
- new Pair<>(entry, getDismissedByUserStats(entry)));
- }
- mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
- }
+ if (selectedRows == ROWS_ALL) {
+ mNotifCollection.dismissAllNotifications(
+ mLockscreenUserManager.getCurrentUserId());
} else {
- for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
- if (canChildBeCleared(rowToRemove)) {
- mNotificationEntryManager.performRemoveNotification(
- rowToRemove.getEntry().getSbn(),
- getDismissedByUserStats(rowToRemove.getEntry()),
- NotificationListenerService.REASON_CANCEL_ALL);
- } else {
- rowToRemove.resetTranslation();
- }
- }
- if (selectedRows == ROWS_ALL) {
- try {
- // TODO(b/169585328): Do not clear media player notifications
- mIStatusBarService.onClearAllNotifications(
- mLockscreenUserManager.getCurrentUserId());
- } catch (Exception ignored) {
- }
+ final List<Pair<NotificationEntry, DismissedByUserStats>>
+ entriesWithRowsDismissedFromShade = new ArrayList<>();
+ for (ExpandableNotificationRow row : viewsToRemove) {
+ final NotificationEntry entry = row.getEntry();
+ entriesWithRowsDismissedFromShade.add(
+ new Pair<>(entry, getDismissedByUserStats(entry)));
}
+ mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index b7a605a793bb..9b07d54c7b52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -265,9 +265,6 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
boolean isPulsing();
- @Nullable
- View getAmbientIndicationContainer();
-
boolean isOccluded();
//TODO: These can / should probably be moved to NotificationPresenter or ShadeController
@@ -560,8 +557,6 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
void setLaunchEmergencyActionOnFinishedWaking(boolean launch);
- void setTopHidesStatusBar(boolean hides);
-
QSPanelController getQSPanelController();
boolean areNotificationAlertsDisabled();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index f627c5bb9d02..a344e71a8134 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -147,7 +147,6 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.emergency.EmergencyGesture;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -197,7 +196,6 @@ import com.android.systemui.statusbar.PowerButtonReveal;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.core.StatusBarInitializer;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
@@ -206,7 +204,6 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -237,7 +234,6 @@ import com.android.systemui.util.WallpaperController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.MessageRouter;
import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
import com.android.wm.shell.startingsurface.StartingSurface;
@@ -291,7 +287,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
private static final UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
- private final DreamOverlayStateController mDreamOverlayStateController;
private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
private float mTransitionToFullShadeProgress = 0f;
private NotificationListContainer mNotifListContainer;
@@ -389,11 +384,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
}
@Override
- public void setTopHidesStatusBar(boolean hides) {
- mTopHidesStatusBar = hides;
- }
-
- @Override
public QSPanelController getQSPanelController() {
return mQSPanelController;
}
@@ -436,7 +426,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
private BiometricUnlockController mBiometricUnlockController;
private final LightBarController mLightBarController;
private final Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
- private final LockscreenGestureLogger mLockscreenGestureLogger;
@Nullable
protected LockscreenWallpaper mLockscreenWallpaper;
private final AutoHideController mAutoHideController;
@@ -503,9 +492,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
private boolean mExpandedVisible;
- private final int[] mAbsPos = new int[2];
-
- private final NotifShadeEventSource mNotifShadeEventSource;
protected final NotificationEntryManager mEntryManager;
private final NotificationGutsManager mGutsManager;
private final NotificationLogger mNotificationLogger;
@@ -587,7 +573,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
}
}
- private Handler mMainHandler;
private final DelayableExecutor mMainExecutor;
private int mInteractingWindows;
@@ -621,12 +606,9 @@ public class CentralSurfacesImpl extends CoreStartable implements
// Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
private int mLastLoggedStateFingerprint;
- private boolean mTopHidesStatusBar;
- private boolean mStatusBarWindowHidden;
private boolean mIsLaunchingActivityOverLockscreen;
private final UserSwitcherController mUserSwitcherController;
- private final NetworkController mNetworkController;
private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
protected final BatteryController mBatteryController;
protected boolean mPanelExpanded;
@@ -646,7 +628,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
protected NotificationPresenter mPresenter;
private NotificationActivityStarter mNotificationActivityStarter;
private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
- private final Optional<BubblesManager> mBubblesManagerOptional;
private final Optional<Bubbles> mBubblesOptional;
private final Bubbles.BubbleExpandListener mBubbleExpandListener;
private final Optional<StartingSurface> mStartingSurfaceOptional;
@@ -688,7 +669,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
FalsingManager falsingManager,
FalsingCollector falsingCollector,
BroadcastDispatcher broadcastDispatcher,
- NotifShadeEventSource notifShadeEventSource,
NotificationEntryManager notificationEntryManager,
NotificationGutsManager notificationGutsManager,
NotificationLogger notificationLogger,
@@ -703,13 +683,11 @@ public class CentralSurfacesImpl extends CoreStartable implements
NotificationLockscreenUserManager lockScreenUserManager,
NotificationRemoteInputManager remoteInputManager,
UserSwitcherController userSwitcherController,
- NetworkController networkController,
BatteryController batteryController,
SysuiColorExtractor colorExtractor,
ScreenLifecycle screenLifecycle,
WakefulnessLifecycle wakefulnessLifecycle,
SysuiStatusBarStateController statusBarStateController,
- Optional<BubblesManager> bubblesManagerOptional,
Optional<Bubbles> bubblesOptional,
VisualStabilityManager visualStabilityManager,
DeviceProvisionedController deviceProvisionedController,
@@ -721,7 +699,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
DozeParameters dozeParameters,
ScrimController scrimController,
Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
- LockscreenGestureLogger lockscreenGestureLogger,
Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
DozeServiceHost dozeServiceHost,
PowerManager powerManager,
@@ -754,7 +731,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
LockscreenShadeTransitionController lockscreenShadeTransitionController,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
- @Main Handler mainHandler,
@Main DelayableExecutor delayableExecutor,
@Main MessageRouter messageRouter,
WallpaperManager wallpaperManager,
@@ -763,7 +739,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
NotifPipelineFlags notifPipelineFlags,
InteractionJankMonitor jankMonitor,
DeviceStateManager deviceStateManager,
- DreamOverlayStateController dreamOverlayStateController,
WiredChargingRippleController wiredChargingRippleController,
IDreamManager dreamManager) {
super(context);
@@ -784,7 +759,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
mFalsingCollector = falsingCollector;
mFalsingManager = falsingManager;
mBroadcastDispatcher = broadcastDispatcher;
- mNotifShadeEventSource = notifShadeEventSource;
mEntryManager = notificationEntryManager;
mGutsManager = notificationGutsManager;
mNotificationLogger = notificationLogger;
@@ -799,13 +773,11 @@ public class CentralSurfacesImpl extends CoreStartable implements
mLockscreenUserManager = lockScreenUserManager;
mRemoteInputManager = remoteInputManager;
mUserSwitcherController = userSwitcherController;
- mNetworkController = networkController;
mBatteryController = batteryController;
mColorExtractor = colorExtractor;
mScreenLifecycle = screenLifecycle;
mWakefulnessLifecycle = wakefulnessLifecycle;
mStatusBarStateController = statusBarStateController;
- mBubblesManagerOptional = bubblesManagerOptional;
mBubblesOptional = bubblesOptional;
mVisualStabilityManager = visualStabilityManager;
mDeviceProvisionedController = deviceProvisionedController;
@@ -819,7 +791,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
mDozeParameters = dozeParameters;
mScrimController = scrimController;
mLockscreenWallpaperLazy = lockscreenWallpaperLazy;
- mLockscreenGestureLogger = lockscreenGestureLogger;
mScreenPinningRequest = screenPinningRequest;
mDozeScrimController = dozeScrimController;
mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
@@ -846,12 +817,10 @@ public class CentralSurfacesImpl extends CoreStartable implements
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mFeatureFlags = featureFlags;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
- mMainHandler = mainHandler;
mMainExecutor = delayableExecutor;
mMessageRouter = messageRouter;
mWallpaperManager = wallpaperManager;
mJankMonitor = jankMonitor;
- mDreamOverlayStateController = dreamOverlayStateController;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
mStartingSurfaceOptional = startingSurfaceOptional;
@@ -1181,9 +1150,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
- if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
- mHeadsUpManager.addListener(mVisualStabilityManager);
- }
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
createNavigationBar(result);
@@ -1468,12 +1434,16 @@ public class CentralSurfacesImpl extends CoreStartable implements
mPowerManager.wakeUp(
time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
- where.getLocationInWindow(mTmpInt2);
// NOTE, the incoming view can sometimes be the entire container... unsure if
// this location is valuable enough
- mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
- mTmpInt2[1] + where.getHeight() / 2);
+ if (where != null) {
+ where.getLocationInWindow(mTmpInt2);
+ mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
+ mTmpInt2[1] + where.getHeight() / 2);
+ } else {
+ mWakeUpTouchLocation = new PointF(-1, -1);
+ }
mFalsingCollector.onScreenOnFromTouch();
}
}
@@ -1871,12 +1841,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
return mDozeServiceHost.isPulsing();
}
- @androidx.annotation.Nullable
- @Override
- public View getAmbientIndicationContainer() {
- return mAmbientIndicationContainer;
- }
-
/**
* When the keyguard is showing and covered by a "showWhenLocked" activity it
* is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
@@ -2256,8 +2220,7 @@ public class CentralSurfacesImpl extends CoreStartable implements
public void updateBubblesVisibility() {
mBubblesOptional.ifPresent(bubbles -> bubbles.onStatusBarVisibilityChanged(
mStatusBarMode != MODE_LIGHTS_OUT
- && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT
- && !mStatusBarWindowHidden));
+ && mStatusBarMode != MODE_LIGHTS_OUT_TRANSPARENT));
}
void checkBarMode(@TransitionMode int mode, @WindowVisibleState int windowState,
@@ -2543,8 +2506,13 @@ public class CentralSurfacesImpl extends CoreStartable implements
callback.onActivityStarted(ActivityManager.START_CANCELED);
}
};
+ // Do not deferKeyguard when occluded because, when keyguard is occluded,
+ // we do not launch the activity until keyguard is done.
+ boolean occluded = mStatusBarKeyguardViewManager.isShowing()
+ && mStatusBarKeyguardViewManager.isOccluded();
+ boolean deferred = !occluded;
executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
- willLaunchResolverActivity, true /* deferred */, animate);
+ willLaunchResolverActivity, deferred /* deferred */, animate);
}
@Nullable
@@ -2704,7 +2672,8 @@ public class CentralSurfacesImpl extends CoreStartable implements
@Override
public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
boolean afterKeyguardGone) {
- if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
+ if (!action.willRunAnimationOnKeyguard()
+ && mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
&& mKeyguardStateController.canDismissLockScreen()
&& !mStatusBarStateController.leaveOpenOnKeyguardHide()
&& mDozeServiceHost.isPulsing()) {
@@ -3519,6 +3488,9 @@ public class CentralSurfacesImpl extends CoreStartable implements
setBouncerShowingForStatusBarComponents(bouncerShowing);
mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
+ if (mBouncerShowing) {
+ wakeUpIfDozing(SystemClock.uptimeMillis(), null, "BOUNCER_VISIBLE");
+ }
updateScrimController();
if (!mBouncerShowing) {
updatePanelExpansionForKeyguard();
@@ -4338,9 +4310,6 @@ public class CentralSurfacesImpl extends CoreStartable implements
Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
}
- if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
- mViewHierarchyManager.updateRowStates();
- }
mScreenPinningRequest.onConfigurationChanged();
}
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 a8913bfbefa6..ff3d122855d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -39,6 +39,7 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -62,6 +63,9 @@ import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
@@ -347,8 +351,17 @@ public class KeyguardBottomAreaView extends FrameLayout {
dozeTimeTick();
}
- public View getIndicationArea() {
- return mIndicationArea;
+ /**
+ * Returns a list of animators to use to animate the indication areas.
+ */
+ public List<ViewPropertyAnimator> getIndicationAreaAnimators() {
+ List<ViewPropertyAnimator> animators =
+ new ArrayList<>(mAmbientIndicationArea != null ? 2 : 1);
+ animators.add(mIndicationArea.animate());
+ if (mAmbientIndicationArea != null) {
+ animators.add(mAmbientIndicationArea.animate());
+ }
+ return animators;
}
@Override
@@ -418,9 +431,17 @@ public class KeyguardBottomAreaView extends FrameLayout {
}
/**
- * Sets the alpha of the indication areas and affordances, excluding the lock icon.
+ * Sets the alpha of various sub-components, for example the indication areas and bottom quick
+ * action buttons. Does not set the alpha of the lock icon.
*/
- public void setAffordanceAlpha(float alpha) {
+ public void setComponentAlphas(float alpha) {
+ setImportantForAccessibility(
+ alpha == 0f
+ ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+ : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ if (mAmbientIndicationArea != null) {
+ mAmbientIndicationArea.setAlpha(alpha);
+ }
mIndicationArea.setAlpha(alpha);
mWalletButton.setAlpha(alpha);
mQRCodeScannerButton.setAlpha(alpha);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 8e65541081aa..e63c383b010b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -266,6 +266,9 @@ public class KeyguardBouncer {
private void setVisibility(@View.Visibility int visibility) {
mContainer.setVisibility(visibility);
+ if (mKeyguardViewController != null) {
+ mKeyguardViewController.onBouncerVisibilityChanged(visibility);
+ }
dispatchVisibilityChanged();
}
@@ -397,10 +400,6 @@ public class KeyguardBouncer {
return mShowingSoon || mExpansion != EXPANSION_HIDDEN && mExpansion != EXPANSION_VISIBLE;
}
- public boolean getShowingSoon() {
- return mShowingSoon;
- }
-
/**
* @return {@code true} when bouncer's pre-hide animation already started but isn't completely
* hidden yet, {@code false} otherwise.
@@ -644,6 +643,10 @@ public class KeyguardBouncer {
public interface BouncerExpansionCallback {
/**
* Invoked when the bouncer expansion reaches {@link KeyguardBouncer#EXPANSION_VISIBLE}.
+ * This is NOT called each time the bouncer is shown, but rather only when the fully
+ * shown amount has changed based on the panel expansion. The bouncer's visibility
+ * can still change when the expansion amount hasn't changed.
+ * See {@link KeyguardBouncer#isShowing()} for the checks for the bouncer showing state.
*/
default void onFullyShown() {
}
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 dcc02b44806b..f3aef768a5bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -3183,14 +3183,7 @@ public final class NotificationPanelViewController extends PanelViewController {
getExpandedFraction());
float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction());
alpha *= mBottomAreaShadeAlpha;
- mKeyguardBottomArea.setAffordanceAlpha(alpha);
- mKeyguardBottomArea.setImportantForAccessibility(
- alpha == 0f ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
- : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
- View ambientIndicationContainer = mCentralSurfaces.getAmbientIndicationContainer();
- if (ambientIndicationContainer != null) {
- ambientIndicationContainer.setAlpha(alpha);
- }
+ mKeyguardBottomArea.setComponentAlphas(alpha);
mLockIconViewController.setAlpha(alpha);
}
@@ -3908,7 +3901,6 @@ public final class NotificationPanelViewController extends PanelViewController {
* {@link ShadeViewManager}.
*/
public void updateNotificationViews(String reason) {
- mNotificationStackScrollLayoutController.updateSectionBoundaries(reason);
mNotificationStackScrollLayoutController.updateFooter();
mNotificationIconAreaController.updateNotificationIcons(createVisibleEntriesList());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index a8da554d7e1f..905a5f943f0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -44,6 +44,8 @@ import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
+import androidx.lifecycle.ViewTreeLifecycleOwner;
+
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
@@ -52,6 +54,7 @@ import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.lifecycle.WindowAddedViewLifecycleOwner;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -241,6 +244,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
mWindowManager.addView(mNotificationShadeView, mLp);
+
+ // Set up and "inject" a LifecycleOwner bound to the Window-View relationship such that all
+ // views in the sub-tree rooted under this view can access the LifecycleOwner using
+ // ViewTreeLifecycleOwner.get(...).
+ if (ViewTreeLifecycleOwner.get(mNotificationShadeView) == null) {
+ ViewTreeLifecycleOwner.set(
+ mNotificationShadeView,
+ new WindowAddedViewLifecycleOwner(mNotificationShadeView));
+ }
+
mLpChanged.copyFrom(mLp);
onThemeChanged();
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 d2fc1af010b9..dabc52663a6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -41,6 +41,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
@@ -66,6 +67,7 @@ import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
import java.io.PrintWriter;
+import java.util.List;
public abstract class PanelViewController {
public static final boolean DEBUG = PanelView.DEBUG;
@@ -599,9 +601,7 @@ public abstract class PanelViewController {
float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
if (target == mExpandedHeight && mOverExpansion == 0.0f) {
// We're at the target and didn't fling and there's no overshoot
- endJankMonitoring(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
- mKeyguardStateController.notifyPanelFlingEnd();
- notifyExpandingFinished();
+ onFlingEnd(false /* cancelled */);
return;
}
mIsFlinging = true;
@@ -1034,16 +1034,19 @@ public abstract class PanelViewController {
animator.start();
setAnimator(animator);
- View[] viewsToAnimate = {
- mKeyguardBottomArea.getIndicationArea(),
- mCentralSurfaces.getAmbientIndicationContainer()};
- for (View v : viewsToAnimate) {
- if (v == null) {
- continue;
- }
- v.animate().translationY(-mHintDistance).setDuration(250).setInterpolator(
- Interpolators.FAST_OUT_SLOW_IN).withEndAction(() -> v.animate().translationY(
- 0).setDuration(450).setInterpolator(mBounceInterpolator).start()).start();
+ final List<ViewPropertyAnimator> indicationAnimators =
+ mKeyguardBottomArea.getIndicationAreaAnimators();
+ for (final ViewPropertyAnimator indicationAreaAnimator : indicationAnimators) {
+ indicationAreaAnimator
+ .translationY(-mHintDistance)
+ .setDuration(250)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .withEndAction(() -> indicationAreaAnimator
+ .translationY(0)
+ .setDuration(450)
+ .setInterpolator(mBounceInterpolator)
+ .start())
+ .start();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index a94c2b73d1f6..7c31366ba4f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.statusbar.phone.StatusBarIconList.Slot;
+
import android.annotation.NonNull;
import android.content.Context;
import android.graphics.drawable.Icon;
@@ -56,11 +58,12 @@ import javax.inject.Inject;
* registered with it.
*/
@SysUISingleton
-public class StatusBarIconControllerImpl extends StatusBarIconList implements Tunable,
+public class StatusBarIconControllerImpl implements Tunable,
ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController, DemoMode {
private static final String TAG = "StatusBarIconController";
+ private final StatusBarIconList mStatusBarIconList;
private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
private final ArraySet<String> mIconHideList = new ArraySet<>();
@@ -74,15 +77,12 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
DemoModeController demoModeController,
ConfigurationController configurationController,
TunerService tunerService,
- DumpManager dumpManager) {
- super(context.getResources().getStringArray(
- com.android.internal.R.array.config_statusBarIcons));
- configurationController.addCallback(this);
-
+ DumpManager dumpManager,
+ StatusBarIconList statusBarIconList) {
+ mStatusBarIconList = statusBarIconList;
mContext = context;
- loadDimens();
-
+ configurationController.addCallback(this);
commandQueue.addCallback(this);
tunerService.addTunable(this, ICON_HIDE_LIST);
demoModeController.addCallback(this);
@@ -101,15 +101,14 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
group.setController(this);
mIconGroups.add(group);
- List<Slot> allSlots = getSlots();
+ List<Slot> allSlots = mStatusBarIconList.getSlots();
for (int i = 0; i < allSlots.size(); i++) {
Slot slot = allSlots.get(i);
List<StatusBarIconHolder> holders = slot.getHolderListInViewOrder();
boolean hidden = mIconHideList.contains(slot.getName());
for (StatusBarIconHolder holder : holders) {
- int tag = holder.getTag();
- int viewIndex = getViewIndex(getSlotIndex(slot.getName()), holder.getTag());
+ int viewIndex = mStatusBarIconList.getViewIndex(slot.getName(), holder.getTag());
group.onIconAdded(viewIndex, slot.getName(), hidden, holder);
}
}
@@ -144,7 +143,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
}
mIconHideList.clear();
mIconHideList.addAll(StatusBarIconController.getIconHideList(mContext, newValue));
- ArrayList<Slot> currentSlots = getSlots();
+ List<Slot> currentSlots = mStatusBarIconList.getSlots();
ArrayMap<Slot, List<StatusBarIconHolder>> slotsToReAdd = new ArrayMap<>();
// This is a little hacky... Peel off all of the holders on all of the slots
@@ -163,17 +162,13 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
List<StatusBarIconHolder> iconsForSlot = slotsToReAdd.get(item);
if (iconsForSlot == null) continue;
for (StatusBarIconHolder holder : iconsForSlot) {
- setIcon(getSlotIndex(item.getName()), holder);
+ setIcon(item.getName(), holder);
}
}
}
- private void loadDimens() {
- }
-
- private void addSystemIcon(int index, StatusBarIconHolder holder) {
- String slot = getSlotName(index);
- int viewIndex = getViewIndex(index, holder.getTag());
+ private void addSystemIcon(String slot, StatusBarIconHolder holder) {
+ int viewIndex = mStatusBarIconList.getViewIndex(slot, holder.getTag());
boolean hidden = mIconHideList.contains(slot);
mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, hidden, holder));
@@ -182,18 +177,17 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
/** */
@Override
public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
- int index = getSlotIndex(slot);
- StatusBarIconHolder holder = getIcon(index, 0);
+ StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, 0);
if (holder == null) {
StatusBarIcon icon = new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
Icon.createWithResource(
mContext, resourceId), 0, 0, contentDescription);
holder = StatusBarIconHolder.fromIcon(icon);
- setIcon(index, holder);
+ setIcon(slot, holder);
} else {
holder.getIcon().icon = Icon.createWithResource(mContext, resourceId);
holder.getIcon().contentDescription = contentDescription;
- handleSet(index, holder);
+ handleSet(slot, holder);
}
}
@@ -203,21 +197,18 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
*/
@Override
public void setSignalIcon(String slot, WifiIconState state) {
-
- int index = getSlotIndex(slot);
-
if (state == null) {
- removeIcon(index, 0);
+ removeIcon(slot, 0);
return;
}
- StatusBarIconHolder holder = getIcon(index, 0);
+ StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, 0);
if (holder == null) {
holder = StatusBarIconHolder.fromWifiIconState(state);
- setIcon(index, holder);
+ setIcon(slot, holder);
} else {
holder.setWifiState(state);
- handleSet(index, holder);
+ handleSet(slot, holder);
}
}
@@ -229,8 +220,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
*/
@Override
public void setMobileIcons(String slot, List<MobileIconState> iconStates) {
- Slot mobileSlot = getSlot(slot);
- int slotIndex = getSlotIndex(slot);
+ Slot mobileSlot = mStatusBarIconList.getSlot(slot);
// Reverse the sort order to show icons with left to right([Slot1][Slot2]..).
// StatusBarIconList has UI design that first items go to the right of second items.
@@ -241,10 +231,10 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
StatusBarIconHolder holder = mobileSlot.getHolderForTag(state.subId);
if (holder == null) {
holder = StatusBarIconHolder.fromMobileIconState(state);
- setIcon(slotIndex, holder);
+ setIcon(slot, holder);
} else {
holder.setMobileState(state);
- handleSet(slotIndex, holder);
+ handleSet(slot, holder);
}
}
}
@@ -256,21 +246,19 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
*/
@Override
public void setCallStrengthIcons(String slot, List<CallIndicatorIconState> states) {
- Slot callStrengthSlot = getSlot(slot);
- int callStrengthSlotIndex = getSlotIndex(slot);
+ Slot callStrengthSlot = mStatusBarIconList.getSlot(slot);
Collections.reverse(states);
for (CallIndicatorIconState state : states) {
if (!state.isNoCalling) {
StatusBarIconHolder holder = callStrengthSlot.getHolderForTag(state.subId);
if (holder == null) {
holder = StatusBarIconHolder.fromCallIndicatorState(mContext, state);
- setIcon(callStrengthSlotIndex, holder);
} else {
holder.setIcon(new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
Icon.createWithResource(mContext, state.callStrengthResId), 0, 0,
state.callStrengthDescription));
- setIcon(callStrengthSlotIndex, holder);
}
+ setIcon(slot, holder);
}
setIconVisibility(slot, !state.isNoCalling, state.subId);
}
@@ -283,21 +271,19 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
*/
@Override
public void setNoCallingIcons(String slot, List<CallIndicatorIconState> states) {
- Slot noCallingSlot = getSlot(slot);
- int noCallingSlotIndex = getSlotIndex(slot);
+ Slot noCallingSlot = mStatusBarIconList.getSlot(slot);
Collections.reverse(states);
for (CallIndicatorIconState state : states) {
if (state.isNoCalling) {
StatusBarIconHolder holder = noCallingSlot.getHolderForTag(state.subId);
if (holder == null) {
holder = StatusBarIconHolder.fromCallIndicatorState(mContext, state);
- setIcon(noCallingSlotIndex, holder);
} else {
holder.setIcon(new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
Icon.createWithResource(mContext, state.noCallingResId), 0, 0,
state.noCallingDescription));
- setIcon(noCallingSlotIndex, holder);
}
+ setIcon(slot, holder);
}
setIconVisibility(slot, state.isNoCalling, state.subId);
}
@@ -305,42 +291,31 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
@Override
public void setExternalIcon(String slot) {
- int viewIndex = getViewIndex(getSlotIndex(slot), 0);
+ int viewIndex = mStatusBarIconList.getViewIndex(slot, 0);
int height = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_drawing_size);
mIconGroups.forEach(l -> l.onIconExternal(viewIndex, height));
}
//TODO: remove this (used in command queue and for 3rd party tiles?)
- @Override
public void setIcon(String slot, StatusBarIcon icon) {
- setIcon(getSlotIndex(slot), icon);
- }
-
- /**
- * For backwards compatibility, in the event that someone gives us a slot and a status bar icon
- */
- private void setIcon(int index, StatusBarIcon icon) {
- String slot = getSlotName(index);
if (icon == null) {
removeAllIconsForSlot(slot);
return;
}
StatusBarIconHolder holder = StatusBarIconHolder.fromIcon(icon);
- setIcon(index, holder);
+ setIcon(slot, holder);
}
- /** */
- @Override
- public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
- boolean isNew = getIcon(index, holder.getTag()) == null;
- super.setIcon(index, holder);
+ private void setIcon(String slot, @NonNull StatusBarIconHolder holder) {
+ boolean isNew = mStatusBarIconList.getIconHolder(slot, holder.getTag()) == null;
+ mStatusBarIconList.setIcon(slot, holder);
if (isNew) {
- addSystemIcon(index, holder);
+ addSystemIcon(slot, holder);
} else {
- handleSet(index, holder);
+ handleSet(slot, holder);
}
}
@@ -351,34 +326,33 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
/** */
public void setIconVisibility(String slot, boolean visibility, int tag) {
- int index = getSlotIndex(slot);
- StatusBarIconHolder holder = getIcon(index, tag);
+ StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, tag);
if (holder == null || holder.isVisible() == visibility) {
return;
}
holder.setVisible(visibility);
- handleSet(index, holder);
+ handleSet(slot, holder);
}
/** */
@Override
public void setIconAccessibilityLiveRegion(String slotName, int accessibilityLiveRegion) {
- Slot slot = getSlot(slotName);
+ Slot slot = mStatusBarIconList.getSlot(slotName);
if (!slot.hasIconsInSlot()) {
return;
}
- int slotIndex = getSlotIndex(slotName);
List<StatusBarIconHolder> iconsToUpdate = slot.getHolderListInViewOrder();
for (StatusBarIconHolder holder : iconsToUpdate) {
- int viewIndex = getViewIndex(slotIndex, holder.getTag());
+ int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
mIconGroups.forEach(l -> l.mGroup.getChildAt(viewIndex)
.setAccessibilityLiveRegion(accessibilityLiveRegion));
}
}
/** */
+ @Override
public void removeIcon(String slot) {
removeAllIconsForSlot(slot);
}
@@ -386,39 +360,34 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
/** */
@Override
public void removeIcon(String slot, int tag) {
- removeIcon(getSlotIndex(slot), tag);
+ if (mStatusBarIconList.getIconHolder(slot, tag) == null) {
+ return;
+ }
+ int viewIndex = mStatusBarIconList.getViewIndex(slot, tag);
+ mStatusBarIconList.removeIcon(slot, tag);
+ mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
}
/** */
@Override
public void removeAllIconsForSlot(String slotName) {
- Slot slot = getSlot(slotName);
+ Slot slot = mStatusBarIconList.getSlot(slotName);
if (!slot.hasIconsInSlot()) {
return;
}
- int slotIndex = getSlotIndex(slotName);
List<StatusBarIconHolder> iconsToRemove = slot.getHolderListInViewOrder();
for (StatusBarIconHolder holder : iconsToRemove) {
- int viewIndex = getViewIndex(slotIndex, holder.getTag());
+ int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
slot.removeForTag(holder.getTag());
mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
}
}
- /** */
- @Override
- public void removeIcon(int index, int tag) {
- if (getIcon(index, tag) == null) {
- return;
- }
- super.removeIcon(index, tag);
- int viewIndex = getViewIndex(index, 0);
- mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
- }
- private void handleSet(int index, StatusBarIconHolder holder) {
- int viewIndex = getViewIndex(index, holder.getTag());
+
+ private void handleSet(String slotName, StatusBarIconHolder holder) {
+ int viewIndex = mStatusBarIconList.getViewIndex(slotName, holder.getTag());
mIconGroups.forEach(l -> l.onSetIconHolder(viewIndex, holder));
}
@@ -438,7 +407,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
}
}
- super.dump(pw);
+ mStatusBarIconList.dump(pw);
}
/** */
@@ -482,7 +451,6 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
/** */
@Override
public void onDensityOrFontScaleChanged() {
- loadDimens();
refreshIconGroups();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index c876c3228eb8..8800b05fadb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -25,60 +25,72 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+/** A class holding the list of all the system icons that could be shown in the status bar. */
public class StatusBarIconList {
- private ArrayList<Slot> mSlots = new ArrayList<>();
+ private final ArrayList<Slot> mSlots = new ArrayList<>();
+ private final List<Slot> mViewOnlySlots = Collections.unmodifiableList(mSlots);
public StatusBarIconList(String[] slots) {
final int N = slots.length;
- for (int i=0; i < N; i++) {
+ for (int i = 0; i < N; i++) {
mSlots.add(new Slot(slots[i], null));
}
}
- public int getSlotIndex(String slot) {
- final int N = mSlots.size();
- for (int i=0; i<N; i++) {
- Slot item = mSlots.get(i);
- if (item.getName().equals(slot)) {
- return i;
- }
- }
- // Auto insert new items at the beginning.
- mSlots.add(0, new Slot(slot, null));
- return 0;
- }
-
- protected ArrayList<Slot> getSlots() {
- return new ArrayList<>(mSlots);
- }
-
- protected Slot getSlot(String name) {
- return mSlots.get(getSlotIndex(name));
+ /** Returns the list of current slots. */
+ public List<Slot> getSlots() {
+ return mViewOnlySlots;
}
- public int size() {
- return mSlots.size();
+ /**
+ * Gets the slot with the given {@code name}, or creates a new slot if we don't already have a
+ * slot by that name.
+ *
+ * If a new slot is created, that slot will be inserted at the front of the list.
+ *
+ * TODO(b/237533036): Rename this to getOrCreateSlot to make it more clear that it could create
+ * a new slot. Other methods in this class will also create a new slot if we don't have one,
+ * should those be re-named too?
+ */
+ public Slot getSlot(String name) {
+ return mSlots.get(findOrInsertSlot(name));
}
- public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
- mSlots.get(index).addHolder(holder);
+ /**
+ * Sets the icon in {@code holder} to be associated with the slot with the given
+ * {@code slotName}.
+ */
+ public void setIcon(String slotName, @NonNull StatusBarIconHolder holder) {
+ mSlots.get(findOrInsertSlot(slotName)).addHolder(holder);
}
- public void removeIcon(int index, int tag) {
- mSlots.get(index).removeForTag(tag);
+ /**
+ * Removes the icon holder that we had associated with {@code slotName}'s slot at the given
+ * {@code tag}.
+ */
+ public void removeIcon(String slotName, int tag) {
+ mSlots.get(findOrInsertSlot(slotName)).removeForTag(tag);
}
- public String getSlotName(int index) {
- return mSlots.get(index).getName();
+ /**
+ * Returns the icon holder currently associated with {@code slotName}'s slot at the given
+ * {@code tag}, or null if we don't have one.
+ */
+ @Nullable
+ public StatusBarIconHolder getIconHolder(String slotName, int tag) {
+ return mSlots.get(findOrInsertSlot(slotName)).getHolderForTag(tag);
}
- public StatusBarIconHolder getIcon(int index, int tag) {
- return mSlots.get(index).getHolderForTag(tag);
- }
-
- public int getViewIndex(int slotIndex, int tag) {
+ /**
+ * Returns the index of the icon in {@code slotName}'s slot at the given {@code tag}.
+ *
+ * Note that a single slot can have multiple icons, and this function takes that into account.
+ */
+ public int getViewIndex(String slotName, int tag) {
+ int slotIndex = findOrInsertSlot(slotName);
int count = 0;
for (int i = 0; i < slotIndex; i++) {
Slot item = mSlots.get(i);
@@ -100,6 +112,25 @@ public class StatusBarIconList {
}
}
+ private int findOrInsertSlot(String slot) {
+ final int N = mSlots.size();
+ for (int i = 0; i < N; i++) {
+ Slot item = mSlots.get(i);
+ if (item.getName().equals(slot)) {
+ return i;
+ }
+ }
+ // Auto insert new items at the beginning.
+ mSlots.add(0, new Slot(slot, null));
+ return 0;
+ }
+
+
+ /**
+ * A class representing one slot in the status bar system icons view.
+ *
+ * Note that one slot can have multiple icons associated with it.
+ */
public static class Slot {
private final String mName;
private StatusBarIconHolder mHolder;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index c90383f3cf00..12b86092d959 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -129,8 +129,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void onFullyShown() {
mBouncerAnimating = false;
updateStates();
- mCentralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(),
- mCentralSurfaces.getBouncerContainer(), "BOUNCER_VISIBLE");
}
@Override
@@ -966,7 +964,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public boolean bouncerIsOrWillBeShowing() {
- return isBouncerShowing() || mBouncer.getShowingSoon();
+ return isBouncerShowing() || mBouncer.inTransit();
}
public boolean isFullscreenBouncer() {
@@ -1042,7 +1040,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
if (occluded != mLastOccluded || mFirstUpdate) {
- mKeyguardUpdateManager.onKeyguardOccludedChanged(occluded);
mKeyguardStateController.notifyKeyguardState(showing, occluded);
}
if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
@@ -1071,11 +1068,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
}
- private View getCurrentNavBarView() {
- final NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
- return navBarView != null ? navBarView.getCurrentView() : null;
- }
-
/**
* Updates the visibility of the nav bar window (which will cause insets changes).
*/
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 cf776e3b60d1..72db884b4cac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -52,21 +52,15 @@ import com.android.systemui.EventLogTags;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.NotificationEntryListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -92,24 +86,19 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
private final Context mContext;
- private final CommandQueue mCommandQueue;
private final Handler mMainThreadHandler;
private final Executor mUiBgExecutor;
- private final NotificationEntryManager mEntryManager;
- private final NotifPipeline mNotifPipeline;
private final NotificationVisibilityProvider mVisibilityProvider;
private final HeadsUpManagerPhone mHeadsUpManager;
private final ActivityStarter mActivityStarter;
private final NotificationClickNotifier mClickNotifier;
- private final StatusBarStateController mStatusBarStateController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final KeyguardManager mKeyguardManager;
private final IDreamManager mDreamManager;
private final Optional<BubblesManager> mBubblesManagerOptional;
private final Lazy<AssistManager> mAssistManagerLazy;
private final NotificationRemoteInputManager mRemoteInputManager;
- private final GroupMembershipManager mGroupMembershipManager;
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final ShadeController mShadeController;
private final KeyguardStateController mKeyguardStateController;
@@ -118,7 +107,6 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
private final ActivityIntentHelper mActivityIntentHelper;
- private final NotifPipelineFlags mNotifPipelineFlags;
private final MetricsLogger mMetricsLogger;
private final StatusBarNotificationActivityStarterLogger mLogger;
@@ -134,23 +122,19 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
@Inject
StatusBarNotificationActivityStarter(
Context context,
- CommandQueue commandQueue,
Handler mainThreadHandler,
Executor uiBgExecutor,
- NotificationEntryManager entryManager,
NotifPipeline notifPipeline,
NotificationVisibilityProvider visibilityProvider,
HeadsUpManagerPhone headsUpManager,
ActivityStarter activityStarter,
NotificationClickNotifier clickNotifier,
- StatusBarStateController statusBarStateController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
KeyguardManager keyguardManager,
IDreamManager dreamManager,
Optional<BubblesManager> bubblesManagerOptional,
Lazy<AssistManager> assistManagerLazy,
NotificationRemoteInputManager remoteInputManager,
- GroupMembershipManager groupMembershipManager,
NotificationLockscreenUserManager lockscreenUserManager,
ShadeController shadeController,
KeyguardStateController keyguardStateController,
@@ -158,7 +142,6 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
LockPatternUtils lockPatternUtils,
StatusBarRemoteInputCallback remoteInputCallback,
ActivityIntentHelper activityIntentHelper,
- NotifPipelineFlags notifPipelineFlags,
MetricsLogger metricsLogger,
StatusBarNotificationActivityStarterLogger logger,
OnUserInteractionCallback onUserInteractionCallback,
@@ -168,23 +151,18 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
ActivityLaunchAnimator activityLaunchAnimator,
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) {
mContext = context;
- mCommandQueue = commandQueue;
mMainThreadHandler = mainThreadHandler;
mUiBgExecutor = uiBgExecutor;
- mEntryManager = entryManager;
- mNotifPipeline = notifPipeline;
mVisibilityProvider = visibilityProvider;
mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter;
mClickNotifier = clickNotifier;
- mStatusBarStateController = statusBarStateController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardManager = keyguardManager;
mDreamManager = dreamManager;
mBubblesManagerOptional = bubblesManagerOptional;
mAssistManagerLazy = assistManagerLazy;
mRemoteInputManager = remoteInputManager;
- mGroupMembershipManager = groupMembershipManager;
mLockscreenUserManager = lockscreenUserManager;
mShadeController = shadeController;
mKeyguardStateController = keyguardStateController;
@@ -192,7 +170,6 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
mLockPatternUtils = lockPatternUtils;
mStatusBarRemoteInputCallback = remoteInputCallback;
mActivityIntentHelper = activityIntentHelper;
- mNotifPipelineFlags = notifPipelineFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
mOnUserInteractionCallback = onUserInteractionCallback;
@@ -203,21 +180,12 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
mActivityLaunchAnimator = activityLaunchAnimator;
mNotificationAnimationProvider = notificationAnimationProvider;
- if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
- mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
- @Override
- public void onPendingEntryAdded(NotificationEntry entry) {
- handleFullScreenIntent(entry);
- }
- });
- } else {
- mNotifPipeline.addCollectionListener(new NotifCollectionListener() {
- @Override
- public void onEntryAdded(NotificationEntry entry) {
- handleFullScreenIntent(entry);
- }
- });
- }
+ notifPipeline.addCollectionListener(new NotifCollectionListener() {
+ @Override
+ public void onEntryAdded(NotificationEntry entry) {
+ handleFullScreenIntent(entry);
+ }
+ });
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 55b7e7b00060..4f0c374bd473 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -30,13 +30,9 @@ import android.util.Log;
import android.util.Slog;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
-import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.widget.MessagingGroup;
-import com.android.internal.widget.MessagingMessage;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceNotificationListener;
import com.android.systemui.InitController;
@@ -56,7 +52,6 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
@@ -71,16 +66,12 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import java.util.List;
-
import javax.inject.Inject;
@CentralSurfacesComponent.CentralSurfacesScope
class StatusBarNotificationPresenter implements NotificationPresenter,
- ConfigurationController.ConfigurationListener,
NotificationRowBinderImpl.BindRowCallback,
CommandQueue.Callbacks {
private static final String TAG = "StatusBarNotificationPresenter";
@@ -90,10 +81,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final SysuiStatusBarStateController mStatusBarStateController;
private final NotifShadeEventSource mNotifShadeEventSource;
- private final NotificationEntryManager mEntryManager;
private final NotificationMediaManager mMediaManager;
private final NotificationGutsManager mGutsManager;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final LockscreenGestureLogger mLockscreenGestureLogger;
private final NotificationPanelViewController mNotificationPanel;
@@ -114,9 +103,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
private final IStatusBarService mBarService;
private final DynamicPrivacyController mDynamicPrivacyController;
private final NotificationListContainer mNotifListContainer;
- private boolean mReinflateNotificationsOnUserSwitched;
- private boolean mDispatchUiModeChangeOnUserSwitched;
- private TextView mNotificationPanelDebugText;
protected boolean mVrMode;
@@ -140,15 +126,12 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
NotificationLockscreenUserManager lockscreenUserManager,
SysuiStatusBarStateController sysuiStatusBarStateController,
NotifShadeEventSource notifShadeEventSource,
- NotificationEntryManager notificationEntryManager,
NotificationMediaManager notificationMediaManager,
NotificationGutsManager notificationGutsManager,
- KeyguardUpdateMonitor keyguardUpdateMonitor,
LockscreenGestureLogger lockscreenGestureLogger,
InitController initController,
NotificationInterruptStateProvider notificationInterruptStateProvider,
NotificationRemoteInputManager remoteInputManager,
- ConfigurationController configurationController,
NotifPipelineFlags notifPipelineFlags,
NotificationRemoteInputManager.Callback remoteInputManagerCallback,
NotificationListContainer notificationListContainer) {
@@ -166,10 +149,8 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
mLockscreenUserManager = lockscreenUserManager;
mStatusBarStateController = sysuiStatusBarStateController;
mNotifShadeEventSource = notifShadeEventSource;
- mEntryManager = notificationEntryManager;
mMediaManager = notificationMediaManager;
mGutsManager = notificationGutsManager;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockscreenGestureLogger = lockscreenGestureLogger;
mAboveShelfObserver = new AboveShelfObserver(stackScrollerController.getView());
mNotificationShadeWindowController = notificationShadeWindowController;
@@ -212,7 +193,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
onUserSwitched(mLockscreenUserManager.getCurrentUserId());
});
- configurationController.addCallback(this);
}
/** Called when the shade has been emptied to attempt to close the shade */
@@ -227,65 +207,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
}
@Override
- public void onDensityOrFontScaleChanged() {
- // TODO(b/145659174): Remove legacy pipeline code
- if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
- MessagingMessage.dropCache();
- MessagingGroup.dropCache();
- if (!mKeyguardUpdateMonitor.isSwitchingUser()) {
- updateNotificationsOnDensityOrFontScaleChanged();
- } else {
- mReinflateNotificationsOnUserSwitched = true;
- }
- }
-
- @Override
- public void onUiModeChanged() {
- // TODO(b/145659174): Remove legacy pipeline code
- if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
- if (!mKeyguardUpdateMonitor.isSwitchingUser()) {
- updateNotificationsOnUiModeChanged();
- } else {
- mDispatchUiModeChangeOnUserSwitched = true;
- }
- }
-
- @Override
- public void onThemeChanged() {
- onDensityOrFontScaleChanged();
- }
-
- private void updateNotificationsOnUiModeChanged() {
- // TODO(b/145659174): Remove legacy pipeline code
- if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
- List<NotificationEntry> userNotifications =
- mEntryManager.getActiveNotificationsForCurrentUser();
- for (int i = 0; i < userNotifications.size(); i++) {
- NotificationEntry entry = userNotifications.get(i);
- ExpandableNotificationRow row = entry.getRow();
- if (row != null) {
- row.onUiModeChanged();
- }
- }
- }
-
- private void updateNotificationsOnDensityOrFontScaleChanged() {
- // TODO(b/145659174): Remove legacy pipeline code
- if (mNotifPipelineFlags.isNewPipelineEnabled()) return;
- List<NotificationEntry> userNotifications =
- mEntryManager.getActiveNotificationsForCurrentUser();
- for (int i = 0; i < userNotifications.size(); i++) {
- NotificationEntry entry = userNotifications.get(i);
- entry.onDensityOrFontScaleChanged();
- boolean exposedGuts = entry.areGutsExposed();
- if (exposedGuts) {
- mGutsManager.onDensityOrFontScaleChanged(entry);
- }
- }
- }
-
-
- @Override
public boolean isCollapsing() {
return mNotificationPanel.isCollapsing()
|| mNotificationShadeWindowController.isLaunchingActivity();
@@ -324,17 +245,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
// End old BaseStatusBar.userSwitched
if (MULTIUSER_DEBUG) mNotificationPanel.setHeaderDebugInfo("USER " + newUserId);
mCommandQueue.animateCollapsePanels();
- if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
- if (mReinflateNotificationsOnUserSwitched) {
- updateNotificationsOnDensityOrFontScaleChanged();
- mReinflateNotificationsOnUserSwitched = false;
- }
- if (mDispatchUiModeChangeOnUserSwitched) {
- updateNotificationsOnUiModeChanged();
- mDispatchUiModeChangeOnUserSwitched = false;
- }
- updateNotificationViews("user switched");
- }
mMediaManager.clearCurrentMediaNotification();
mCentralSurfaces.setLockscreenUser(newUserId);
updateMediaMetaData(true, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 5bd20ff2d090..a29ba916eb41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -68,6 +68,7 @@ public class BrightnessMirrorController
mBrightnessMirror.setVisibility(View.INVISIBLE);
});
mVisibilityCallback = visibilityCallback;
+ updateResources();
}
public void showMirror() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 2fb16ee9b3b9..bdac88837969 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -424,11 +424,6 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
}
@Override
- public void onFaceUnlockStateChanged(boolean running, int userId) {
- update(false /* updateAlways */);
- }
-
- @Override
public void onStrongAuthStateChanged(int userId) {
update(false /* updateAlways */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
index 0b5594b14d0e..fabbb2c1f44d 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
@@ -16,14 +16,20 @@
package com.android.systemui.tv;
-import com.android.systemui.SystemUIFactory;
+import android.content.Context;
+
+import com.android.systemui.SystemUIInitializer;
import com.android.systemui.dagger.GlobalRootComponent;
/**
- * TV variant {@link SystemUIFactory}, that substitutes default {@link GlobalRootComponent} for
+ * TV variant {@link SystemUIInitializer}, that substitutes default {@link GlobalRootComponent} for
* {@link TvGlobalRootComponent}
*/
-public class TvSystemUIFactory extends SystemUIFactory {
+public class TvSystemUIInitializer extends SystemUIInitializer {
+ public TvSystemUIInitializer(Context context) {
+ super(context);
+ }
+
@Override
protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
return DaggerTvGlobalRootComponent.builder();
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
index ad734914170b..74d51112deeb 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
@@ -28,6 +28,7 @@ import android.os.Bundle
import android.os.UserManager
import android.provider.Settings
import android.view.LayoutInflater
+import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
@@ -38,8 +39,10 @@ import androidx.constraintlayout.helper.widget.Flow
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.util.UserIcons
import com.android.settingslib.Utils
+import com.android.systemui.Gefingerpoken
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
import com.android.systemui.settings.UserTracker
@@ -61,12 +64,13 @@ class UserSwitcherActivity @Inject constructor(
private val userSwitcherController: UserSwitcherController,
private val broadcastDispatcher: BroadcastDispatcher,
private val layoutInflater: LayoutInflater,
+ private val falsingCollector: FalsingCollector,
private val falsingManager: FalsingManager,
private val userManager: UserManager,
private val userTracker: UserTracker
) : LifecycleActivity() {
- private lateinit var parent: ViewGroup
+ private lateinit var parent: UserSwitcherRootView
private lateinit var broadcastReceiver: BroadcastReceiver
private var popupMenu: UserSwitcherPopupMenu? = null
private lateinit var addButton: View
@@ -202,7 +206,14 @@ class UserSwitcherActivity @Inject constructor(
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
- parent = requireViewById<ViewGroup>(R.id.user_switcher_root)
+ parent = requireViewById<UserSwitcherRootView>(R.id.user_switcher_root)
+
+ parent.touchHandler = object : Gefingerpoken {
+ override fun onTouchEvent(ev: MotionEvent?): Boolean {
+ falsingCollector.onTouchEvent(ev)
+ return false
+ }
+ }
requireViewById<View>(R.id.cancel).apply {
setOnClickListener {
@@ -241,7 +252,7 @@ class UserSwitcherActivity @Inject constructor(
)
popupMenuAdapter.addAll(items)
- popupMenu = UserSwitcherPopupMenu(this, falsingManager).apply {
+ popupMenu = UserSwitcherPopupMenu(this).apply {
setAnchorView(addButton)
setAdapter(popupMenuAdapter)
setOnItemClickListener {
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
index 754a9342bfb0..ee785b62bd50 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
@@ -23,16 +23,13 @@ import android.view.View.MeasureSpec
import android.widget.ListAdapter
import android.widget.ListPopupWindow
import android.widget.ListView
-
import com.android.systemui.R
-import com.android.systemui.plugins.FalsingManager
/**
* Popup menu for displaying items on the fullscreen user switcher.
*/
class UserSwitcherPopupMenu(
- private val context: Context,
- private val falsingManager: FalsingManager
+ private val context: Context
) : ListPopupWindow(context) {
private val res = context.resources
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
new file mode 100644
index 000000000000..66a301744025
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.user
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.android.systemui.Gefingerpoken
+
+/** A simple subclass that allows for observing touch events as they happen. */
+class UserSwitcherRootView(
+ context: Context,
+ attrs: AttributeSet?
+) : ConstraintLayout(context, attrs) {
+
+ /** Assign this field to observer touch events. */
+ var touchHandler: Gefingerpoken? = null
+
+ override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
+ touchHandler?.onTouchEvent(ev)
+ return super.dispatchTouchEvent(ev)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
new file mode 100644
index 000000000000..05d087e232ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
@@ -0,0 +1,41 @@
+package com.android.systemui.util.kotlin
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import dagger.Module
+import dagger.Provides
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+
+/** Providers for various coroutines-related constructs. */
+@Module
+object CoroutinesModule {
+ @Provides
+ @SysUISingleton
+ @Application
+ fun applicationScope(
+ @Main dispatcher: CoroutineDispatcher,
+ ): CoroutineScope = CoroutineScope(dispatcher)
+
+ @Provides
+ @SysUISingleton
+ @Main
+ fun mainDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate
+
+ /**
+ * Provide a [CoroutineDispatcher] backed by a thread pool containing at most X threads, where
+ * X is the number of CPU cores available.
+ *
+ * Because there are multiple threads at play, there is no serialization order guarantee. You
+ * should use a [kotlinx.coroutines.channels.Channel] for serialization if necessary.
+ *
+ * @see Dispatchers.Default
+ */
+ @Provides
+ @SysUISingleton
+ @Background
+ fun bgDispatcher(): CoroutineDispatcher = Dispatchers.Default
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 802194464b62..0ac4eda84eea 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -107,13 +107,15 @@ class ClockEventControllerTest : SysuiTestCase() {
@Test
fun themeChanged_verifyClockPaletteUpdated() {
clockEventController.clock = clock
+ verify(events).onColorPaletteChanged(any(), any(), any())
+
clockEventController.registerListeners()
val captor = argumentCaptor<ConfigurationController.ConfigurationListener>()
verify(configurationController).addCallback(capture(captor))
captor.value.onThemeChanged()
- verify(events).onColorPaletteChanged(any(), any(), any())
+ verify(events, times(2)).onColorPaletteChanged(any(), any(), any())
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
index ac1a83c269e0..4021652295c1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -31,6 +32,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.view.Gravity;
+import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -42,6 +44,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -104,6 +107,17 @@ public class KeyguardHostViewControllerTest extends SysuiTestCase {
}
@Test
+ public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() {
+ mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE);
+ mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE);
+
+ InOrder order = inOrder(mKeyguardSecurityContainerController);
+ order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE);
+ order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(
+ View.INVISIBLE);
+ }
+
+ @Test
public void testGravityReappliedOnConfigurationChange() {
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
index b1e2012ecd40..ad6d146fb5f3 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
@@ -92,7 +92,6 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel(
keyguardAwake = false,
keyguardGoingAway = false,
listeningForFaceAssistant = false,
- lockIconPressed = false,
occludingAppRequestingFaceAuth = false,
primaryUser = false,
scanningAllowedByStrongAuth = false,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index bc351427310d..68e49c0a1d4b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -25,17 +25,21 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.hardware.biometrics.BiometricSourceType;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
+import android.view.View;
import android.view.WindowInsetsController;
import androidx.test.filters.SmallTest;
@@ -46,6 +50,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.SidefpsController;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.SessionTracker;
@@ -59,10 +64,14 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
+import java.util.Optional;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper()
@@ -124,6 +133,14 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
private SessionTracker mSessionTracker;
@Mock
private KeyguardViewController mKeyguardViewController;
+ @Mock
+ private SidefpsController mSidefpsController;
+ @Mock
+ private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
+
+ @Captor
+ private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
+
private Configuration mConfiguration;
private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
@@ -160,7 +177,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
mKeyguardStateController, mKeyguardSecurityViewFlipperController,
mConfigurationController, mFalsingCollector, mFalsingManager,
mUserSwitcherController, mFeatureFlags, mGlobalSettings,
- mSessionTracker).create(mSecurityCallback);
+ mSessionTracker, Optional.of(mSidefpsController)).create(mSecurityCallback);
}
@Test
@@ -258,9 +275,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
@Test
public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() {
when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true);
- when(mKeyguardSecurityViewFlipperController.getSecurityView(
- eq(SecurityMode.Password), any(KeyguardSecurityCallback.class)))
- .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
+ setupGetSecurityView();
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
verify(mView).initMode(MODE_DEFAULT, mGlobalSettings, mFalsingManager,
@@ -276,4 +291,126 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
verify(mUserSwitcherController)
.removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
}
+
+ @Test
+ public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
+ setupConditionsToEnableSideFpsHint();
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+ verify(mSidefpsController).show();
+ verify(mSidefpsController, never()).hide();
+ }
+
+ @Test
+ public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
+ setupConditionsToEnableSideFpsHint();
+ setFingerprintDetectionRunning(false);
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ @Test
+ public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
+ setupConditionsToEnableSideFpsHint();
+ setSidedSecurityMode(false);
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ @Test
+ public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() {
+ setupConditionsToEnableSideFpsHint();
+ setNeedsStrongAuth(true);
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ @Test
+ public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() {
+ setupGetSecurityView();
+ setupConditionsToEnableSideFpsHint();
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+ verify(mSidefpsController, atLeastOnce()).show();
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ @Test
+ public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() {
+ setupGetSecurityView();
+ setupConditionsToEnableSideFpsHint();
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+ verify(mSidefpsController, atLeastOnce()).show();
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onStartingToHide();
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ @Test
+ public void onPause_sideFpsHintShown_sideFpsHintHidden() {
+ setupGetSecurityView();
+ setupConditionsToEnableSideFpsHint();
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+ verify(mSidefpsController, atLeastOnce()).show();
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onPause();
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ private void setupConditionsToEnableSideFpsHint() {
+ attachView();
+ setSidedSecurityMode(true);
+ setFingerprintDetectionRunning(true);
+ setNeedsStrongAuth(false);
+ }
+
+ private void attachView() {
+ mKeyguardSecurityContainerController.onViewAttached();
+ verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
+ }
+
+ private void setFingerprintDetectionRunning(boolean running) {
+ when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running);
+ mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running,
+ BiometricSourceType.FINGERPRINT);
+ }
+
+ private void setSidedSecurityMode(boolean sided) {
+ when(mView.isSidedSecurityMode()).thenReturn(sided);
+ }
+
+ private void setNeedsStrongAuth(boolean needed) {
+ when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed);
+ mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0);
+ }
+
+ private void setupGetSecurityView() {
+ when(mKeyguardSecurityViewFlipperController.getSecurityView(
+ any(), any(KeyguardSecurityCallback.class)))
+ .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewControllerMock);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 2dc066c8a9db..84903d17852f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -1109,8 +1109,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
// THEN face unlock is not running b/c status bar state changes don't cause biometric
// listening state to update
- assertThat(mKeyguardUpdateMonitor.isFaceUnlockRunning(
- KeyguardUpdateMonitor.getCurrentUser())).isEqualTo(false);
+ assertThat(mKeyguardUpdateMonitor.isFaceDetectionRunning()).isEqualTo(false);
// WHEN biometric listening state is updated
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
index 5d8e4351cfd9..a0fdc8f1555e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
@@ -26,6 +26,8 @@ import com.android.systemui.statusbar.policy.FlashlightController;
import org.junit.Assert;
import org.junit.Test;
+import java.util.concurrent.ExecutionException;
+
@SmallTest
public class DependencyTest extends SysuiTestCase {
@@ -44,10 +46,12 @@ public class DependencyTest extends SysuiTestCase {
}
@Test
- public void testInitDependency() {
+ public void testInitDependency() throws ExecutionException, InterruptedException {
Dependency.clearDependencies();
- Dependency dependency =
- SystemUIFactory.getInstance().getSysUIComponent().createDependency();
+ SystemUIInitializer initializer =
+ SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
+ initializer.init(true);
+ Dependency dependency = initializer.getSysUIComponent().createDependency();
dependency.start();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index 8c20b248d02c..9179efc9f39f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -34,6 +34,8 @@ import org.junit.Before;
import org.junit.Rule;
import org.mockito.Mockito;
+import java.util.concurrent.ExecutionException;
+
public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
public static final Class<?>[] ALL_SUPPORTED_CLASSES = LeakCheckedTest.ALL_SUPPORTED_CLASSES;
@@ -54,10 +56,11 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
}
@Before
- public void SysuiSetup() {
- SystemUIFactory.createFromConfig(mContext, true);
- mDependency = new TestableDependency(
- SystemUIFactory.getInstance().getSysUIComponent().createDependency());
+ public void sysuiSetup() throws ExecutionException, InterruptedException {
+ SystemUIInitializer initializer =
+ SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
+ initializer.init(true);
+ mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);
// TODO: Figure out another way to give reference to a SysuiTestableContext.
@@ -77,7 +80,6 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
public void SysuiTeardown() {
InstrumentationRegistry.registerInstance(mRealInstrumentation,
InstrumentationRegistry.getArguments());
- SystemUIFactory.cleanup();
}
@AfterClass
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 8c7927782d2d..c52ea60f0bfc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -76,9 +76,10 @@ public abstract class SysuiTestCase {
@Before
public void SysuiSetup() throws Exception {
- SystemUIFactory.createFromConfig(mContext, true);
- mDependency = new TestableDependency(
- SystemUIFactory.getInstance().getSysUIComponent().createDependency());
+ SystemUIInitializer initializer =
+ SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
+ initializer.init(true);
+ mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
mock(Executor.class), mock(DumpManager.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
index 7e9f84c1ef8c..bebd8712a750 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
@@ -191,6 +191,16 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
}
@Test
+ public void hideMenuViewWhenStartingAnimation_animatorNotRunning() {
+ mMenuView.show();
+
+ mMenuView.mDragAnimator.start();
+ mMenuView.hide();
+
+ assertThat(mMenuView.mDragAnimator.isRunning()).isFalse();
+ }
+
+ @Test
public void onTargetsChanged_singleTarget_expectedRadii() {
final Position alignRightPosition = new Position(1.0f, 0.0f);
final AccessibilityFloatingMenuView menuView = new AccessibilityFloatingMenuView(mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
index b61fbbe1ea75..273786d74782 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
@@ -207,25 +207,30 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
}
@Test
- fun animatesAppearingViewsFromStartToEnd() {
- // Starting GONE.
- rootView.visibility = View.GONE
- rootView.layout(0 /* l */, 50 /* t */, 50 /* r */, 100 /* b */)
- var success = ViewHierarchyAnimator.animateAddition(rootView)
- rootView.visibility = View.VISIBLE
- rootView.layout(0 /* l */, 100 /* t */, 100 /* r */, 200 /* b */)
+ fun animatesInvisibleViews() {
+ rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
+ rootView.visibility = View.INVISIBLE
+
+ val success = ViewHierarchyAnimator.animate(rootView)
+ // Change all bounds.
+ rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
assertTrue(success)
assertNotNull(rootView.getTag(R.id.tag_animator))
- checkBounds(rootView, l = 50, t = 150, r = 50, b = 150)
+ // The initial values should be those of the previous layout.
+ checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
endAnimation(rootView)
assertNull(rootView.getTag(R.id.tag_animator))
- checkBounds(rootView, l = 0, t = 100, r = 100, b = 200)
+ // The end values should be those of the latest layout.
+ checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
+ }
- // Starting INVISIBLE.
- rootView.visibility = View.INVISIBLE
+ @Test
+ fun animatesAppearingViewsFromStartToEnd() {
+ // Starting GONE.
+ rootView.visibility = View.GONE
rootView.layout(0 /* l */, 50 /* t */, 50 /* r */, 100 /* b */)
- success = ViewHierarchyAnimator.animateAddition(rootView)
+ var success = ViewHierarchyAnimator.animateAddition(rootView)
rootView.visibility = View.VISIBLE
rootView.layout(0 /* l */, 100 /* t */, 100 /* r */, 200 /* b */)
@@ -937,7 +942,7 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
}
@Test
- fun doesNotAnimateInvisibleViews() {
+ fun doesNotAnimateGoneViews() {
rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
// GONE
@@ -948,15 +953,6 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
assertFalse(success)
assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 0, t = 15, r = 55, b = 80)
-
- // INVISIBLE.
- rootView.visibility = View.INVISIBLE
- success = ViewHierarchyAnimator.animate(rootView)
- rootView.layout(0 /* l */, 20 /* t */, 10 /* r */, 50 /* b */)
-
- assertFalse(success)
- assertNull(rootView.getTag(R.id.tag_animator))
- checkBounds(rootView, l = 0, t = 20, r = 10, b = 50)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index bc5a4d3d274e..bf3788e4c76a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -48,11 +48,12 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.anyLong
import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
@@ -87,7 +88,7 @@ class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testNotifiesAnimatedIn() {
initializeFingerprintContainer()
- verify(callback).onDialogAnimatedIn()
+ verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
}
@Test
@@ -96,13 +97,13 @@ class AuthContainerViewTest : SysuiTestCase() {
container.dismissFromSystemServer()
waitForIdleSync()
- verify(callback, never()).onDialogAnimatedIn()
+ verify(callback, never()).onDialogAnimatedIn(anyLong())
container.addToView()
waitForIdleSync()
// attaching the view resets the state and allows this to happen again
- verify(callback).onDialogAnimatedIn()
+ verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
}
@Test
@@ -110,14 +111,17 @@ class AuthContainerViewTest : SysuiTestCase() {
val container = initializeFingerprintContainer()
waitForIdleSync()
- verify(callback).onDialogAnimatedIn()
+ val requestID = authContainer?.requestId ?: 0L
+
+ verify(callback).onDialogAnimatedIn(requestID)
container.onWindowFocusChanged(false)
waitForIdleSync()
verify(callback).onDismissed(
- eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
- eq<ByteArray?>(null) /* credentialAttestation */
+ eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
+ eq<ByteArray?>(null), /* credentialAttestation */
+ eq(requestID)
)
assertThat(container.parent).isNull()
}
@@ -131,8 +135,9 @@ class AuthContainerViewTest : SysuiTestCase() {
waitForIdleSync()
verify(callback).onDismissed(
- eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
- eq<ByteArray?>(null) /* credentialAttestation */
+ eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
+ eq<ByteArray?>(null), /* credentialAttestation */
+ eq(authContainer?.requestId ?: 0L)
)
assertThat(container.parent).isNull()
}
@@ -146,11 +151,13 @@ class AuthContainerViewTest : SysuiTestCase() {
waitForIdleSync()
verify(callback).onSystemEvent(
- eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL)
+ eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL),
+ eq(authContainer?.requestId ?: 0L)
)
verify(callback).onDismissed(
- eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
- eq<ByteArray?>(null) /* credentialAttestation */
+ eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
+ eq<ByteArray?>(null), /* credentialAttestation */
+ eq(authContainer?.requestId ?: 0L)
)
assertThat(container.parent).isNull()
}
@@ -164,8 +171,9 @@ class AuthContainerViewTest : SysuiTestCase() {
waitForIdleSync()
verify(callback).onDismissed(
- eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
- eq<ByteArray?>(null) /* credentialAttestation */
+ eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
+ eq<ByteArray?>(null), /* credentialAttestation */
+ eq(authContainer?.requestId ?: 0L)
)
assertThat(container.parent).isNull()
}
@@ -180,7 +188,7 @@ class AuthContainerViewTest : SysuiTestCase() {
)
waitForIdleSync()
- verify(callback).onTryAgainPressed()
+ verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
}
@Test
@@ -192,8 +200,9 @@ class AuthContainerViewTest : SysuiTestCase() {
waitForIdleSync()
verify(callback).onDismissed(
- eq(AuthDialogCallback.DISMISSED_ERROR),
- eq<ByteArray?>(null) /* credentialAttestation */
+ eq(AuthDialogCallback.DISMISSED_ERROR),
+ eq<ByteArray?>(null), /* credentialAttestation */
+ eq(authContainer?.requestId ?: 0L)
)
assertThat(authContainer!!.parent).isNull()
}
@@ -209,7 +218,7 @@ class AuthContainerViewTest : SysuiTestCase() {
)
waitForIdleSync()
- verify(callback).onDeviceCredentialPressed()
+ verify(callback).onDeviceCredentialPressed(authContainer?.requestId ?: 0L)
assertThat(container.hasCredentialView()).isTrue()
}
@@ -297,6 +306,16 @@ class AuthContainerViewTest : SysuiTestCase() {
}
@Test
+ fun testLayoutParams_hasDimbehindWindowFlag() {
+ val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+ val lpFlags = layoutParams.flags
+ val lpDimAmount = layoutParams.dimAmount
+
+ assertThat((lpFlags and WindowManager.LayoutParams.FLAG_DIM_BEHIND) != 0).isTrue()
+ assertThat(lpDimAmount).isGreaterThan(0f)
+ }
+
+ @Test
fun testLayoutParams_excludesImeInsets() {
val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
@@ -312,12 +331,12 @@ class AuthContainerViewTest : SysuiTestCase() {
container.onAuthenticationFailed(BiometricAuthenticator.TYPE_FACE, "failed")
waitForIdleSync()
- verify(callback, never()).onTryAgainPressed()
+ verify(callback, never()).onTryAgainPressed(anyLong())
container.onPointerDown()
waitForIdleSync()
- verify(callback).onTryAgainPressed()
+ verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
}
private fun initializeFingerprintContainer(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index d948a99f8ad8..d158892e4ec5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -291,7 +291,8 @@ public class AuthControllerTest extends SysuiTestCase {
public void testSendsReasonUserCanceled_whenDismissedByUserCancel() throws Exception {
showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
- null /* credentialAttestation */);
+ null, /* credentialAttestation */
+ mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL),
eq(null) /* credentialAttestation */);
@@ -301,7 +302,8 @@ public class AuthControllerTest extends SysuiTestCase {
public void testSendsReasonNegative_whenDismissedByButtonNegative() throws Exception {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE,
- null /* credentialAttestation */);
+ null, /* credentialAttestation */
+ mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_NEGATIVE),
eq(null) /* credentialAttestation */);
@@ -311,7 +313,8 @@ public class AuthControllerTest extends SysuiTestCase {
public void testSendsReasonConfirmed_whenDismissedByButtonPositive() throws Exception {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE,
- null /* credentialAttestation */);
+ null, /* credentialAttestation */
+ mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED),
eq(null) /* credentialAttestation */);
@@ -321,7 +324,8 @@ public class AuthControllerTest extends SysuiTestCase {
public void testSendsReasonConfirmNotRequired_whenDismissedByAuthenticated() throws Exception {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED,
- null /* credentialAttestation */);
+ null, /* credentialAttestation */
+ mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED),
eq(null) /* credentialAttestation */);
@@ -331,7 +335,8 @@ public class AuthControllerTest extends SysuiTestCase {
public void testSendsReasonError_whenDismissedByError() throws Exception {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_ERROR,
- null /* credentialAttestation */);
+ null, /* credentialAttestation */
+ mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_ERROR),
eq(null) /* credentialAttestation */);
@@ -341,7 +346,8 @@ public class AuthControllerTest extends SysuiTestCase {
public void testSendsReasonServerRequested_whenDismissedByServer() throws Exception {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER,
- null /* credentialAttestation */);
+ null, /* credentialAttestation */
+ mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED),
eq(null) /* credentialAttestation */);
@@ -355,7 +361,7 @@ public class AuthControllerTest extends SysuiTestCase {
final byte[] credentialAttestation = generateRandomHAT();
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED,
- credentialAttestation);
+ credentialAttestation, mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
AdditionalMatchers.aryEq(credentialAttestation));
@@ -531,7 +537,7 @@ public class AuthControllerTest extends SysuiTestCase {
final byte[] credentialAttestation = generateRandomHAT();
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED,
- credentialAttestation);
+ credentialAttestation, mAuthController.mCurrentDialog.getRequestId());
verify(mReceiver).onDialogDismissed(
eq(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
AdditionalMatchers.aryEq(credentialAttestation));
@@ -640,17 +646,19 @@ public class AuthControllerTest extends SysuiTestCase {
@Test
public void testDoesNotCrash_whenTryAgainPressedAfterDismissal() {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+ final long requestID = mAuthController.mCurrentDialog.getRequestId();
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
- null /* credentialAttestation */);
- mAuthController.onTryAgainPressed();
+ null, /* credentialAttestation */requestID);
+ mAuthController.onTryAgainPressed(requestID);
}
@Test
public void testDoesNotCrash_whenDeviceCredentialPressedAfterDismissal() {
showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+ final long requestID = mAuthController.mCurrentDialog.getRequestId();
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
- null /* credentialAttestation */);
- mAuthController.onDeviceCredentialPressed();
+ null /* credentialAttestation */, requestID);
+ mAuthController.onDeviceCredentialPressed(requestID);
}
@Test
@@ -708,7 +716,8 @@ public class AuthControllerTest extends SysuiTestCase {
// WHEN dialog is shown and then dismissed
showDialog(new int[]{1} /* sensorIds */, false /* credentialAllowed */);
mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED,
- null /* credentialAttestation */);
+ null /* credentialAttestation */,
+ mAuthController.mCurrentDialog.getRequestId());
// THEN callback should be received
verify(callback).onBiometricPromptDismissed();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS
new file mode 100644
index 000000000000..adb10f01b5e1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/OWNERS
@@ -0,0 +1,4 @@
+set noparent
+
+include /services/core/java/com/android/server/biometrics/OWNERS
+beverlyt@google.com
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
index dec2b82ed88f..6157ccbd597a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
@@ -62,7 +62,6 @@ import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.eq
import org.mockito.Captor
import org.mockito.Mock
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.anyFloat
import org.mockito.Mockito.anyInt
@@ -72,6 +71,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenEver
import org.mockito.junit.MockitoJUnit
private const val DISPLAY_ID = 2
@@ -126,15 +126,15 @@ class SidefpsControllerTest : SysuiTestCase() {
context.addMockSystemService(DisplayManager::class.java, displayManager)
context.addMockSystemService(WindowManager::class.java, windowManager)
- `when`(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
- `when`(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
+ whenEver(layoutInflater.inflate(R.layout.sidefps_view, null, false)).thenReturn(sidefpsView)
+ whenEver(sidefpsView.findViewById<LottieAnimationView>(eq(R.id.sidefps_animation)))
.thenReturn(mock(LottieAnimationView::class.java))
with(mock(ViewPropertyAnimator::class.java)) {
- `when`(sidefpsView.animate()).thenReturn(this)
- `when`(alpha(anyFloat())).thenReturn(this)
- `when`(setStartDelay(anyLong())).thenReturn(this)
- `when`(setDuration(anyLong())).thenReturn(this)
- `when`(setListener(any())).thenAnswer {
+ whenEver(sidefpsView.animate()).thenReturn(this)
+ whenEver(alpha(anyFloat())).thenReturn(this)
+ whenEver(setStartDelay(anyLong())).thenReturn(this)
+ whenEver(setDuration(anyLong())).thenReturn(this)
+ whenEver(setListener(any())).thenAnswer {
(it.arguments[0] as Animator.AnimatorListener)
.onAnimationEnd(mock(Animator::class.java))
this
@@ -177,7 +177,7 @@ class SidefpsControllerTest : SysuiTestCase() {
displayBounds = Rect(0, 0, displayWidth, displayHeight)
var locations = listOf(sensorLocation)
- `when`(fingerprintManager.sensorPropertiesInternal).thenReturn(
+ whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(
listOf(
FingerprintSensorPropertiesInternal(
SENSOR_ID,
@@ -196,12 +196,12 @@ class SidefpsControllerTest : SysuiTestCase() {
displayInfo.initInfo()
val dmGlobal = mock(DisplayManagerGlobal::class.java)
val display = Display(dmGlobal, DISPLAY_ID, displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS)
- `when`(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
- `when`(windowManager.defaultDisplay).thenReturn(display)
- `when`(windowManager.maximumWindowMetrics).thenReturn(
+ whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
+ whenEver(windowManager.defaultDisplay).thenReturn(display)
+ whenEver(windowManager.maximumWindowMetrics).thenReturn(
WindowMetrics(displayBounds, WindowInsets.CONSUMED)
)
- `when`(windowManager.currentWindowMetrics).thenReturn(
+ whenEver(windowManager.currentWindowMetrics).thenReturn(
WindowMetrics(displayBounds, windowInsets)
)
@@ -277,13 +277,13 @@ class SidefpsControllerTest : SysuiTestCase() {
@Test
fun testShowsForMostSettings() = testWithDisplay {
- `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
+ whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpEnrollTask()))
testIgnoredFor(REASON_AUTH_SETTINGS, ignored = false)
}
@Test
fun testIgnoredForVerySpecificSettings() = testWithDisplay {
- `when`(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
+ whenEver(activityTaskManager.getTasks(anyInt())).thenReturn(listOf(fpSettingsTask()))
testIgnoredFor(REASON_AUTH_SETTINGS)
}
@@ -424,6 +424,20 @@ class SidefpsControllerTest : SysuiTestCase() {
assertThat(overlayViewParamsCaptor.value.x).isEqualTo(displayWidth - boundsWidth)
assertThat(overlayViewParamsCaptor.value.y).isEqualTo(sensorLocation.sensorLocationY)
}
+
+ @Test
+ fun hasSideFpsSensor_withSensorProps_returnsTrue() = testWithDisplay {
+ // By default all those tests assume the side fps sensor is available.
+
+ assertThat(fingerprintManager.hasSideFpsSensor()).isTrue()
+ }
+
+ @Test
+ fun hasSideFpsSensor_withoutSensorProps_returnsFalse() {
+ whenEver(fingerprintManager.sensorPropertiesInternal).thenReturn(null)
+
+ assertThat(fingerprintManager.hasSideFpsSensor()).isFalse()
+ }
}
private fun insetsForSmallNavbar() = insetsWithBottom(60)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 638e6f32a241..d7a0a0ae974d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -414,37 +414,43 @@ public class UdfpsControllerTest extends SysuiTestCase {
final UdfpsOverlayParams oldParams = new UdfpsOverlayParams(sensorBounds[0],
displayWidth[0], displayHeight[0], scaleFactor[0], rotation[0]);
- for (int i1 = 0; i1 <= 1; ++i1)
- for (int i2 = 0; i2 <= 1; ++i2)
- for (int i3 = 0; i3 <= 1; ++i3)
- for (int i4 = 0; i4 <= 1; ++i4)
- for (int i5 = 0; i5 <= 1; ++i5) {
- final UdfpsOverlayParams newParams = new UdfpsOverlayParams(sensorBounds[i1],
- displayWidth[i2], displayHeight[i3], scaleFactor[i4], rotation[i5]);
-
- if (newParams.equals(oldParams)) {
- continue;
+ for (int i1 = 0; i1 <= 1; ++i1) {
+ for (int i2 = 0; i2 <= 1; ++i2) {
+ for (int i3 = 0; i3 <= 1; ++i3) {
+ for (int i4 = 0; i4 <= 1; ++i4) {
+ for (int i5 = 0; i5 <= 1; ++i5) {
+ final UdfpsOverlayParams newParams = new UdfpsOverlayParams(
+ sensorBounds[i1], displayWidth[i2], displayHeight[i3],
+ scaleFactor[i4], rotation[i5]);
+
+ if (newParams.equals(oldParams)) {
+ continue;
+ }
+
+ // Initialize the overlay with old parameters.
+ mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, oldParams);
+
+ // Show the overlay.
+ reset(mWindowManager);
+ mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID,
+ TEST_UDFPS_SENSOR_ID,
+ BiometricOverlayConstants.REASON_ENROLL_ENROLLING,
+ mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+ verify(mWindowManager).addView(any(), any());
+
+ // Update overlay parameters.
+ reset(mWindowManager);
+ mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, newParams);
+ mFgExecutor.runAllReady();
+
+ // Ensure the overlay was recreated.
+ verify(mWindowManager).removeView(any());
+ verify(mWindowManager).addView(any(), any());
+ }
+ }
+ }
}
-
- // Initialize the overlay with old parameters.
- mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, oldParams);
-
- // Show the overlay.
- reset(mWindowManager);
- mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, TEST_UDFPS_SENSOR_ID,
- BiometricOverlayConstants.REASON_ENROLL_ENROLLING,
- mUdfpsOverlayControllerCallback);
- mFgExecutor.runAllReady();
- verify(mWindowManager).addView(any(), any());
-
- // Update overlay parameters.
- reset(mWindowManager);
- mUdfpsController.updateOverlayParams(TEST_UDFPS_SENSOR_ID, newParams);
- mFgExecutor.runAllReady();
-
- // Ensure the overlay was recreated.
- verify(mWindowManager).removeView(any());
- verify(mWindowManager).addView(any(), any());
}
}
@@ -740,12 +746,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
anyString(),
any(),
eq("udfps-onStart-click"),
- eq(UdfpsController.VIBRATION_ATTRIBUTES));
+ eq(UdfpsController.UDFPS_VIBRATION_ATTRIBUTES));
// THEN make sure vibration attributes has so that it always will play the haptic,
// even in battery saver mode
assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST,
- UdfpsController.VIBRATION_ATTRIBUTES.getUsage());
+ UdfpsController.UDFPS_VIBRATION_ATTRIBUTES.getUsage());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index e5a75e231f8d..49cdfa72f344 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -86,7 +86,7 @@ public class DozeUiTest extends SysuiTestCase {
mHandler = mHandlerThread.getThreadHandler();
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
- mDozeParameters, mKeyguardUpdateMonitor, mStatusBarStateController, mDozeLog);
+ mDozeParameters, mStatusBarStateController, mDozeLog);
mDozeUi.setDozeMachine(mMachine);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index d334694805fe..60e5a9423c61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -184,25 +184,36 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
- public void testOnViewAttachedShowsMicCameraIconWhenDisabled() {
+ public void testOnViewAttachedShowsMicIconWhenDisabled() {
when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
.thenReturn(true);
when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
- .thenReturn(true);
+ .thenReturn(false);
mController.onViewAttached();
verify(mView).showIcon(
- DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, true, null);
+ DreamOverlayStatusBarView.STATUS_ICON_MIC_DISABLED, true, null);
}
@Test
- public void testOnViewAttachedHidesMicCameraIconWhenEnabled() {
+ public void testOnViewAttachedShowsCameraIconWhenDisabled() {
when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
.thenReturn(false);
when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
- .thenReturn(false);
+ .thenReturn(true);
+ mController.onViewAttached();
+ verify(mView).showIcon(
+ DreamOverlayStatusBarView.STATUS_ICON_CAMERA_DISABLED, true, null);
+ }
+
+ @Test
+ public void testOnViewAttachedShowsMicCameraIconWhenDisabled() {
+ when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+ .thenReturn(true);
+ when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+ .thenReturn(true);
mController.onViewAttached();
verify(mView).showIcon(
- DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false, null);
+ DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, true, null);
}
@Test
@@ -386,24 +397,6 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
- public void testMicCameraIconHiddenWhenSensorsNotBlocked() {
- when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
- .thenReturn(true).thenReturn(false);
- when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
- .thenReturn(true).thenReturn(false);
- mController.onViewAttached();
-
- final ArgumentCaptor<IndividualSensorPrivacyController.Callback> callbackCapture =
- ArgumentCaptor.forClass(IndividualSensorPrivacyController.Callback.class);
- verify(mSensorPrivacyController).addCallback(callbackCapture.capture());
- callbackCapture.getValue().onSensorBlockedChanged(
- SensorPrivacyManager.Sensors.MICROPHONE, false);
-
- verify(mView).showIcon(
- DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false, null);
- }
-
- @Test
public void testPriorityModeIconShownWhenZenModeEnabled() {
mController.onViewAttached();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
index 883bec465815..a23c4b50082f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
@@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.content.res.Resources;
import android.testing.AndroidTestingRunner;
import android.widget.TextView;
@@ -79,7 +80,7 @@ public class DreamWeatherComplicationTest extends SysuiTestCase {
final DreamWeatherComplication.DreamWeatherViewController controller =
new DreamWeatherComplication.DreamWeatherViewController(mock(
TextView.class), TRAMPOLINE_COMPONENT, mock(ActivityStarter.class),
- mDreamSmartspaceController);
+ mDreamSmartspaceController, mock(Resources.class));
controller.onViewAttached();
verify(mDreamSmartspaceController).addUnfilteredListener(any());
controller.onViewDetached();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 51c258055465..23516c94d851 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -45,6 +45,7 @@ import androidx.slice.core.SliceQuery;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.SystemUIInitializerImpl;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -100,7 +101,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mIsZenMode = false;
mProvider = new TestableKeyguardSliceProvider();
- mProvider.setContextAvailableCallback(context -> { });
+ mProvider.setContextAvailableCallback(context -> new SystemUIInitializerImpl(mContext));
mProvider.attachInfo(getContext(), null);
reset(mContentResolver);
SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt
new file mode 100644
index 000000000000..4f5c570ee812
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/WindowAddedViewLifecycleOwnerTest.kt
@@ -0,0 +1,150 @@
+package com.android.systemui.lifecycle
+
+import android.view.View
+import android.view.ViewTreeObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleRegistry
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(JUnit4::class)
+class WindowAddedViewLifecycleOwnerTest : SysuiTestCase() {
+
+ @Mock lateinit var view: View
+ @Mock lateinit var viewTreeObserver: ViewTreeObserver
+
+ private lateinit var underTest: WindowAddedViewLifecycleOwner
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ whenever(view.viewTreeObserver).thenReturn(viewTreeObserver)
+ whenever(view.isAttachedToWindow).thenReturn(false)
+ whenever(view.windowVisibility).thenReturn(View.INVISIBLE)
+ whenever(view.hasWindowFocus()).thenReturn(false)
+
+ underTest = WindowAddedViewLifecycleOwner(view) { LifecycleRegistry.createUnsafe(it) }
+ }
+
+ @Test
+ fun `detached - invisible - does not have focus -- INITIALIZED`() {
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+ }
+
+ @Test
+ fun `detached - invisible - has focus -- INITIALIZED`() {
+ whenever(view.hasWindowFocus()).thenReturn(true)
+ val captor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+ verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(captor))
+ captor.value.onWindowFocusChanged(true)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+ }
+
+ @Test
+ fun `detached - visible - does not have focus -- INITIALIZED`() {
+ whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+ val captor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+ verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(captor))
+ captor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+ }
+
+ @Test
+ fun `detached - visible - has focus -- INITIALIZED`() {
+ whenever(view.hasWindowFocus()).thenReturn(true)
+ val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+ verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor))
+ focusCaptor.value.onWindowFocusChanged(true)
+
+ whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+ val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+ verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor))
+ visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.INITIALIZED)
+ }
+
+ @Test
+ fun `attached - invisible - does not have focus -- CREATED`() {
+ whenever(view.isAttachedToWindow).thenReturn(true)
+ val captor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+ verify(viewTreeObserver).addOnWindowAttachListener(capture(captor))
+ captor.value.onWindowAttached()
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
+ }
+
+ @Test
+ fun `attached - invisible - has focus -- CREATED`() {
+ whenever(view.isAttachedToWindow).thenReturn(true)
+ val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+ verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor))
+ attachCaptor.value.onWindowAttached()
+
+ whenever(view.hasWindowFocus()).thenReturn(true)
+ val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+ verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor))
+ focusCaptor.value.onWindowFocusChanged(true)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
+ }
+
+ @Test
+ fun `attached - visible - does not have focus -- STARTED`() {
+ whenever(view.isAttachedToWindow).thenReturn(true)
+ val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+ verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor))
+ attachCaptor.value.onWindowAttached()
+
+ whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+ val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+ verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor))
+ visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
+ }
+
+ @Test
+ fun `attached - visible - has focus -- RESUMED`() {
+ whenever(view.isAttachedToWindow).thenReturn(true)
+ val attachCaptor = argumentCaptor<ViewTreeObserver.OnWindowAttachListener>()
+ verify(viewTreeObserver).addOnWindowAttachListener(capture(attachCaptor))
+ attachCaptor.value.onWindowAttached()
+
+ whenever(view.hasWindowFocus()).thenReturn(true)
+ val focusCaptor = argumentCaptor<ViewTreeObserver.OnWindowFocusChangeListener>()
+ verify(viewTreeObserver).addOnWindowFocusChangeListener(capture(focusCaptor))
+ focusCaptor.value.onWindowFocusChanged(true)
+
+ whenever(view.windowVisibility).thenReturn(View.VISIBLE)
+ val visibilityCaptor = argumentCaptor<ViewTreeObserver.OnWindowVisibilityChangeListener>()
+ verify(viewTreeObserver).addOnWindowVisibilityChangeListener(capture(visibilityCaptor))
+ visibilityCaptor.value.onWindowVisibilityChanged(View.VISIBLE)
+
+ assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED)
+ }
+
+ @Test
+ fun dispose() {
+ underTest.dispose()
+
+ verify(viewTreeObserver).removeOnWindowAttachListener(any())
+ verify(viewTreeObserver).removeOnWindowVisibilityChangeListener(any())
+ verify(viewTreeObserver).removeOnWindowFocusChangeListener(any())
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 226182961934..568e0cb22f18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -78,7 +78,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
- when(mMediaOutputController.isZeroMode()).thenReturn(false);
when(mMediaOutputController.isTransferring()).thenReturn(false);
when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat);
when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat);
@@ -98,28 +97,12 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
}
@Test
- public void getItemCount_nonZeroMode_isDeviceSize() {
- assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size());
- }
-
- @Test
- public void getItemCount_zeroMode_containExtraOneForPairNew() {
- when(mMediaOutputController.isZeroMode()).thenReturn(true);
-
+ public void getItemCount_containExtraOneForPairNew() {
assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
}
@Test
- public void getItemCount_withDynamicGroup_containExtraOneForGroup() {
- when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
- when(mMediaOutputController.isZeroMode()).thenReturn(false);
-
- assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size());
- }
-
- @Test
- public void onBindViewHolder_zeroMode_bindPairNew_verifyView() {
- when(mMediaOutputController.isZeroMode()).thenReturn(true);
+ public void onBindViewHolder_bindPairNew_verifyView() {
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
@@ -133,7 +116,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
@Test
public void onBindViewHolder_bindGroup_withSessionName_verifyView() {
when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
- when(mMediaOutputController.isZeroMode()).thenReturn(false);
when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME);
mMediaOutputAdapter.getItemCount();
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -148,7 +130,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
@Test
public void onBindViewHolder_bindGroup_noSessionName_verifyView() {
when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
- when(mMediaOutputController.isZeroMode()).thenReturn(false);
when(mMediaOutputController.getSessionName()).thenReturn(null);
mMediaOutputAdapter.getItemCount();
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -257,7 +238,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
@Test
public void onItemClick_clickPairNew_verifyLaunchBluetoothPairing() {
- when(mMediaOutputController.isZeroMode()).thenReturn(true);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
mViewHolder.mContainerLayout.performClick();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 9eaa20c2afed..d414660018a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -43,6 +43,8 @@ import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat;
import androidx.test.filters.SmallTest;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -98,10 +100,17 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
private CharSequence mHeaderSubtitle;
private String mStopText;
private boolean mIsBroadcasting;
+ private boolean mIsBroadcastIconVisibility;
+
@Before
public void setUp() {
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ final CachedBluetoothDeviceManager cachedBluetoothDeviceManager = mock(
+ CachedBluetoothDeviceManager.class);
+ when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(
+ cachedBluetoothDeviceManager);
+ when(cachedBluetoothDeviceManager.findDevice(any())).thenReturn(null);
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE);
@@ -153,6 +162,27 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
}
@Test
+ public void refresh_broadcastIconVisibilityOff_broadcastIconLayoutNotVisible() {
+ mIsBroadcastIconVisibility = false;
+
+ mMediaOutputBaseDialogImpl.refresh();
+ final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
+ R.id.broadcast_icon);
+
+ assertThat(view.getVisibility()).isEqualTo(View.GONE);
+ }
+ @Test
+ public void refresh_broadcastIconVisibilityOn_broadcastIconLayoutVisible() {
+ mIsBroadcastIconVisibility = true;
+
+ mMediaOutputBaseDialogImpl.refresh();
+ final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
+ R.id.broadcast_icon);
+
+ assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
public void refresh_checkTitle() {
mHeaderTitle = "test_string";
@@ -308,5 +338,10 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
public CharSequence getStopButtonText() {
return mStopText;
}
+
+ @Override
+ public int getBroadcastIconVisibility() {
+ return mIsBroadcastIconVisibility ? View.VISIBLE : View.GONE;
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 2bf5f0fcbfcb..751c8951859c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -383,62 +383,6 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
- public void isZeroMode_onlyFromPhoneOutput_returnTrue() {
- // Multiple available devices
- assertThat(mMediaOutputController.isZeroMode()).isFalse();
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE);
- mMediaDevices.clear();
- mMediaDevices.add(mMediaDevice1);
- mMediaOutputController.start(mCb);
- mMediaOutputController.onDeviceListUpdate(mMediaDevices);
-
- assertThat(mMediaOutputController.isZeroMode()).isTrue();
-
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE);
-
- assertThat(mMediaOutputController.isZeroMode()).isTrue();
-
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE);
-
- assertThat(mMediaOutputController.isZeroMode()).isTrue();
- }
-
- @Test
- public void isZeroMode_notFromPhoneOutput_returnFalse() {
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_UNKNOWN);
- mMediaDevices.clear();
- mMediaDevices.add(mMediaDevice1);
- mMediaOutputController.start(mCb);
- mMediaOutputController.onDeviceListUpdate(mMediaDevices);
-
- assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_FAST_PAIR_BLUETOOTH_DEVICE);
-
- assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
-
- assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
-
- assertThat(mMediaOutputController.isZeroMode()).isFalse();
-
- when(mMediaDevice1.getDeviceType()).thenReturn(
- MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE);
-
- assertThat(mMediaOutputController.isZeroMode()).isFalse();
- }
-
- @Test
public void getGroupMediaDevices_differentDeviceOrder_showingSameOrder() {
final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class);
final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index c45db05bacee..6afed1a846b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -172,6 +172,39 @@ public class MediaOutputDialogTest extends SysuiTestCase {
}
@Test
+ public void getBroadcastIconVisibility_isBroadcasting_returnVisible() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(true);
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+ when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
+ assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void getBroadcastIconVisibility_noBroadcasting_returnGone() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+ when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
+ assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void getBroadcastIconVisibility_remoteNonLeDevice_returnGone() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+ when(mMediaDevice.isBLEDevice()).thenReturn(false);
+
+ assertThat(mMediaOutputDialog.getBroadcastIconVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
// Check the visibility metric logging by creating a new MediaOutput dialog,
// and verify if the calling times increases.
public void onCreate_ShouldLogVisibility() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
new file mode 100644
index 000000000000..73a0cbc5054d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.net.ConnectivityManager
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.util.settings.GlobalSettings
+import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class AirplaneModeTileTest : SysuiTestCase() {
+ @Mock
+ private lateinit var mHost: QSHost
+ @Mock
+ private lateinit var mMetricsLogger: MetricsLogger
+ @Mock
+ private lateinit var mStatusBarStateController: StatusBarStateController
+ @Mock
+ private lateinit var mActivityStarter: ActivityStarter
+ @Mock
+ private lateinit var mQsLogger: QSLogger
+ @Mock
+ private lateinit var mBroadcastDispatcher: BroadcastDispatcher
+ @Mock
+ private lateinit var mConnectivityManager: Lazy<ConnectivityManager>
+ @Mock
+ private lateinit var mGlobalSettings: GlobalSettings
+ private lateinit var mTestableLooper: TestableLooper
+ private lateinit var mTile: AirplaneModeTile
+
+ private val mUiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ mTestableLooper = TestableLooper.get(this)
+ Mockito.`when`(mHost.context).thenReturn(mContext)
+ Mockito.`when`(mHost.uiEventLogger).thenReturn(mUiEventLogger)
+ Mockito.`when`(mHost.userContext).thenReturn(mContext)
+
+ mTile = AirplaneModeTile(mHost,
+ mTestableLooper.looper,
+ Handler(mTestableLooper.looper),
+ FalsingManagerFake(),
+ mMetricsLogger,
+ mStatusBarStateController,
+ mActivityStarter,
+ mQsLogger,
+ mBroadcastDispatcher,
+ mConnectivityManager,
+ mGlobalSettings)
+ }
+
+ @Test
+ fun testIcon_whenDisabled_showsOffState() {
+ val state = QSTile.BooleanState()
+
+ mTile.handleUpdateState(state, 0)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_airplane_icon_off))
+ }
+
+ @Test
+ fun testIcon_whenEnabled_showsOnState() {
+ val state = QSTile.BooleanState()
+
+ mTile.handleUpdateState(state, 1)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_airplane_icon_on))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index 3d9205ee0354..95e7ad9fad4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -24,15 +24,19 @@ import android.testing.TestableLooper.RunWithLooper
import android.view.View
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
@@ -77,6 +81,7 @@ class BatterySaverTileTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
+ `when`(qsHost.context).thenReturn(mContext)
`when`(qsHost.userContext).thenReturn(userContext)
`when`(userContext.userId).thenReturn(USER)
@@ -133,4 +138,26 @@ class BatterySaverTileTest : SysuiTestCase() {
tile.handleSetListening(false)
verify(batteryController).clearLastPowerSaverStartView()
}
+
+ @Test
+ fun testIcon_whenBatterySaverDisabled_isOffState() {
+ val state = QSTile.BooleanState()
+ tile.onPowerSaveChanged(false)
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_off))
+ }
+
+ @Test
+ fun testIcon_whenBatterySaverEnabled_isOnState() {
+ val state = QSTile.BooleanState()
+ tile.onPowerSaveChanged(true)
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_on))
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
new file mode 100644
index 000000000000..cfbb82f5f338
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class CameraToggleTileTest : SysuiTestCase() {
+ companion object {
+ /* isBlocked */
+ const val CAMERA_TOGGLE_ENABLED: Boolean = false
+ const val CAMERA_TOGGLE_DISABLED: Boolean = true
+ }
+
+ @Mock
+ private lateinit var host: QSHost
+ @Mock
+ private lateinit var metricsLogger: MetricsLogger
+ @Mock
+ private lateinit var statusBarStateController: StatusBarStateController
+ @Mock
+ private lateinit var activityStarter: ActivityStarter
+ @Mock
+ private lateinit var qsLogger: QSLogger
+ @Mock
+ private lateinit var privacyController: IndividualSensorPrivacyController
+ @Mock
+ private lateinit var keyguardStateController: KeyguardStateController
+
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var tile: CameraToggleTile
+ private val uiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+ whenever(host.context).thenReturn(mContext)
+ whenever(host.uiEventLogger).thenReturn(uiEventLogger)
+
+ tile = CameraToggleTile(host,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ metricsLogger,
+ FalsingManagerFake(),
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ privacyController,
+ keyguardStateController)
+ }
+
+ @Test
+ fun testIcon_whenCameraAccessEnabled_isOnState() {
+ val state = QSTile.BooleanState()
+
+ tile.handleUpdateState(state, CAMERA_TOGGLE_ENABLED)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_camera_access_icon_on))
+ }
+
+ @Test
+ fun testIcon_whenCameraAccessDisabled_isOffState() {
+ val state = QSTile.BooleanState()
+
+ tile.handleUpdateState(state, CAMERA_TOGGLE_DISABLED)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_camera_access_icon_off))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
index ae70d3203d57..ce5edb147d87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
@@ -21,6 +21,7 @@ import android.content.ContextWrapper
import android.content.SharedPreferences
import android.os.Handler
import android.provider.Settings
+import android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
import android.provider.Settings.Global.ZEN_MODE_OFF
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
@@ -28,13 +29,16 @@ import android.view.View
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.statusbar.policy.ZenModeController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
@@ -66,22 +70,31 @@ class DndTileTest : SysuiTestCase() {
@Mock
private lateinit var qsHost: QSHost
+
@Mock
private lateinit var metricsLogger: MetricsLogger
+
@Mock
private lateinit var statusBarStateController: StatusBarStateController
+
@Mock
private lateinit var activityStarter: ActivityStarter
+
@Mock
private lateinit var qsLogger: QSLogger
+
@Mock
private lateinit var uiEventLogger: UiEventLogger
+
@Mock
private lateinit var zenModeController: ZenModeController
+
@Mock
private lateinit var sharedPreferences: SharedPreferences
+
@Mock
private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+
@Mock
private lateinit var hostDialog: Dialog
@@ -190,4 +203,24 @@ class DndTileTest : SysuiTestCase() {
verify(dialogLaunchAnimator, never()).showFromView(any(), any(), nullable(), anyBoolean())
}
+
+ @Test
+ fun testIcon_whenDndModeOff_isOffState() {
+ whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF)
+ val state = QSTile.BooleanState()
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_off))
+ }
+
+ @Test
+ fun testIcon_whenDndModeOn_isOnState() {
+ whenever(zenModeController.zen).thenReturn(ZEN_MODE_NO_INTERRUPTIONS)
+ val state = QSTile.BooleanState()
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_on))
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
new file mode 100644
index 000000000000..d2bbc8cfac39
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.content.Context
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.policy.LocationController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class LocationTileTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var mockContext: Context
+ @Mock
+ private lateinit var qsLogger: QSLogger
+ @Mock
+ private lateinit var qsHost: QSTileHost
+ @Mock
+ private lateinit var metricsLogger: MetricsLogger
+ private val falsingManager = FalsingManagerFake()
+ @Mock
+ private lateinit var statusBarStateController: StatusBarStateController
+ @Mock
+ private lateinit var activityStarter: ActivityStarter
+ @Mock
+ private lateinit var locationController: LocationController
+ @Mock
+ private lateinit var keyguardStateController: KeyguardStateController
+
+ private val uiEventLogger = UiEventLoggerFake()
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var tile: LocationTile
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+ `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+ `when`(qsHost.context).thenReturn(mockContext)
+
+ tile = LocationTile(qsHost,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ falsingManager,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ locationController,
+ keyguardStateController)
+ }
+
+ @Test
+ fun testIcon_whenDisabled_isOffState() {
+ val state = QSTile.BooleanState()
+ `when`(locationController.isLocationEnabled).thenReturn(false)
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_off))
+ }
+
+ @Test
+ fun testIcon_whenEnabled_isOnState() {
+ val state = QSTile.BooleanState()
+ `when`(locationController.isLocationEnabled).thenReturn(true)
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.icon)
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_on))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
new file mode 100644
index 000000000000..1ab601ce3ebe
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles
+
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class MicrophoneToggleTileTest : SysuiTestCase() {
+ companion object {
+ /* isBlocked */
+ const val MICROPHONE_TOGGLE_ENABLED: Boolean = false
+ const val MICROPHONE_TOGGLE_DISABLED: Boolean = true
+ }
+
+ @Mock
+ private lateinit var host: QSHost
+ @Mock
+ private lateinit var metricsLogger: MetricsLogger
+ @Mock
+ private lateinit var statusBarStateController: StatusBarStateController
+ @Mock
+ private lateinit var activityStarter: ActivityStarter
+ @Mock
+ private lateinit var qsLogger: QSLogger
+ @Mock
+ private lateinit var privacyController: IndividualSensorPrivacyController
+ @Mock
+ private lateinit var keyguardStateController: KeyguardStateController
+
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var tile: MicrophoneToggleTile
+ private val uiEventLogger: UiEventLogger = UiEventLoggerFake()
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+ whenever(host.context).thenReturn(mContext)
+ whenever(host.uiEventLogger).thenReturn(uiEventLogger)
+
+ tile = MicrophoneToggleTile(host,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ metricsLogger,
+ FalsingManagerFake(),
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ privacyController,
+ keyguardStateController)
+ }
+
+ @Test
+ fun testIcon_whenMicrophoneAccessEnabled_isOnState() {
+ val state = QSTile.BooleanState()
+
+ tile.handleUpdateState(state, MICROPHONE_TOGGLE_ENABLED)
+
+ assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_mic_access_on))
+ }
+
+ @Test
+ fun testIcon_whenMicrophoneAccessDisabled_isOffState() {
+ val state = QSTile.BooleanState()
+
+ tile.handleUpdateState(state, MICROPHONE_TOGGLE_DISABLED)
+
+ assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_mic_access_off))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
new file mode 100644
index 000000000000..73226fa0b12c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.settings
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.IntentFilter
+import android.os.Environment
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class UserFileManagerImplTest : SysuiTestCase() {
+ companion object {
+ const val TEST_FILE_NAME = "abc.txt"
+ }
+
+ lateinit var userFileManager: UserFileManagerImpl
+ lateinit var backgroundExecutor: FakeExecutor
+ @Mock
+ lateinit var userManager: UserManager
+ @Mock
+ lateinit var broadcastDispatcher: BroadcastDispatcher
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ backgroundExecutor = FakeExecutor(FakeSystemClock())
+ userFileManager = UserFileManagerImpl(context, userManager,
+ broadcastDispatcher, backgroundExecutor)
+ }
+
+ @Test
+ fun testGetFile() {
+ assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path)
+ .isEqualTo("${context.filesDir}/$TEST_FILE_NAME")
+ assertThat(userFileManager.getFile(TEST_FILE_NAME, 11).path)
+ .isEqualTo("${context.filesDir}/${UserFileManagerImpl.ID}/11/files/$TEST_FILE_NAME")
+ }
+
+ @Test
+ fun testGetSharedPreferences() {
+ assertThat(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0))
+ .isNotEqualTo(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11))
+ }
+
+ @Test
+ fun testUserFileManagerStart() {
+ val userFileManager = spy(userFileManager)
+ userFileManager.start()
+ verify(userFileManager).clearDeletedUserData()
+ verify(broadcastDispatcher).registerReceiver(any(BroadcastReceiver::class.java),
+ any(IntentFilter::class.java),
+ any(Executor::class.java), isNull(), eq(Context.RECEIVER_EXPORTED), isNull())
+ }
+
+ @Test
+ fun testClearDeletedUserData() {
+ val dir = Environment.buildPath(
+ context.filesDir,
+ UserFileManagerImpl.ID,
+ "11",
+ "files"
+ )
+ dir.mkdirs()
+ val file = Environment.buildPath(
+ context.filesDir,
+ UserFileManagerImpl.ID,
+ "11",
+ "files",
+ TEST_FILE_NAME
+ )
+ val secondaryUserDir = Environment.buildPath(
+ context.filesDir,
+ UserFileManagerImpl.ID,
+ "11",
+ )
+ file.createNewFile()
+ assertThat(secondaryUserDir.exists()).isTrue()
+ assertThat(file.exists()).isTrue()
+ userFileManager.clearDeletedUserData()
+ assertThat(backgroundExecutor.runAllReady()).isGreaterThan(0)
+ verify(userManager).aliveUsers
+ assertThat(secondaryUserDir.exists()).isFalse()
+ assertThat(file.exists()).isFalse()
+ dir.deleteRecursively()
+ }
+}
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 883e2dc45554..c5beee892172 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -30,6 +30,7 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont
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.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
import static com.google.common.truth.Truth.assertThat;
@@ -212,7 +213,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
- when(mScreenLifecycle.getScreenState()).thenReturn(ScreenLifecycle.SCREEN_ON);
+ when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
@@ -957,64 +958,170 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
}
@Test
- public void nonBypassFaceSuccess_touchExplorationEnabled_showsSwipeToOpen() {
- // GIVEN non bypass face auth and touch exploration is enabled
- when(mKeyguardBypassController.canBypass()).thenReturn(false);
- when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
+ public void coEx_faceSuccess_showsPressToOpen() {
+ // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, no a11y enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+ when(mAccessibilityManager.isEnabled()).thenReturn(false);
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+ createController();
+ mController.setVisible(true);
+
+ // WHEN face auth succeeds
+ when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+ mController.getKeyguardCallback().onBiometricAuthenticated(0,
+ BiometricSourceType.FACE, false);
+
+ // THEN 'face unlocked. press unlock icon to open' message shows
+ String pressToOpen = mContext.getString(R.string.keyguard_face_successful_unlock_press);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen);
+
+ assertThat(mTextView.getText()).isNotEqualTo(pressToOpen);
+ }
+
+
+ @Test
+ public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() {
+ // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+ when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
createController();
- String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
mController.setVisible(true);
// WHEN face authenticated
+ when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
mController.getKeyguardCallback().onBiometricAuthenticated(0,
BiometricSourceType.FACE, false);
- // THEN show 'swipe up to open' message
- verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
+ // THEN show 'face unlocked. swipe up to open' message
+ String faceUnlockedSwipeToOpen =
+ mContext.getString(R.string.keyguard_face_successful_unlock_swipe);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen);
}
@Test
- public void nonBypassFaceSuccess_a11yEnabled_showsSwipeToOpen() {
- // GIVEN non bypass face auth and a11y is enabled
- when(mKeyguardBypassController.canBypass()).thenReturn(false);
+ public void coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen() {
+ // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ createController();
+ mController.setVisible(true);
+
+ // WHEN face auth is successful
+ when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
+ mController.getKeyguardCallback().onBiometricAuthenticated(0,
+ BiometricSourceType.FACE, false);
+
+ // THEN show 'swipe up to open' message
+ String faceUnlockedSwipeToOpen =
+ mContext.getString(R.string.keyguard_face_successful_unlock_swipe);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen);
+ }
+
+ @Test
+ public void faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen() {
+ // GIVEN bouncer isn't showing, can skip bouncer, no udfps supported
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
createController();
- String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
mController.setVisible(true);
// WHEN face auth is successful
+ when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
mController.getKeyguardCallback().onBiometricAuthenticated(0,
BiometricSourceType.FACE, false);
// THEN show 'swipe up to open' message
+ String faceUnlockedSwipeToOpen =
+ mContext.getString(R.string.keyguard_face_successful_unlock_swipe);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, faceUnlockedSwipeToOpen);
+ }
+
+ @Test
+ public void udfpsOnly_a11yEnabled_showsSwipeToOpen() {
+ // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
+ when(mAccessibilityManager.isEnabled()).thenReturn(true);
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
+ createController();
+ mController.setVisible(true);
+
+ // WHEN showActionToUnlock
+ mController.showActionToUnlock();
+
+ // THEN show 'swipe up to open' message
+ String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
}
@Test
- public void coEx_nonBypassFaceSuccess_showsPressLockIcon() {
- // GIVEN udfps is supported, non-bypass face auth, and no a11y enabled
+ public void udfpsOnly_showsPressToOpen() {
+ // GIVEN bouncer isn't showing, udfps is supported, a11y is NOT enabled, can skip bouncer
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
- when(mKeyguardBypassController.canBypass()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(false);
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+ createController();
+ mController.setVisible(true);
+
+ // WHEN showActionToUnlock
+ mController.showActionToUnlock();
+
+ // THEN show 'press unlock icon to open' message
+ String pressToOpen = mContext.getString(R.string.keyguard_unlock_press);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen);
+ }
+
+ @Test
+ public void canSkipBouncer_noSecurity_showSwipeToUnlockHint() {
+ // GIVEN bouncer isn't showing, can skip bouncer, no security (udfps isn't supported,
+ // face wasn't authenticated)
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
.thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
createController();
mController.setVisible(true);
- // WHEN face auth succeeds
- mController.getKeyguardCallback().onBiometricAuthenticated(0,
- BiometricSourceType.FACE, false);
+ // WHEN showActionToUnlock
+ mController.showActionToUnlock();
- // THEN press unlock icon to open message shows
- String pressLockIcon = mContext.getString(R.string.keyguard_face_successful_unlock_press);
- verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressLockIcon);
+ // THEN show 'swipe up to open' message
+ String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
+ }
- assertThat(mTextView.getText()).isNotEqualTo(pressLockIcon);
+ @Test
+ public void cannotSkipBouncer_showSwipeToUnlockHint() {
+ // GIVEN bouncer isn't showing and cannot skip bouncer
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ .thenReturn(false);
+ createController();
+ mController.setVisible(true);
+
+ // WHEN showActionToUnlock
+ mController.showActionToUnlock();
+
+ // THEN show 'swipe up to open' message
+ String swipeToOpen = mContext.getString(R.string.keyguard_unlock);
+ verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen);
}
private void sendUpdateDisclosureBroadcast() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 4efd5c995a97..f42e6fb2d186 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -150,7 +150,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper);
- when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
mController = new NotificationStackScrollLayoutController(
true,
@@ -166,7 +165,6 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mKeyguardMediaController,
mKeyguardBypassController,
mZenModeController,
- mColorExtractor,
mNotificationLockscreenUserManager,
mMetricsLogger,
mDumpManager,
@@ -179,15 +177,12 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mLegacyGroupManager,
mLegacyGroupManager,
mSilentHeaderController,
- mNotifPipelineFlags,
mNotifPipeline,
mNotifCollection,
mEntryManager,
mLockscreenShadeTransitionController,
mShadeTransitionController,
- mIStatusBarService,
mUiEventLogger,
- mLayoutInflater,
mRemoteInputManager,
mVisualStabilityManager,
mShadeController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index b4532c431415..74fb7f67940d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.phone;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.fail;
@@ -44,6 +46,7 @@ import android.app.WallpaperManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
+import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.display.AmbientDisplayConfiguration;
@@ -89,7 +92,6 @@ import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.fragments.FragmentService;
@@ -118,7 +120,6 @@ import com.android.systemui.statusbar.OperatorNameViewController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
-import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -129,7 +130,6 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
@@ -159,7 +159,6 @@ import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.concurrency.MessageRouterImpl;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.volume.VolumeComponent;
-import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.StartingSurface;
@@ -223,7 +222,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock private BroadcastDispatcher mBroadcastDispatcher;
@Mock private AssistManager mAssistManager;
- @Mock private NotifShadeEventSource mNotifShadeEventSource;
@Mock private NotificationEntryManager mNotificationEntryManager;
@Mock private NotificationGutsManager mNotificationGutsManager;
@Mock private NotificationMediaManager mNotificationMediaManager;
@@ -240,15 +238,12 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
@Mock private UserSwitcherController mUserSwitcherController;
- @Mock private NetworkController mNetworkController;
- @Mock private BubblesManager mBubblesManager;
@Mock private Bubbles mBubbles;
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
@Mock private NotificationIconAreaController mNotificationIconAreaController;
@Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
@Mock private DozeParameters mDozeParameters;
@Mock private Lazy<LockscreenWallpaper> mLockscreenWallpaperLazy;
- @Mock private LockscreenGestureLogger mLockscreenGestureLogger;
@Mock private LockscreenWallpaper mLockscreenWallpaper;
@Mock private DozeServiceHost mDozeServiceHost;
@Mock private ViewMediatorCallback mKeyguardVieMediatorCallback;
@@ -286,7 +281,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private NotifLiveDataStore mNotifLiveDataStore;
@Mock private InteractionJankMonitor mJankMonitor;
@Mock private DeviceStateManager mDeviceStateManager;
- @Mock private DreamOverlayStateController mDreamOverlayStateController;
@Mock private WiredChargingRippleController mWiredChargingRippleController;
private ShadeController mShadeController;
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -401,7 +395,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
new FalsingManagerFake(),
new FalsingCollectorFake(),
mBroadcastDispatcher,
- mNotifShadeEventSource,
mNotificationEntryManager,
mNotificationGutsManager,
notificationLogger,
@@ -416,13 +409,11 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mLockscreenUserManager,
mRemoteInputManager,
mUserSwitcherController,
- mNetworkController,
mBatteryController,
mColorExtractor,
new ScreenLifecycle(mDumpManager),
wakefulnessLifecycle,
mStatusBarStateController,
- Optional.of(mBubblesManager),
Optional.of(mBubbles),
mVisualStabilityManager,
mDeviceProvisionedController,
@@ -434,7 +425,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mDozeParameters,
mScrimController,
mLockscreenWallpaperLazy,
- mLockscreenGestureLogger,
mBiometricUnlockControllerLazy,
mDozeServiceHost,
mPowerManager, mScreenPinningRequest,
@@ -466,7 +456,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mLockscreenTransitionController,
mFeatureFlags,
mKeyguardUnlockAnimationController,
- new Handler(TestableLooper.get(this).getLooper()),
mMainExecutor,
new MessageRouterImpl(mMainExecutor),
mWallpaperManager,
@@ -475,7 +464,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mNotifPipelineFlags,
mJankMonitor,
mDeviceStateManager,
- mDreamOverlayStateController,
mWiredChargingRippleController, mDreamManager);
when(mKeyguardViewMediator.registerCentralSurfaces(
any(CentralSurfacesImpl.class),
@@ -999,6 +987,22 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
verify(mStatusBarStateController, never()).setLeaveOpenOnKeyguardHide(true);
}
+ @Test
+ public void startActivityDismissingKeyguard_isShowingandIsOccluded() {
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
+ mCentralSurfaces.startActivityDismissingKeyguard(
+ new Intent(),
+ /* onlyProvisioned = */false,
+ /* dismissShade = */false);
+ verify(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any(Runnable.class));
+ ArgumentCaptor<OnDismissAction> onDismissActionCaptor =
+ ArgumentCaptor.forClass(OnDismissAction.class);
+ verify(mStatusBarKeyguardViewManager)
+ .dismissWithAction(onDismissActionCaptor.capture(), any(Runnable.class), eq(true));
+ assertThat(onDismissActionCaptor.getValue().onDismiss()).isFalse();
+ }
+
private void setDeviceState(int state) {
ArgumentCaptor<DeviceStateManager.DeviceStateCallback> callbackCaptor =
ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 39021d8732d3..60a3d95e24f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -230,6 +230,15 @@ public class KeyguardBouncerTest extends SysuiTestCase {
}
@Test
+ public void show_notifiesKeyguardViewController() {
+ mBouncer.ensureView();
+
+ mBouncer.show(/* resetSecuritySelection= */ false);
+
+ verify(mKeyguardHostViewController).onBouncerVisibilityChanged(View.VISIBLE);
+ }
+
+ @Test
public void testHide_notifiesFalsingManager() {
mBouncer.hide(false);
verify(mFalsingCollector).onBouncerHidden();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 5b0f3c4b32ae..98cd0804bfd2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -991,6 +991,21 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
}
@Test
+ public void testSwipe_exactlyToTarget_notifiesNssl() {
+ // No over-expansion
+ mNotificationPanelViewController.setOverExpansion(0f);
+ // Fling to a target that is equal to the current position (i.e. a no-op fling).
+ mNotificationPanelViewController.flingToHeight(
+ 0f,
+ true,
+ mNotificationPanelViewController.mExpandedHeight,
+ 1f,
+ false);
+ // Verify that the NSSL is notified that the panel is *not* flinging.
+ verify(mNotificationStackScrollLayoutController).setPanelFlinging(false);
+ }
+
+ @Test
public void testDoubleTapRequired_Keyguard() {
FalsingManager.FalsingTapListener listener = getFalsingTapListener();
mStatusBarStateController.setState(KEYGUARD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index c402d2e47cf3..0e42d9a576f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -28,8 +28,10 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -42,6 +44,8 @@ import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.view.WindowManager;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.ViewTreeLifecycleOwner;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor;
@@ -61,6 +65,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -69,7 +74,8 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
@Mock private WindowManager mWindowManager;
@Mock private DozeParameters mDozeParameters;
- @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
+ @Spy private final NotificationShadeWindowView mNotificationShadeWindowView = spy(
+ new NotificationShadeWindowView(mContext, null));
@Mock private IActivityManager mActivityManager;
@Mock private SysuiStatusBarStateController mStatusBarStateController;
@Mock private ConfigurationController mConfigurationController;
@@ -85,6 +91,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -177,6 +184,24 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
}
@Test
+ public void attach_setsUpLifecycleOwner() {
+ mNotificationShadeWindowController.attach();
+
+ assertThat(ViewTreeLifecycleOwner.get(mNotificationShadeWindowView)).isNotNull();
+ }
+
+ @Test
+ public void attach_doesNotSetUpLifecycleOwnerIfAlreadySet() {
+ final LifecycleOwner previouslySet = mock(LifecycleOwner.class);
+ ViewTreeLifecycleOwner.set(mNotificationShadeWindowView, previouslySet);
+
+ mNotificationShadeWindowController.attach();
+
+ assertThat(ViewTreeLifecycleOwner.get(mNotificationShadeWindowView))
+ .isEqualTo(previouslySet);
+ }
+
+ @Test
public void setScrimsVisibility_earlyReturn() {
clearInvocations(mWindowManager);
mNotificationShadeWindowController.setScrimsVisibility(ScrimController.TRANSPARENT);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
index 7e245fcea22d..7982bc0c101c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
@@ -37,94 +37,94 @@ import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManage
import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.tuner.TunerService
import com.google.common.truth.Truth.assertThat
+import java.util.Optional
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Mock
-import org.mockito.MockitoAnnotations
import org.mockito.Mockito.anyFloat
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import java.util.Optional
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
- private lateinit var mController: NotificationShadeWindowViewController
-
@Mock
- private lateinit var mView: NotificationShadeWindowView
+ private lateinit var view: NotificationShadeWindowView
@Mock
- private lateinit var mTunerService: TunerService
+ private lateinit var tunserService: TunerService
@Mock
- private lateinit var mStatusBarStateController: SysuiStatusBarStateController
+ private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@Mock
- private lateinit var mCentralSurfaces: CentralSurfaces
+ private lateinit var centralSurfaces: CentralSurfaces
@Mock
- private lateinit var mDockManager: DockManager
+ private lateinit var dockManager: DockManager
@Mock
- private lateinit var mNotificationPanelViewController: NotificationPanelViewController
+ private lateinit var notificationPanelViewController: NotificationPanelViewController
@Mock
- private lateinit var mNotificationShadeDepthController: NotificationShadeDepthController
+ private lateinit var notificationShadeDepthController: NotificationShadeDepthController
@Mock
- private lateinit var mNotificationShadeWindowController: NotificationShadeWindowController
+ private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@Mock
- private lateinit var mKeyguardUnlockAnimationController: KeyguardUnlockAnimationController
+ private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
@Mock
- private lateinit var mAmbientState: AmbientState
+ private lateinit var ambientState: AmbientState
@Mock
private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
@Mock
- private lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
@Mock
- private lateinit var mStatusBarWindowStateController: StatusBarWindowStateController
+ private lateinit var statusBarWindowStateController: StatusBarWindowStateController
@Mock
- private lateinit var mLockscreenShadeTransitionController: LockscreenShadeTransitionController
+ private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
@Mock
- private lateinit var mLockIconViewController: LockIconViewController
+ private lateinit var lockIconViewController: LockIconViewController
@Mock
- private lateinit var mPhoneStatusBarViewController: PhoneStatusBarViewController
+ private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
@Mock
- private lateinit var mLowLightClockController: LowLightClockController
+ private lateinit var lowLightClockController: LowLightClockController
+
+ private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
+ private lateinit var interactionEventHandler: InteractionEventHandler
- private lateinit var mInteractionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
- private lateinit var mInteractionEventHandler: InteractionEventHandler
+ private lateinit var underTest: NotificationShadeWindowViewController
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- whenever(mView.bottom).thenReturn(VIEW_BOTTOM)
+ whenever(view.bottom).thenReturn(VIEW_BOTTOM)
- mController = NotificationShadeWindowViewController(
- mLockscreenShadeTransitionController,
+ underTest = NotificationShadeWindowViewController(
+ lockscreenShadeTransitionController,
FalsingCollectorFake(),
- mTunerService,
- mStatusBarStateController,
- mDockManager,
- mNotificationShadeDepthController,
- mView,
- mNotificationPanelViewController,
+ tunserService,
+ sysuiStatusBarStateController,
+ dockManager,
+ notificationShadeDepthController,
+ view,
+ notificationPanelViewController,
PanelExpansionStateManager(),
stackScrollLayoutController,
- mStatusBarKeyguardViewManager,
- mStatusBarWindowStateController,
- mLockIconViewController,
- Optional.of(mLowLightClockController),
- mCentralSurfaces,
- mNotificationShadeWindowController,
- mKeyguardUnlockAnimationController,
- mAmbientState
+ statusBarKeyguardViewManager,
+ statusBarWindowStateController,
+ lockIconViewController,
+ Optional.of(lowLightClockController),
+ centralSurfaces,
+ notificationShadeWindowController,
+ keyguardUnlockAnimationController,
+ ambientState
)
- mController.setupExpandedStatusBar()
+ underTest.setupExpandedStatusBar()
- mInteractionEventHandlerCaptor =
+ interactionEventHandlerCaptor =
ArgumentCaptor.forClass(InteractionEventHandler::class.java)
- verify(mView).setInteractionEventHandler(mInteractionEventHandlerCaptor.capture())
- mInteractionEventHandler = mInteractionEventHandlerCaptor.value
+ verify(view).setInteractionEventHandler(interactionEventHandlerCaptor.capture())
+ interactionEventHandler = interactionEventHandlerCaptor.value
}
// Note: So far, these tests only cover interactions with the status bar view controller. More
@@ -132,148 +132,148 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
@Test
fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() {
- mController.setStatusBarViewController(null)
+ underTest.setStatusBarViewController(null)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
assertThat(returnVal).isFalse()
}
@Test
fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
- whenever(mPhoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
+ whenever(phoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(ev)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(ev)
- verify(mPhoneStatusBarViewController).sendTouchToView(ev)
+ verify(phoneStatusBarViewController).sendTouchToView(ev)
assertThat(returnVal).isTrue()
}
@Test
fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
val downEvBelow = MotionEvent.obtain(
0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0
)
- mInteractionEventHandler.handleDispatchTouchEvent(downEvBelow)
+ interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
val nextEvent = MotionEvent.obtain(
0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0
)
- whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+ whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
- verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
+ verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
assertThat(returnVal).isTrue()
}
@Test
fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
- whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
- whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
.thenReturn(true)
- whenever(mPhoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
+ whenever(phoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
- verify(mPhoneStatusBarViewController).sendTouchToView(downEv)
+ verify(phoneStatusBarViewController).sendTouchToView(downEv)
assertThat(returnVal).isTrue()
}
@Test
fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
- whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
.thenReturn(true)
// Item we're testing
- whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(false)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(false)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
- verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+ verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
assertThat(returnVal).isNull()
}
@Test
fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
- whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
// Item we're testing
- whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
.thenReturn(false)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
- verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+ verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
assertThat(returnVal).isNull()
}
@Test
fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
- whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
- whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
.thenReturn(true)
// Item we're testing
- whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(false)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(false)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
- verify(mPhoneStatusBarViewController, never()).sendTouchToView(downEv)
+ verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
assertThat(returnVal).isTrue()
}
@Test
fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() {
- mController.setStatusBarViewController(mPhoneStatusBarViewController)
- whenever(mStatusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(mNotificationPanelViewController.isFullyCollapsed).thenReturn(true)
- whenever(mPhoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
.thenReturn(true)
// Down event first
- mInteractionEventHandler.handleDispatchTouchEvent(downEv)
+ interactionEventHandler.handleDispatchTouchEvent(downEv)
// Then another event
val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
- whenever(mPhoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+ whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
- val returnVal = mInteractionEventHandler.handleDispatchTouchEvent(nextEvent)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
- verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
+ verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
assertThat(returnVal).isTrue()
}
@Test
fun testLowLightClockAttachedWhenExpandedStatusBarSetup() {
- verify(mLowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
+ verify(lowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
}
@Test
fun testLowLightClockShownWhenDozing() {
- mController.setDozing(true)
- verify(mLowLightClockController).showLowLightClock(true)
+ underTest.setDozing(true)
+ verify(lowLightClockController).showLowLightClock(true)
}
@Test
fun testLowLightClockDozeTimeTickCalled() {
- mController.dozeTimeTick()
- verify(mLowLightClockController).dozeTimeTick()
+ underTest.dozeTimeTick()
+ verify(lowLightClockController).dozeTimeTick()
}
@Test
fun testLowLightClockHiddenWhenNotDozing() {
- mController.setDozing(true)
- verify(mLowLightClockController).showLowLightClock(true)
- mController.setDozing(false)
- verify(mLowLightClockController).showLowLightClock(false)
+ underTest.setDozing(true)
+ verify(lowLightClockController).showLowLightClock(true)
+ underTest.setDozing(false)
+ verify(lowLightClockController).showLowLightClock(false)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconListTest.java
index 4c20b61083f7..f0a4f3f2bf7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconListTest.java
@@ -1,4 +1,20 @@
-package com.android.systemui.statusbar;
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY;
@@ -9,13 +25,10 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import android.test.suitebuilder.annotation.SmallTest;
-
+import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.phone.StatusBarIconHolder;
-import com.android.systemui.statusbar.phone.StatusBarIconList;
import com.android.systemui.statusbar.phone.StatusBarIconList.Slot;
import org.junit.Test;
@@ -33,28 +46,39 @@ public class StatusBarIconListTest extends SysuiTestCase {
@Test
public void testGetExistingSlot() {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
- assertEquals(1, statusBarIconList.getSlotIndex("bbb"));
- assertEquals(2, statusBarIconList.getSlotIndex("ccc"));
+
+ List<Slot> slots = statusBarIconList.getSlots();
+ assertEquals(3, slots.size());
+ assertEquals("aaa", slots.get(0).getName());
+ assertEquals("bbb", slots.get(1).getName());
+ assertEquals("ccc", slots.get(2).getName());
}
@Test
public void testGetNonexistingSlot() {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
- assertEquals(0, statusBarIconList.getSlotIndex("aaa"));
- assertEquals(3, statusBarIconList.size());
- assertEquals(0, statusBarIconList.getSlotIndex("zzz")); // new content added in front
- assertEquals(1, statusBarIconList.getSlotIndex("aaa")); // slid back
- assertEquals(4, statusBarIconList.size());
+
+ statusBarIconList.getSlot("zzz");
+
+ List<Slot> slots = statusBarIconList.getSlots();
+ assertEquals(4, slots.size());
+ // new content added in front, so zzz should be first and aaa should slide back to second
+ assertEquals("zzz", slots.get(0).getName());
+ assertEquals("aaa", slots.get(1).getName());
}
@Test
public void testAddSlotSlidesIcons() {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
- statusBarIconList.setIcon(0, sbHolder);
- statusBarIconList.getSlotIndex("zzz"); // new content added in front
- assertNull(statusBarIconList.getIcon(0, TAG_PRIMARY));
- assertEquals(sbHolder, statusBarIconList.getIcon(1, TAG_PRIMARY));
+ statusBarIconList.setIcon("aaa", sbHolder);
+
+ statusBarIconList.getSlot("zzz");
+
+ List<Slot> slots = statusBarIconList.getSlots();
+ // new content added in front, so the holder we set on "aaa" should show up at index 1
+ assertNull(slots.get(0).getHolderForTag(TAG_PRIMARY));
+ assertEquals(sbHolder, slots.get(1).getHolderForTag(TAG_PRIMARY));
}
@Test
@@ -62,11 +86,13 @@ public class StatusBarIconListTest extends SysuiTestCase {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
StatusBarIconHolder sbHolderA = mock(StatusBarIconHolder.class);
StatusBarIconHolder sbHolderB = mock(StatusBarIconHolder.class);
- statusBarIconList.setIcon(0, sbHolderA);
- statusBarIconList.setIcon(1, sbHolderB);
- assertEquals(sbHolderA, statusBarIconList.getIcon(0, TAG_PRIMARY));
- assertEquals(sbHolderB, statusBarIconList.getIcon(1, TAG_PRIMARY));
- assertNull(statusBarIconList.getIcon(2, TAG_PRIMARY)); // icon not set
+
+ statusBarIconList.setIcon("aaa", sbHolderA);
+ statusBarIconList.setIcon("bbb", sbHolderB);
+
+ assertEquals(sbHolderA, statusBarIconList.getIconHolder("aaa", TAG_PRIMARY));
+ assertEquals(sbHolderB, statusBarIconList.getIconHolder("bbb", TAG_PRIMARY));
+ assertNull(statusBarIconList.getIconHolder("ccc", TAG_PRIMARY)); // icon not set
}
@Test
@@ -74,24 +100,31 @@ public class StatusBarIconListTest extends SysuiTestCase {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
StatusBarIconHolder sbHolderA = mock(StatusBarIconHolder.class);
StatusBarIconHolder sbHolderB = mock(StatusBarIconHolder.class);
- statusBarIconList.setIcon(0, sbHolderA);
- statusBarIconList.setIcon(1, sbHolderB);
- statusBarIconList.removeIcon(0, TAG_PRIMARY);
- assertNull(statusBarIconList.getIcon(0, TAG_PRIMARY)); // icon not set
+
+ statusBarIconList.setIcon("aaa", sbHolderA);
+ statusBarIconList.setIcon("bbb", sbHolderB);
+
+ statusBarIconList.removeIcon("aaa", TAG_PRIMARY);
+
+ assertNull(statusBarIconList.getIconHolder("aaa", TAG_PRIMARY)); // icon not set
}
@Test
public void testGetViewIndex_NoMultiples() {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
- statusBarIconList.setIcon(2, sbHolder);
- // Icon for item 2 is 0th child view.
- assertEquals(0, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
- statusBarIconList.setIcon(0, sbHolder);
- // Icon for item 0 is 0th child view,
- assertEquals(0, statusBarIconList.getViewIndex(0, TAG_PRIMARY));
- // and item 2 is now 1st child view.
- assertEquals(1, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
+
+ statusBarIconList.setIcon("ccc", sbHolder);
+
+ // Since only "ccc" has a holder set, it should be first
+ assertEquals(0, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
+
+ // Now, also set a holder for "aaa"
+ statusBarIconList.setIcon("aaa", sbHolder);
+
+ // Then "aaa" gets the first view index and "ccc" gets the second
+ assertEquals(0, statusBarIconList.getViewIndex("aaa", TAG_PRIMARY));
+ assertEquals(1, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
}
@Test
@@ -99,7 +132,7 @@ public class StatusBarIconListTest extends SysuiTestCase {
StatusBarIconList statusBarIconList = new StatusBarIconList(STATUS_BAR_SLOTS);
StatusBarIconHolder sbHolder = mock(StatusBarIconHolder.class);
- statusBarIconList.setIcon(2, sbHolder); // item 2, one icon 0th child
+ statusBarIconList.setIcon("ccc", sbHolder);
// All of these can be added to the same slot
// no tag bc it defaults to 0
@@ -111,23 +144,23 @@ public class StatusBarIconListTest extends SysuiTestCase {
int sb4Tag = 2;
when(sbHolder4.getTag()).thenReturn(sb4Tag);
- // Put a holder at slot 1, verify that it is first
- statusBarIconList.setIcon(1, sbHolder2);
- assertEquals(0, statusBarIconList.getViewIndex(1, TAG_PRIMARY));
-
- // Put another holder at slot 1, verify it's index 0 and the rest come after
- statusBarIconList.setIcon(1, sbHolder3);
- assertEquals(0, statusBarIconList.getViewIndex(1, sb3Tag));
- assertEquals(1, statusBarIconList.getViewIndex(1, TAG_PRIMARY));
- // First icon should be at the end
- assertEquals(2, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
-
- // Put another one in there just for good measure
- statusBarIconList.setIcon(1, sbHolder4);
- assertEquals(0, statusBarIconList.getViewIndex(1, sb4Tag));
- assertEquals(1, statusBarIconList.getViewIndex(1, sb3Tag));
- assertEquals(2, statusBarIconList.getViewIndex(1, TAG_PRIMARY));
- assertEquals(3, statusBarIconList.getViewIndex(2, TAG_PRIMARY));
+ // Put a holder for "bbb", verify that it is first
+ statusBarIconList.setIcon("bbb", sbHolder2);
+ assertEquals(0, statusBarIconList.getViewIndex("bbb", TAG_PRIMARY));
+
+ // Put another holder for "bbb" at slot 1, verify its index 0 and the rest come after
+ statusBarIconList.setIcon("bbb", sbHolder3);
+ assertEquals(0, statusBarIconList.getViewIndex("bbb", sb3Tag));
+ assertEquals(1, statusBarIconList.getViewIndex("bbb", TAG_PRIMARY));
+ // "ccc" should appear at the end
+ assertEquals(2, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
+
+ // Put another one in "bbb" just for good measure
+ statusBarIconList.setIcon("bbb", sbHolder4);
+ assertEquals(0, statusBarIconList.getViewIndex("bbb", sb4Tag));
+ assertEquals(1, statusBarIconList.getViewIndex("bbb", sb3Tag));
+ assertEquals(2, statusBarIconList.getViewIndex("bbb", TAG_PRIMARY));
+ assertEquals(3, statusBarIconList.getViewIndex("ccc", TAG_PRIMARY));
}
/**
@@ -172,4 +205,4 @@ public class StatusBarIconListTest extends SysuiTestCase {
return true;
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 0c1d04253bf5..aa08440d8cbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -275,21 +275,18 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
// Should be false to start, so no invocations
mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, false /* animated */);
- verify(mKeyguardUpdateMonitor, never()).onKeyguardOccludedChanged(anyBoolean());
verify(mKeyguardStateController, never()).notifyKeyguardState(anyBoolean(), anyBoolean());
clearInvocations(mKeyguardUpdateMonitor);
clearInvocations(mKeyguardStateController);
mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
- verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true);
verify(mKeyguardStateController).notifyKeyguardState(true, true);
clearInvocations(mKeyguardUpdateMonitor);
clearInvocations(mKeyguardStateController);
mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
- verify(mKeyguardUpdateMonitor, never()).onKeyguardOccludedChanged(anyBoolean());
verify(mKeyguardStateController, never()).notifyKeyguardState(anyBoolean(), anyBoolean());
}
@@ -299,7 +296,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager.show(null);
mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
- verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true);
verify(mKeyguardStateController).notifyKeyguardState(true, true);
}
@@ -309,7 +305,6 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mStatusBarKeyguardViewManager.show(null);
mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
- verify(mKeyguardUpdateMonitor).onKeyguardOccludedChanged(true);
verify(mKeyguardStateController).notifyKeyguardState(true, true);
}
@@ -389,6 +384,16 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ public void testBouncerIsOrWillBeShowing_whenBouncerIsInTransit() {
+ when(mBouncer.isShowing()).thenReturn(false);
+ when(mBouncer.inTransit()).thenReturn(true);
+
+ assertTrue(
+ "Is or will be showing should be true when bouncer is in transit",
+ mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing());
+ }
+
+ @Test
public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
// GIVEN alt auth exists, unlocking with biometric isn't allowed
mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
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 ecea14c6a522..f53f5fb2aebd 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
@@ -59,18 +59,15 @@ import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationClickNotifier;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -127,8 +124,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
@Mock
private ShadeControllerImpl mShadeController;
@Mock
- private NotifPipelineFlags mNotifPipelineFlags;
- @Mock
private NotifPipeline mNotifPipeline;
@Mock
private NotificationVisibilityProvider mVisibilityProvider;
@@ -148,15 +143,13 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private ActivityLaunchAnimator mActivityLaunchAnimator;
@Mock
private InteractionJankMonitor mJankMonitor;
- private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
- private NotificationTestHelper mNotificationTestHelper;
+ private final FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private ExpandableNotificationRow mNotificationRow;
private ExpandableNotificationRow mBubbleNotificationRow;
private final Answer<Void> mCallOnDismiss = answerVoid(
(OnDismissAction dismissAction, Runnable cancel,
Boolean afterKeyguardGone) -> dismissAction.onDismiss());
- private ArrayList<NotificationEntry> mActiveNotifications;
@Before
public void setUp() throws Exception {
@@ -165,29 +158,28 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
when(mContentIntent.getIntent()).thenReturn(mContentIntentInner);
- mNotificationTestHelper = new NotificationTestHelper(
+ NotificationTestHelper notificationTestHelper = new NotificationTestHelper(
mContext,
mDependency,
TestableLooper.get(this));
// Create standard notification with contentIntent
- mNotificationRow = mNotificationTestHelper.createRow();
+ mNotificationRow = notificationTestHelper.createRow();
StatusBarNotification sbn = mNotificationRow.getEntry().getSbn();
sbn.getNotification().contentIntent = mContentIntent;
sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
// Create bubble notification row with contentIntent
- mBubbleNotificationRow = mNotificationTestHelper.createBubble();
+ mBubbleNotificationRow = notificationTestHelper.createBubble();
StatusBarNotification bubbleSbn = mBubbleNotificationRow.getEntry().getSbn();
bubbleSbn.getNotification().contentIntent = mContentIntent;
bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
- mActiveNotifications = new ArrayList<>();
- mActiveNotifications.add(mNotificationRow.getEntry());
- mActiveNotifications.add(mBubbleNotificationRow.getEntry());
- when(mEntryManager.getVisibleNotifications()).thenReturn(mActiveNotifications);
+ ArrayList<NotificationEntry> activeNotifications = new ArrayList<>();
+ activeNotifications.add(mNotificationRow.getEntry());
+ activeNotifications.add(mBubbleNotificationRow.getEntry());
+ when(mEntryManager.getVisibleNotifications()).thenReturn(activeNotifications);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
- when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
when(mOnUserInteractionCallback.registerFutureDismissal(eq(mNotificationRow.getEntry()),
anyInt())).thenReturn(mFutureDismissalRunnable);
when(mVisibilityProvider.obtain(anyString(), anyBoolean()))
@@ -207,23 +199,19 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mNotificationActivityStarter =
new StatusBarNotificationActivityStarter(
getContext(),
- mock(CommandQueue.class),
mHandler,
mUiBgExecutor,
- mEntryManager,
mNotifPipeline,
mVisibilityProvider,
headsUpManager,
mActivityStarter,
mClickNotifier,
- mock(StatusBarStateController.class),
mStatusBarKeyguardViewManager,
mock(KeyguardManager.class),
mock(IDreamManager.class),
Optional.of(mBubblesManager),
() -> mAssistManager,
mRemoteInputManager,
- mock(NotificationGroupManagerLegacy.class),
mock(NotificationLockscreenUserManager.class),
mShadeController,
mKeyguardStateController,
@@ -231,7 +219,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mock(LockPatternUtils.class),
mock(StatusBarRemoteInputCallback.class),
mActivityIntentHelper,
- mNotifPipelineFlags,
mock(MetricsLogger.class),
mock(StatusBarNotificationActivityStarterLogger.class),
mOnUserInteractionCallback,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 12c0c92c59e8..63014667b110 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -33,7 +33,6 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.FakeMetricsLogger;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.ForegroundServiceNotificationListener;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
@@ -49,7 +48,6 @@ import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
@@ -60,7 +58,6 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -123,15 +120,12 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
mock(NotificationLockscreenUserManager.class),
mock(SysuiStatusBarStateController.class),
mock(NotifShadeEventSource.class),
- mock(NotificationEntryManager.class),
mock(NotificationMediaManager.class),
mock(NotificationGutsManager.class),
- mock(KeyguardUpdateMonitor.class),
lockscreenGestureLogger,
mInitController,
mNotificationInterruptStateProvider,
mock(NotificationRemoteInputManager.class),
- mock(ConfigurationController.class),
mock(NotifPipelineFlags.class),
mock(NotificationRemoteInputManager.Callback.class),
mock(NotificationListContainer.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 3d03c4750869..6f9e60fc5d69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -44,6 +44,7 @@ import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogcatEchoTracker;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -112,6 +113,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+ mDependency.injectMockDependency(DarkIconDispatcher.class);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
index eaad69c6b9d2..66367ecfc95c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
@@ -23,6 +23,7 @@ import android.view.LayoutInflater
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.policy.UserSwitcherController
@@ -46,6 +47,8 @@ class UserSwitcherActivityTest : SysuiTestCase() {
@Mock
private lateinit var layoutInflater: LayoutInflater
@Mock
+ private lateinit var falsingCollector: FalsingCollector
+ @Mock
private lateinit var falsingManager: FalsingManager
@Mock
private lateinit var userManager: UserManager
@@ -59,6 +62,7 @@ class UserSwitcherActivityTest : SysuiTestCase() {
userSwitcherController,
broadcastDispatcher,
layoutInflater,
+ falsingCollector,
falsingManager,
userManager,
userTracker
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 2e58fc4f93fa..2a7feb02abf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -71,6 +71,7 @@ import android.testing.TestableLooper;
import android.util.Pair;
import android.util.SparseArray;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
import androidx.test.filters.SmallTest;
@@ -265,6 +266,8 @@ public class BubblesTest extends SysuiTestCase {
ShellExecutor syncExecutor = new SyncExecutor();
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
+ when(mNotificationShadeWindowView.getViewTreeObserver())
+ .thenReturn(mock(ViewTreeObserver.class));
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
diff --git a/packages/VpnDialogs/res/values-te/strings.xml b/packages/VpnDialogs/res/values-te/strings.xml
index 8f8ff0778d06..78843360bdab 100644
--- a/packages/VpnDialogs/res/values-te/strings.xml
+++ b/packages/VpnDialogs/res/values-te/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="prompt" msgid="3183836924226407828">"కనెక్షన్ రిక్వెస్ట్‌"</string>
- <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN సక్రియంగా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; కనిపిస్తుంది."</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించగలగడానికి VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు మూలాన్ని విశ్వసిస్తే మాత్రమే ఆమోదించండి. VPN యాక్టివ్‌గా ఉన్నప్పుడు మీ స్క్రీన్ ఎగువన &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; కనిపిస్తుంది."</string>
<string name="warning" product="tv" msgid="5188957997628124947">"నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించగలగడానికి, <xliff:g id="APP">%s</xliff:g> VPN కనెక్షన్‌ను సెటప్ చేయాలనుకుంటోంది. మీరు సోర్స్‌ను విశ్వసిస్తే మాత్రమే ఆమోదించండి. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; VPN యాక్టివ్‌గా ఉన్నప్పుడు మీ స్క్రీన్ పై కనిపిస్తుంది."</string>
<string name="legacy_title" msgid="192936250066580964">"VPN కనెక్ట్ చేయబడింది"</string>
<string name="session" msgid="6470628549473641030">"సెషన్:"</string>
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 79f590f8384a..6eabc981e9fe 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -114,6 +114,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowAttributes;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
import android.view.accessibility.IAccessibilityManager;
@@ -3554,6 +3555,26 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
+ /**
+ * Sets the {@link AccessibilityWindowAttributes} to the window associated with the given
+ * window id.
+ *
+ * @param displayId The display id of the window.
+ * @param windowId The id of the window
+ * @param userId The user id.
+ * @param attributes The accessibility window attributes.
+ */
+ @Override
+ public void setAccessibilityWindowAttributes(int displayId, int windowId, int userId,
+ AccessibilityWindowAttributes attributes) {
+ if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) {
+ mTraceManager.logTrace(LOG_TAG + ".setAccessibilityWindowAttributes",
+ FLAGS_ACCESSIBILITY_MANAGER);
+ }
+ mA11yWindowManager.setAccessibilityWindowAttributes(displayId, windowId, userId,
+ attributes);
+ }
+
@Override
@RequiresPermission(Manifest.permission.SET_SYSTEM_AUDIO_CAPTION)
public void setSystemAudioCaptioningEnabled(boolean isEnabled, int userId) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index e7ade3dbe4a4..676bde7ed00f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -43,6 +43,7 @@ import android.view.WindowInfo;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowAttributes;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -120,6 +121,43 @@ public class AccessibilityWindowManager {
private final SparseArray<IBinder> mWindowIdMap = new SparseArray<>();
/**
+ * Map of window id and window attribute hierarchy.
+ * The key is the window id when the ViewRootImpl register to accessibility, and the value is
+ * its window attribute .
+ */
+ private final SparseArray<AccessibilityWindowAttributes> mWindowAttributes =
+ new SparseArray<>();
+
+ /**
+ * Sets the {@link AccessibilityWindowAttributes} to the window associated with the given
+ * window id.
+ *
+ * @param displayId The display id of the window.
+ * @param windowId The id of the window
+ * @param userId The user id.
+ * @param attributes The accessibility window attributes.
+ */
+ public void setAccessibilityWindowAttributes(int displayId, int windowId, int userId,
+ AccessibilityWindowAttributes attributes) {
+ boolean shouldComputeWindows = false;
+ synchronized (mLock) {
+ final int resolvedUserId =
+ mSecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(userId);
+ if (getWindowTokenForUserAndWindowIdLocked(resolvedUserId, windowId) == null) {
+ return;
+ }
+ final AccessibilityWindowAttributes currentAttrs = mWindowAttributes.get(windowId);
+ if (currentAttrs == null || !currentAttrs.equals(attributes)) {
+ mWindowAttributes.put(windowId, attributes);
+ shouldComputeWindows = findWindowInfoByIdLocked(windowId) != null;
+ }
+ }
+ if (shouldComputeWindows) {
+ mWindowManagerInternal.computeWindowsForAccessibility(displayId);
+ }
+ }
+
+ /**
* This class implements {@link WindowManagerInternal.WindowsForAccessibilityCallback} to
* receive {@link WindowInfo}s from window manager when there's an accessibility change in
* window and holds window lists information per display.
@@ -359,6 +397,7 @@ public class AccessibilityWindowManager {
public void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows) {
synchronized (mLock) {
+ updateWindowsByWindowAttributesLocked(windows);
if (DEBUG) {
Slog.i(LOG_TAG, "Display Id = " + mDisplayId);
Slog.i(LOG_TAG, "Windows changed: " + windows);
@@ -376,6 +415,24 @@ public class AccessibilityWindowManager {
}
}
+ private void updateWindowsByWindowAttributesLocked(List<WindowInfo> windows) {
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowInfo windowInfo = windows.get(i);
+ final IBinder token = windowInfo.token;
+ final int windowId = findWindowIdLocked(
+ mAccessibilityUserManager.getCurrentUserIdLocked(), token);
+ updateWindowWithWindowAttributes(windowInfo, mWindowAttributes.get(windowId));
+ }
+ }
+
+ private void updateWindowWithWindowAttributes(@NonNull WindowInfo windowInfo,
+ @Nullable AccessibilityWindowAttributes attributes) {
+ if (attributes == null) {
+ return;
+ }
+ windowInfo.title = attributes.getWindowTitle();
+ }
+
private boolean shouldUpdateWindowsLocked(boolean forceSend,
@NonNull List<WindowInfo> windows) {
if (forceSend) {
@@ -1223,6 +1280,7 @@ public class AccessibilityWindowManager {
binder, AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
}
unregisterIdLocked(windowId);
+ mWindowAttributes.remove(windowId);
}
/**
@@ -1872,5 +1930,10 @@ public class AccessibilityWindowManager {
observer.dumpLocked(fd, pw, args);
}
}
+ pw.println();
+ pw.append("Window attributes:[");
+ pw.append(mWindowAttributes.toString());
+ pw.append("]");
+ pw.println();
}
}
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 1af8ad344190..84707a8d9c00 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -398,18 +398,7 @@ public class AppPredictionPerUserService extends
final IBinder.DeathRecipient mDeathRecipient;
private final RemoteCallbackList<IPredictionCallback> mCallbacks =
- new RemoteCallbackList<IPredictionCallback>() {
- @Override
- public void onCallbackDied(IPredictionCallback callback) {
- if (DEBUG) {
- Slog.d(TAG, "Binder died for session Id=" + mSessionId
- + " and callback=" + callback.asBinder());
- }
- if (mCallbacks.getRegisteredCallbackCount() == 0) {
- destroy();
- }
- }
- };
+ new RemoteCallbackList<>();
AppPredictionSessionInfo(
@NonNull final AppPredictionSessionId id,
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 9466a312f823..9b11a68e3860 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -125,6 +125,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.IRemoteViewsFactory;
import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
import com.android.server.WidgetBackupProvider;
import org.xmlpull.v1.XmlPullParser;
@@ -270,7 +271,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mSaveStateHandler = BackgroundThread.getHandler();
- mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
+ final ServiceThread serviceThread = new ServiceThread(TAG,
+ android.os.Process.THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
+ serviceThread.start();
+ mCallbackHandler = new CallbackHandler(serviceThread.getLooper());
mBackupRestoreController = new BackupRestoreController();
mSecurityPolicy = new SecurityPolicy();
mIsProviderInfoPersisted = !ActivityManager.isLowRamDeviceStatic()
@@ -313,26 +317,26 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
packageFilter.addDataScheme("package");
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- packageFilter, null, null);
+ packageFilter, null, mCallbackHandler);
// Register for events related to sdcard installation.
IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- sdFilter, null, null);
+ sdFilter, null, mCallbackHandler);
IntentFilter offModeFilter = new IntentFilter();
offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- offModeFilter, null, null);
+ offModeFilter, null, mCallbackHandler);
IntentFilter suspendPackageFilter = new IntentFilter();
suspendPackageFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
suspendPackageFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- suspendPackageFilter, null, null);
+ suspendPackageFilter, null, mCallbackHandler);
}
private void registerOnCrossProfileProvidersChangedListener() {
@@ -1224,11 +1228,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
try {
// Ask ActivityManager to bind it. Notice that we are binding the service with the
// caller app instead of DevicePolicyManagerService.
- if(ActivityManager.getService().bindService(
+ if (ActivityManager.getService().bindService(
caller, activtiyToken, intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
- connection, flags, mContext.getOpPackageName(),
- widget.provider.getUserId()) != 0) {
+ connection, flags & (Context.BIND_AUTO_CREATE
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
+ mContext.getOpPackageName(), widget.provider.getUserId()) != 0) {
// Add it to the mapping of RemoteViewsService to appWidgetIds so that we
// can determine when we can call back to the RemoteViewsService later to
diff --git a/services/art-profile b/services/art-profile
index cb9dbb5e8e86..f5be083ff926 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -13194,23 +13194,23 @@ PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSugg
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl$$ExternalSyntheticLambda5;->accept(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl$$ExternalSyntheticLambda6;-><init>()V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl$$ExternalSyntheticLambda6;->accept(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$3cUMi5AwXItCfiFDVCUXCimE1C8(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$3cUMi5AwXItCfiFDVCUXCimE1C8(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$4eD-NhaAQgAaWV4xWXp6fTTGpK8(Ljava/lang/Object;ZZ)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$93C0LeU2EHcI07fDOWJQBHwvRtc(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$93C0LeU2EHcI07fDOWJQBHwvRtc(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$T6KGeNAHRvMAx6UVwQDBgY5g03s(Ljava/lang/Object;Landroid/view/autofill/AutofillId;ZZ)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$XS1N3pz3fznES_41qVCFW0CXwhs(Ljava/lang/Object;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$_toALHf9LhzDDXXTVXT8BjqBe_E(Ljava/lang/Object;ZZ)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->$r8$lambda$nYWwnndWe0-hXzKg3FU2C6MB78w(Ljava/lang/Object;ZZ)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;-><init>(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;-><init>(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl-IA;)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsRequest$1(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsRequest$1(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsSessionInvalidated$6(Ljava/lang/Object;)V
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsUnsupported$0(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInlineSuggestionsUnsupported$0(Ljava/lang/Object;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodFinishInput$5(Ljava/lang/Object;ZZ)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodFinishInputView$4(Ljava/lang/Object;ZZ)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodStartInput$2(Ljava/lang/Object;Landroid/view/autofill/AutofillId;ZZ)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->lambda$onInputMethodStartInputView$3(Ljava/lang/Object;ZZ)V
-HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsSessionInvalidated()V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInlineSuggestionsUnsupported()V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInputMethodFinishInput()V
@@ -13219,7 +13219,7 @@ PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSugg
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInputMethodStartInput(Landroid/view/autofill/AutofillId;)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession$InlineSuggestionsRequestCallbackImpl;->onInputMethodStartInputView()V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$fgetmHandler(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;)Landroid/os/Handler;
-PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeRequest(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeRequest(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeSessionInvalidated(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeStatusUpdated(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;Landroid/view/autofill/AutofillId;ZZ)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->-$$Nest$mhandleOnReceiveImeStatusUpdated(Lcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;ZZ)V
@@ -13228,7 +13228,7 @@ PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;-><clinit>
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;-><init>(Lcom/android/server/inputmethod/InputMethodManagerInternal;ILandroid/content/ComponentName;Landroid/os/Handler;Ljava/lang/Object;Landroid/view/autofill/AutofillId;Ljava/util/function/Consumer;Landroid/os/Bundle;Lcom/android/server/autofill/ui/InlineFillUi$InlineUiEventCallback;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->destroySessionLocked()V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->getInlineSuggestionsRequestLocked()Ljava/util/Optional;
-HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
PLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeSessionInvalidated()V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeStatusUpdated(Landroid/view/autofill/AutofillId;ZZ)V
HPLcom/android/server/autofill/AutofillInlineSuggestionsRequestSession;->handleOnReceiveImeStatusUpdated(ZZ)V
@@ -23835,23 +23835,23 @@ PLcom/android/server/inputmethod/HandwritingModeController;->initializeHandwriti
PLcom/android/server/inputmethod/HandwritingModeController;->reset()V
PLcom/android/server/inputmethod/HandwritingModeController;->reset(Z)V
PLcom/android/server/inputmethod/HandwritingModeController;->startHandwritingSession(IIILandroid/os/IBinder;)Lcom/android/server/inputmethod/HandwritingModeController$HandwritingSession;
-PLcom/android/server/inputmethod/IInputMethodInvoker;-><init>(Lcom/android/internal/view/IInputMethod;)V
+PLcom/android/server/inputmethod/IInputMethodInvoker;-><init>(Lcom/android/internal/inputmethod/IInputMethod;)V
PLcom/android/server/inputmethod/IInputMethodInvoker;->asBinder()Landroid/os/IBinder;
HPLcom/android/server/inputmethod/IInputMethodInvoker;->bindInput(Landroid/view/inputmethod/InputBinding;)V
PLcom/android/server/inputmethod/IInputMethodInvoker;->changeInputMethodSubtype(Landroid/view/inputmethod/InputMethodSubtype;)V
-PLcom/android/server/inputmethod/IInputMethodInvoker;->create(Lcom/android/internal/view/IInputMethod;)Lcom/android/server/inputmethod/IInputMethodInvoker;
-PLcom/android/server/inputmethod/IInputMethodInvoker;->createSession(Landroid/view/InputChannel;Lcom/android/internal/view/IInputSessionCallback;)V
+PLcom/android/server/inputmethod/IInputMethodInvoker;->create(Lcom/android/internal/inputmethod/IInputMethod;)Lcom/android/server/inputmethod/IInputMethodInvoker;
+PLcom/android/server/inputmethod/IInputMethodInvoker;->createSession(Landroid/view/InputChannel;Lcom/android/internal/inputmethod/IInputMethodSessionCallback;)V
PLcom/android/server/inputmethod/IInputMethodInvoker;->finishStylusHandwriting()V
PLcom/android/server/inputmethod/IInputMethodInvoker;->getBinderIdentityHashCode(Lcom/android/server/inputmethod/IInputMethodInvoker;)I
PLcom/android/server/inputmethod/IInputMethodInvoker;->getCallerMethodName()Ljava/lang/String;
PLcom/android/server/inputmethod/IInputMethodInvoker;->hideSoftInput(Landroid/os/IBinder;ILandroid/os/ResultReceiver;)Z
PLcom/android/server/inputmethod/IInputMethodInvoker;->initializeInternal(Landroid/os/IBinder;Lcom/android/internal/inputmethod/IInputMethodPrivilegedOperations;IZI)V
PLcom/android/server/inputmethod/IInputMethodInvoker;->logRemoteException(Landroid/os/RemoteException;)V
-PLcom/android/server/inputmethod/IInputMethodInvoker;->onCreateInlineSuggestionsRequest(Lcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;)V
+PLcom/android/server/inputmethod/IInputMethodInvoker;->onCreateInlineSuggestionsRequest(Lcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;)V
PLcom/android/server/inputmethod/IInputMethodInvoker;->onNavButtonFlagsChanged(I)V
-HPLcom/android/server/inputmethod/IInputMethodInvoker;->setSessionEnabled(Lcom/android/internal/view/IInputMethodSession;Z)V
+HPLcom/android/server/inputmethod/IInputMethodInvoker;->setSessionEnabled(Lcom/android/internal/inputmethod/IInputMethodSession;Z)V
HPLcom/android/server/inputmethod/IInputMethodInvoker;->showSoftInput(Landroid/os/IBinder;ILandroid/os/ResultReceiver;)Z
-HPLcom/android/server/inputmethod/IInputMethodInvoker;->startInput(Landroid/os/IBinder;Lcom/android/internal/view/IInputContext;Landroid/view/inputmethod/EditorInfo;ZILandroid/window/ImeOnBackInvokedDispatcher;)V
+HPLcom/android/server/inputmethod/IInputMethodInvoker;->startInput(Landroid/os/IBinder;Lcom/android/internal/inputmethod/IRemoteInputConnection;Landroid/view/inputmethod/EditorInfo;ZILandroid/window/ImeOnBackInvokedDispatcher;)V
HPLcom/android/server/inputmethod/IInputMethodInvoker;->unbindInput()V
HSPLcom/android/server/inputmethod/ImePlatformCompatUtils;-><init>()V
HPLcom/android/server/inputmethod/ImePlatformCompatUtils;->isChangeEnabledByUid(JI)Z
@@ -23923,7 +23923,7 @@ PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->getEnabledInputM
PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->getInputMethodListAsUser(I)Ljava/util/List;
PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->hideCurrentInputMethod(I)V
PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->maybeFinishStylusHandwriting()V
-PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->onCreateInlineSuggestionsRequest(ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;)V
+PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->onCreateInlineSuggestionsRequest(ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;)V
HSPLcom/android/server/inputmethod/InputMethodManagerInternal$1;->onImeParentChanged()V
PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->removeImeSurface()V
PLcom/android/server/inputmethod/InputMethodManagerInternal$1;->unbindAccessibilityFromCurrentClient(I)V
@@ -23940,7 +23940,7 @@ HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticL
HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda2;->run()V
HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda3;-><init>(Lcom/android/server/wm/WindowManagerInternal;)V
PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda3;->getDisplayImePolicy(I)I
-PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda4;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)V
+PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda4;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)V
PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda4;->getOrThrow()Ljava/lang/Object;
HPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda5;-><init>()V
HPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda5;->test(Ljava/lang/Object;)Z
@@ -23950,7 +23950,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLam
HSPLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda9;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
PLcom/android/server/inputmethod/InputMethodManagerService$$ExternalSyntheticLambda9;->accept(Ljava/lang/Object;)V
HPLcom/android/server/inputmethod/InputMethodManagerService$1;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/IInputMethodInvoker;Landroid/view/InputChannel;)V
-HPLcom/android/server/inputmethod/InputMethodManagerService$1;->sessionCreated(Lcom/android/internal/view/IInputMethodSession;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$1;->sessionCreated(Lcom/android/internal/inputmethod/IInputMethodSession;)V
HSPLcom/android/server/inputmethod/InputMethodManagerService$2;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpAsProtoNoCheck(Ljava/io/FileDescriptor;)V
PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpCritical(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
@@ -23958,11 +23958,11 @@ PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpHigh(Ljava/io
PLcom/android/server/inputmethod/InputMethodManagerService$2;->dumpNormal(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
PLcom/android/server/inputmethod/InputMethodManagerService$AccessibilitySessionState;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;ILcom/android/internal/inputmethod/IAccessibilityInputMethodSession;)V
PLcom/android/server/inputmethod/InputMethodManagerService$AccessibilitySessionState;->toString()Ljava/lang/String;
-HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/view/IInputMethodClient;)V
+HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/inputmethod/IInputMethodClient;)V
HPLcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;->binderDied()V
-HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientState;-><init>(Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputContext;IIILcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;)V
+HSPLcom/android/server/inputmethod/InputMethodManagerService$ClientState;-><init>(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;IIILcom/android/server/inputmethod/InputMethodManagerService$ClientDeathRecipient;)V
HPLcom/android/server/inputmethod/InputMethodManagerService$ClientState;->toString()Ljava/lang/String;
-HPLcom/android/server/inputmethod/InputMethodManagerService$CreateInlineSuggestionsRequest;-><init>(Lcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Ljava/lang/String;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$CreateInlineSuggestionsRequest;-><init>(Lcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Ljava/lang/String;)V
HSPLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
HSPLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers-IA;)V
HPLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiverForAllUsers;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
@@ -23972,8 +23972,8 @@ PLcom/android/server/inputmethod/InputMethodManagerService$ImmsBroadcastReceiver
HSPLcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;)V
HSPLcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer-IA;)V
PLcom/android/server/inputmethod/InputMethodManagerService$InkWindowInitializer;->run()V
-HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;-><init>(Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Ljava/lang/String;ILandroid/os/IBinder;Lcom/android/server/inputmethod/InputMethodManagerService;)V
-HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/view/IInlineSuggestionsResponseCallback;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;-><init>(Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Ljava/lang/String;ILandroid/os/IBinder;Lcom/android/server/inputmethod/InputMethodManagerService;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsRequest(Landroid/view/inputmethod/InlineSuggestionsRequest;Lcom/android/internal/inputmethod/IInlineSuggestionsResponseCallback;)V
PLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsSessionInvalidated()V
PLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInlineSuggestionsUnsupported()V
HPLcom/android/server/inputmethod/InputMethodManagerService$InlineSuggestionsRequestCallbackDecorator;->onInputMethodFinishInput()V
@@ -24008,7 +24008,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->ge
PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->getInputMethodListAsUser(I)Ljava/util/List;
PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->hideCurrentInputMethod(I)V
HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->maybeFinishStylusHandwriting()V
-HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onCreateInlineSuggestionsRequest(ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onCreateInlineSuggestionsRequest(ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;)V
HPLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onImeParentChanged()V
PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->onSessionForAccessibilityCreated(ILcom/android/internal/inputmethod/IAccessibilityInputMethodSession;)V
PLcom/android/server/inputmethod/InputMethodManagerService$LocalServiceImpl;->removeImeSurface()V
@@ -24035,7 +24035,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->on
PLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->onPackagesUnsuspended([Ljava/lang/String;)V
PLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->onUidRemoved(I)V
HPLcom/android/server/inputmethod/InputMethodManagerService$MyPackageMonitor;->shouldRebuildInputMethodListLocked()Z+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HPLcom/android/server/inputmethod/InputMethodManagerService$SessionState;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/view/IInputMethodSession;Landroid/view/InputChannel;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$SessionState;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/inputmethod/IInputMethodSession;Landroid/view/InputChannel;)V
PLcom/android/server/inputmethod/InputMethodManagerService$SessionState;->toString()Ljava/lang/String;
HSPLcom/android/server/inputmethod/InputMethodManagerService$SettingsObserver;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/Handler;)V
PLcom/android/server/inputmethod/InputMethodManagerService$SettingsObserver;->onChange(ZLandroid/net/Uri;)V
@@ -24064,7 +24064,7 @@ HPLcom/android/server/inputmethod/InputMethodManagerService$StartInputHistory;->
HSPLcom/android/server/inputmethod/InputMethodManagerService$StartInputHistory;->getEntrySize()I
PLcom/android/server/inputmethod/InputMethodManagerService$StartInputInfo;-><clinit>()V
HPLcom/android/server/inputmethod/InputMethodManagerService$StartInputInfo;-><init>(ILandroid/os/IBinder;ILjava/lang/String;IZIILandroid/os/IBinder;Landroid/view/inputmethod/EditorInfo;II)V
-HPLcom/android/server/inputmethod/InputMethodManagerService$UserSwitchHandlerTask;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService$UserSwitchHandlerTask;-><init>(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)V
HPLcom/android/server/inputmethod/InputMethodManagerService$UserSwitchHandlerTask;->run()V
PLcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;->-$$Nest$fgetmMatrix(Lcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;)Landroid/graphics/Matrix;
PLcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;->-$$Nest$fgetmParentClient(Lcom/android/server/inputmethod/InputMethodManagerService$VirtualDisplayInfo;)Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;
@@ -24072,7 +24072,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$1QzpuuZ6
HSPLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$AhkKGaXMb2go3kAOJFxNNwN_Wcw(Lcom/android/server/inputmethod/InputMethodManagerService;I)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$F9EIkbJ0j0nkV0RkbPOhyw9yI_8(Ljava/util/List;ILcom/android/server/inputmethod/InputMethodManagerInternal$InputMethodListListener;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$XUIWnM1I-xqMtdWJBk3rvGL6t0I(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/OverlayableSystemBooleanResourceWrapper;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$bNnzxTzGOLxDTcZA3PdLo_4mWHU(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)Ljava/lang/Integer;
+PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$bNnzxTzGOLxDTcZA3PdLo_4mWHU(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)Ljava/lang/Integer;
PLcom/android/server/inputmethod/InputMethodManagerService;->$r8$lambda$vz_z57ulRhr4T1Ld16KRvnRuVVc(Lcom/android/server/inputmethod/InputMethodManagerService;Z)V
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$fgetmAccessibilityManager(Lcom/android/server/inputmethod/InputMethodManagerService;)Landroid/view/accessibility/AccessibilityManager;
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$fgetmAccessibilityRequestingNoSoftKeyboard(Lcom/android/server/inputmethod/InputMethodManagerService;)Z
@@ -24093,7 +24093,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mchooseNewD
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mcreateInputContentUriToken(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Landroid/net/Uri;Ljava/lang/String;)Lcom/android/internal/inputmethod/IInputContentUriToken;
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mdumpAsStringNoCheck(Lcom/android/server/inputmethod/InputMethodManagerService;Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mdumpDebug(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/util/proto/ProtoOutputStream;J)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mexecuteOrSendMessage(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/view/IInputMethodClient;Landroid/os/Message;)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mexecuteOrSendMessage(Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/Message;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mgetCurMethodLocked(Lcom/android/server/inputmethod/InputMethodManagerService;)Lcom/android/server/inputmethod/IInputMethodInvoker;
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mgetEnabledInputMethodListLocked(Lcom/android/server/inputmethod/InputMethodManagerService;I)Ljava/util/List;
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mgetInputMethodListLocked(Lcom/android/server/inputmethod/InputMethodManagerService;II)Ljava/util/List;
@@ -24101,7 +24101,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mhandleShel
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mhandleShellCommandTraceInputMethod(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/ShellCommand;)I
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mhideMySoftInput(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;I)V
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mnotifyUserAction(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$monCreateInlineSuggestionsRequestLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Z)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$monCreateInlineSuggestionsRequestLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Z)V
HSPLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mpublishLocalService(Lcom/android/server/inputmethod/InputMethodManagerService;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mreportFullscreenMode(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Z)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mreportStartInput(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Landroid/os/IBinder;)V
@@ -24110,10 +24110,10 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$msetInputMe
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mshouldOfferSwitchingToNextInputMethod(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;)Z
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mshowMySoftInput(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;I)V
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mswitchToPreviousInputMethod(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;)Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mswitchUserOnHandlerLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/view/IInputMethodClient;)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mswitchUserOnHandlerLocked(Lcom/android/server/inputmethod/InputMethodManagerService;ILcom/android/internal/inputmethod/IInputMethodClient;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->-$$Nest$mupdateStatusIcon(Lcom/android/server/inputmethod/InputMethodManagerService;Landroid/os/IBinder;Ljava/lang/String;I)V
HSPLcom/android/server/inputmethod/InputMethodManagerService;-><init>(Landroid/content/Context;)V
-HSPLcom/android/server/inputmethod/InputMethodManagerService;->addClient(Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputContext;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;
+HSPLcom/android/server/inputmethod/InputMethodManagerService;->addClient(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;
HPLcom/android/server/inputmethod/InputMethodManagerService;->advanceSequenceNumberLocked()V
HPLcom/android/server/inputmethod/InputMethodManagerService;->applyImeVisibility(Landroid/os/IBinder;Landroid/os/IBinder;Z)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->attachNewAccessibilityLocked(IZI)Lcom/android/internal/inputmethod/InputBindResult;
@@ -24121,8 +24121,8 @@ HPLcom/android/server/inputmethod/InputMethodManagerService;->attachNewInputLock
HSPLcom/android/server/inputmethod/InputMethodManagerService;->buildInputMethodListLocked(Z)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->calledFromValidUserLocked()Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/Context;Landroid/app/ContextImpl;]Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;
HPLcom/android/server/inputmethod/InputMethodManagerService;->calledWithValidTokenLocked(Landroid/os/IBinder;)Z
-HPLcom/android/server/inputmethod/InputMethodManagerService;->canInteractWithImeLocked(ILcom/android/internal/view/IInputMethodClient;Ljava/lang/String;)Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->canShowInputMethodPickerLocked(Lcom/android/internal/view/IInputMethodClient;)Z
+HPLcom/android/server/inputmethod/InputMethodManagerService;->canInteractWithImeLocked(ILcom/android/internal/inputmethod/IInputMethodClient;Ljava/lang/String;)Z
+PLcom/android/server/inputmethod/InputMethodManagerService;->canShowInputMethodPickerLocked(Lcom/android/internal/inputmethod/IInputMethodClient;)Z
PLcom/android/server/inputmethod/InputMethodManagerService;->chooseNewDefaultIMELocked()Z
HPLcom/android/server/inputmethod/InputMethodManagerService;->clearClientSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->clearClientSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;I)V
@@ -24136,7 +24136,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->createInputContentU
PLcom/android/server/inputmethod/InputMethodManagerService;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->dumpAsStringNoCheck(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;Z)V
PLcom/android/server/inputmethod/InputMethodManagerService;->dumpDebug(Landroid/util/proto/ProtoOutputStream;J)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->executeOrSendMessage(Lcom/android/internal/view/IInputMethodClient;Landroid/os/Message;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->executeOrSendMessage(Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/Message;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->finishSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$AccessibilitySessionState;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->finishSessionLocked(Lcom/android/server/inputmethod/InputMethodManagerService$SessionState;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->getAppShowFlagsLocked()I
@@ -24159,7 +24159,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodList(
HPLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodListInternal(II)Ljava/util/List;
HPLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodListLocked(II)Ljava/util/List;
HPLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodNavButtonFlagsLocked()I
-PLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodWindowVisibleHeight(Lcom/android/internal/view/IInputMethodClient;)I
+PLcom/android/server/inputmethod/InputMethodManagerService;->getInputMethodWindowVisibleHeight(Lcom/android/internal/inputmethod/IInputMethodClient;)I
PLcom/android/server/inputmethod/InputMethodManagerService;->getLastBindTimeLocked()J
PLcom/android/server/inputmethod/InputMethodManagerService;->getLastInputMethodSubtype()Landroid/view/inputmethod/InputMethodSubtype;
PLcom/android/server/inputmethod/InputMethodManagerService;->getLastSwitchUserId(Landroid/os/ShellCommand;)I
@@ -24167,7 +24167,7 @@ HSPLcom/android/server/inputmethod/InputMethodManagerService;->getPackageManager
HSPLcom/android/server/inputmethod/InputMethodManagerService;->getSelectedMethodIdLocked()Ljava/lang/String;
HPLcom/android/server/inputmethod/InputMethodManagerService;->getSequenceNumberLocked()I
PLcom/android/server/inputmethod/InputMethodManagerService;->getVirtualDisplayToScreenMatrixLocked(II)Landroid/graphics/Matrix;
-HSPLcom/android/server/inputmethod/InputMethodManagerService;->handleMessage(Landroid/os/Message;)Z+]Landroid/media/AudioManagerInternal;Lcom/android/server/audio/AudioService$AudioServiceInternal;]Ljava/util/OptionalInt;Ljava/util/OptionalInt;]Lcom/android/server/inputmethod/InputMethodBindingController;Lcom/android/server/inputmethod/InputMethodBindingController;]Lcom/android/internal/view/IInputMethodSession;Lcom/android/internal/view/IInputMethodSession$Stub$Proxy;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/view/InputChannel;Landroid/view/InputChannel;]Lcom/android/server/inputmethod/HandwritingModeController;Lcom/android/server/inputmethod/HandwritingModeController;]Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/os/SomeArgs;Lcom/android/internal/os/SomeArgs;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
+HSPLcom/android/server/inputmethod/InputMethodManagerService;->handleMessage(Landroid/os/Message;)Z+]Landroid/media/AudioManagerInternal;Lcom/android/server/audio/AudioService$AudioServiceInternal;]Ljava/util/OptionalInt;Ljava/util/OptionalInt;]Lcom/android/server/inputmethod/InputMethodBindingController;Lcom/android/server/inputmethod/InputMethodBindingController;]Lcom/android/internal/inputmethod/IInputMethodSession;Lcom/android/internal/view/IInputMethodSession$Stub$Proxy;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/view/InputChannel;Landroid/view/InputChannel;]Lcom/android/server/inputmethod/HandwritingModeController;Lcom/android/server/inputmethod/HandwritingModeController;]Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/os/SomeArgs;Lcom/android/internal/os/SomeArgs;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
PLcom/android/server/inputmethod/InputMethodManagerService;->handleOptionsForCommandsThatOnlyHaveUserOption(Landroid/os/ShellCommand;)I
PLcom/android/server/inputmethod/InputMethodManagerService;->handleSetInteractive(Z)V
PLcom/android/server/inputmethod/InputMethodManagerService;->handleShellCommandEnableDisableInputMethod(Landroid/os/ShellCommand;Z)I
@@ -24179,7 +24179,7 @@ HPLcom/android/server/inputmethod/InputMethodManagerService;->handleShellCommand
PLcom/android/server/inputmethod/InputMethodManagerService;->hasConnectionLocked()Z
HPLcom/android/server/inputmethod/InputMethodManagerService;->hideCurrentInputLocked(Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z+]Lcom/android/server/inputmethod/InputMethodBindingController;Lcom/android/server/inputmethod/InputMethodBindingController;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/server/inputmethod/IInputMethodInvoker;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;
HPLcom/android/server/inputmethod/InputMethodManagerService;->hideMySoftInput(Landroid/os/IBinder;I)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->hideSoftInput(Lcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Lcom/android/internal/view/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/inputmethod/ImeTracing;Lcom/android/internal/inputmethod/ImeTracingServerImpl;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->hideSoftInput(Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lcom/android/server/inputmethod/InputMethodManagerService;Lcom/android/server/inputmethod/InputMethodManagerService;]Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/view/IInputMethodClient$Stub$Proxy;]Lcom/android/internal/inputmethod/ImeTracing;Lcom/android/internal/inputmethod/ImeTracingServerImpl;
HSPLcom/android/server/inputmethod/InputMethodManagerService;->hideStatusBarIconLocked()V
PLcom/android/server/inputmethod/InputMethodManagerService;->initializeImeLocked(Lcom/android/server/inputmethod/IInputMethodInvoker;Landroid/os/IBinder;IZ)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->isImeClientFocused(Landroid/os/IBinder;Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)Z
@@ -24188,7 +24188,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->isInlineSuggestions
PLcom/android/server/inputmethod/InputMethodManagerService;->isInputMethodPickerShownForTest()Z
PLcom/android/server/inputmethod/InputMethodManagerService;->isNonPreemptibleImeLocked(Ljava/lang/String;)Z
HPLcom/android/server/inputmethod/InputMethodManagerService;->isSelectedMethodBoundLocked()Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$getInputMethodWindowVisibleHeight$3(ILcom/android/internal/view/IInputMethodClient;)Ljava/lang/Integer;
+PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$getInputMethodWindowVisibleHeight$3(ILcom/android/internal/inputmethod/IInputMethodClient;)Ljava/lang/Integer;
PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$handleMessage$4(Ljava/util/List;ILcom/android/server/inputmethod/InputMethodManagerInternal$InputMethodListListener;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$handleShellCommandResetInputMethod$5(Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;Landroid/view/inputmethod/InputMethodInfo;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->lambda$handleShellCommandResetInputMethod$6(Ljava/io/PrintWriter;Landroid/view/inputmethod/InputMethodInfo;)V
@@ -24200,8 +24200,8 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->notifyUserAction(La
HPLcom/android/server/inputmethod/InputMethodManagerService;->obtainMessageIIIO(IIIILjava/lang/Object;)Landroid/os/Message;
HPLcom/android/server/inputmethod/InputMethodManagerService;->obtainMessageOO(ILjava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
PLcom/android/server/inputmethod/InputMethodManagerService;->onActionLocaleChanged()V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->onCreateInlineSuggestionsRequestLocked(ILcom/android/internal/view/InlineSuggestionsRequestInfo;Lcom/android/internal/view/IInlineSuggestionsRequestCallback;Z)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->onSessionCreated(Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/view/IInputMethodSession;Landroid/view/InputChannel;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->onCreateInlineSuggestionsRequestLocked(ILcom/android/internal/inputmethod/InlineSuggestionsRequestInfo;Lcom/android/internal/inputmethod/IInlineSuggestionsRequestCallback;Z)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->onSessionCreated(Lcom/android/server/inputmethod/IInputMethodInvoker;Lcom/android/internal/inputmethod/IInputMethodSession;Landroid/view/InputChannel;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->onShellCommand(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/lang/String;Landroid/os/ShellCallback;Landroid/os/ResultReceiver;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->onShowHideSoftInputRequested(ZLandroid/os/IBinder;I)V
HSPLcom/android/server/inputmethod/InputMethodManagerService;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -24212,13 +24212,13 @@ HSPLcom/android/server/inputmethod/InputMethodManagerService;->publishLocalServi
HSPLcom/android/server/inputmethod/InputMethodManagerService;->queryInputMethodServicesInternal(Landroid/content/Context;ILandroid/util/ArrayMap;Landroid/util/ArrayMap;Ljava/util/ArrayList;I)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->queryMethodMapForUser(I)Landroid/util/ArrayMap;
HPLcom/android/server/inputmethod/InputMethodManagerService;->reRequestCurrentClientSessionLocked()V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->removeClient(Lcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->removeClient(Lcom/android/internal/inputmethod/IInputMethodClient;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->removeImeSurface()V
HPLcom/android/server/inputmethod/InputMethodManagerService;->removeImeSurfaceFromWindowAsync(Landroid/os/IBinder;)V+]Landroid/os/Handler;Landroid/os/Handler;]Landroid/os/Message;Landroid/os/Message;
HPLcom/android/server/inputmethod/InputMethodManagerService;->reportFullscreenMode(Landroid/os/IBinder;Z)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->reportPerceptibleAsync(Landroid/os/IBinder;Z)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->reportStartInput(Landroid/os/IBinder;Landroid/os/IBinder;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->reportVirtualDisplayGeometryAsync(Lcom/android/internal/view/IInputMethodClient;I[F)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->reportVirtualDisplayGeometryAsync(Lcom/android/internal/inputmethod/IInputMethodClient;I[F)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->requestClientSessionForAccessibilityLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->requestClientSessionLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->resetCurrentMethodAndClientLocked(I)V
@@ -24229,7 +24229,7 @@ PLcom/android/server/inputmethod/InputMethodManagerService;->resetSystemUiLocked
HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleNotifyImeUidToAudioService(I)V
PLcom/android/server/inputmethod/InputMethodManagerService;->scheduleResetStylusHandwriting()V
HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleSetActiveToClient(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;ZZZ)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleSwitchUserTaskLocked(ILcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->scheduleSwitchUserTaskLocked(ILcom/android/internal/inputmethod/IInputMethodClient;)V
HSPLcom/android/server/inputmethod/InputMethodManagerService;->sendOnNavButtonFlagsChangedLocked()V
PLcom/android/server/inputmethod/InputMethodManagerService;->setAdditionalInputMethodSubtypes(Ljava/lang/String;[Landroid/view/inputmethod/InputMethodSubtype;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->setCurHostInputToken(Landroid/os/IBinder;Landroid/os/IBinder;)V
@@ -24249,20 +24249,20 @@ HPLcom/android/server/inputmethod/InputMethodManagerService;->shouldPreventImeSt
PLcom/android/server/inputmethod/InputMethodManagerService;->shouldRestoreImeVisibility(Landroid/os/IBinder;I)Z
HPLcom/android/server/inputmethod/InputMethodManagerService;->shouldShowImeSwitcherLocked(I)Z+]Landroid/view/inputmethod/InputMethodSubtype;Landroid/view/inputmethod/InputMethodSubtype;]Ljava/util/List;Ljava/util/ArrayList;]Lcom/android/server/wm/WindowManagerInternal;Lcom/android/server/wm/WindowManagerService$LocalService;]Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;Lcom/android/server/inputmethod/InputMethodUtils$InputMethodSettings;]Landroid/app/KeyguardManager;Landroid/app/KeyguardManager;]Lcom/android/server/inputmethod/InputMethodMenuController;Lcom/android/server/inputmethod/InputMethodMenuController;
HPLcom/android/server/inputmethod/InputMethodManagerService;->showCurrentInputLocked(Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z
-PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodAndSubtypeEnablerFromClient(Lcom/android/internal/view/IInputMethodClient;Ljava/lang/String;)V
-PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodPickerFromClient(Lcom/android/internal/view/IInputMethodClient;I)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodAndSubtypeEnablerFromClient(Lcom/android/internal/inputmethod/IInputMethodClient;Ljava/lang/String;)V
+PLcom/android/server/inputmethod/InputMethodManagerService;->showInputMethodPickerFromClient(Lcom/android/internal/inputmethod/IInputMethodClient;I)V
PLcom/android/server/inputmethod/InputMethodManagerService;->showMySoftInput(Landroid/os/IBinder;I)V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->showSoftInput(Lcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z
+HPLcom/android/server/inputmethod/InputMethodManagerService;->showSoftInput(Lcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;ILandroid/os/ResultReceiver;I)Z
HPLcom/android/server/inputmethod/InputMethodManagerService;->startImeTrace()V
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocus(ILcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternal(ILcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternalLocked(ILcom/android/internal/view/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;IILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
-HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputUncheckedLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/internal/view/IInputContext;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;Landroid/view/inputmethod/EditorInfo;IIILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocus(ILcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternal(ILcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;ILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputOrWindowGainedFocusInternalLocked(ILcom/android/internal/inputmethod/IInputMethodClient;Landroid/os/IBinder;IIILandroid/view/inputmethod/EditorInfo;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;IILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
+HPLcom/android/server/inputmethod/InputMethodManagerService;->startInputUncheckedLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;Lcom/android/internal/inputmethod/IRemoteInputConnection;Lcom/android/internal/inputmethod/IRemoteAccessibilityInputConnection;Landroid/view/inputmethod/EditorInfo;IIILandroid/window/ImeOnBackInvokedDispatcher;)Lcom/android/internal/inputmethod/InputBindResult;
PLcom/android/server/inputmethod/InputMethodManagerService;->startProtoDump([BILjava/lang/String;)V
PLcom/android/server/inputmethod/InputMethodManagerService;->stopImeTrace()V
PLcom/android/server/inputmethod/InputMethodManagerService;->switchToNextInputMethod(Landroid/os/IBinder;Z)Z
PLcom/android/server/inputmethod/InputMethodManagerService;->switchToPreviousInputMethod(Landroid/os/IBinder;)Z
-HPLcom/android/server/inputmethod/InputMethodManagerService;->switchUserOnHandlerLocked(ILcom/android/internal/view/IInputMethodClient;)V
+HPLcom/android/server/inputmethod/InputMethodManagerService;->switchUserOnHandlerLocked(ILcom/android/internal/inputmethod/IInputMethodClient;)V
HSPLcom/android/server/inputmethod/InputMethodManagerService;->systemRunning(Lcom/android/server/statusbar/StatusBarManagerService;)V
HPLcom/android/server/inputmethod/InputMethodManagerService;->tryReuseConnectionLocked(Lcom/android/server/inputmethod/InputMethodManagerService$ClientState;)Lcom/android/internal/inputmethod/InputBindResult;
HSPLcom/android/server/inputmethod/InputMethodManagerService;->unbindCurrentClientLocked(I)V
diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java
index 622396ccfa36..17c22e3afe9e 100644
--- a/services/companion/java/com/android/server/companion/PackageUtils.java
+++ b/services/companion/java/com/android/server/companion/PackageUtils.java
@@ -30,6 +30,7 @@ import android.companion.CompanionDeviceService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PackageInfoFlags;
@@ -39,8 +40,6 @@ import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.util.Slog;
-import com.android.internal.util.ArrayUtils;
-
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -65,15 +64,18 @@ final class PackageUtils {
static void enforceUsesCompanionDeviceFeature(@NonNull Context context,
@UserIdInt int userId, @NonNull String packageName) {
- final boolean requested = ArrayUtils.contains(
- getPackageInfo(context, userId, packageName).reqFeatures,
- FEATURE_COMPANION_DEVICE_SETUP);
-
- if (requested) {
- throw new IllegalStateException("Must declare uses-feature "
- + FEATURE_COMPANION_DEVICE_SETUP
- + " in manifest to use this API");
+ String requiredFeature = FEATURE_COMPANION_DEVICE_SETUP;
+
+ FeatureInfo[] requestedFeatures = getPackageInfo(context, userId, packageName).reqFeatures;
+ for (int i = 0; i < requestedFeatures.length; i++) {
+ if (requiredFeature.equals(requestedFeatures[i].name)) {
+ return;
+ }
}
+
+ throw new IllegalStateException("Must declare uses-feature "
+ + requiredFeature
+ + " in manifest to use this API");
}
/**
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 60636684302a..97582044fa0b 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -503,12 +503,6 @@ public abstract class PackageManagerInternal {
public abstract void pruneInstantApps();
/**
- * Prunes the cache of the APKs in the given APEXes.
- * @param apexPackageNames The list of APEX package names that may contain APK-in-APEX.
- */
- public abstract void pruneCachedApksInApex(@NonNull List<String> apexPackageNames);
-
- /**
* @return The SetupWizard package name.
*/
public abstract String getSetupWizardPackageName();
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 9cdb2df6bc79..83e3b499fc96 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -353,6 +353,8 @@ class StorageManagerService extends IStorageManager.Stub
private static final boolean DEFAULT_CHARGING_REQUIRED = true;
// Minimum GC interval sleep time in ms
private static final int DEFAULT_MIN_GC_SLEEPTIME = 10000;
+ // Target dirty segment ratio to aim to
+ private static final int DEFAULT_TARGET_DIRTY_RATIO = 80;
private volatile int mLifetimePercentThreshold;
private volatile int mMinSegmentsThreshold;
@@ -361,6 +363,7 @@ class StorageManagerService extends IStorageManager.Stub
private volatile float mLowBatteryLevel;
private volatile boolean mChargingRequired;
private volatile int mMinGCSleepTime;
+ private volatile int mTargetDirtyRatio;
private volatile boolean mNeedGC;
private volatile boolean mPassedLifetimeThresh;
@@ -1248,10 +1251,10 @@ class StorageManagerService extends IStorageManager.Stub
mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
// Binder entry point for kicking off an immediate fstrim
@Override
public void runMaintenance() {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
runIdleMaintenance(null);
}
@@ -2165,17 +2168,17 @@ class StorageManagerService extends IStorageManager.Stub
mCallbacks.unregister(listener);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.SHUTDOWN)
@Override
public void shutdown(final IStorageShutdownObserver observer) {
- enforcePermission(android.Manifest.permission.SHUTDOWN);
Slog.i(TAG, "Shutting down");
mHandler.obtainMessage(H_SHUTDOWN, observer).sendToTarget();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void mount(String volId) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
final VolumeInfo vol = findVolumeByIdOrThrow(volId);
if (isMountDisallowed(vol)) {
@@ -2241,9 +2244,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void unmount(String volId) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
final VolumeInfo vol = findVolumeByIdOrThrow(volId);
unmount(vol);
@@ -2265,9 +2268,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
@Override
public void format(String volId) {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
final VolumeInfo vol = findVolumeByIdOrThrow(volId);
final String fsUuid = vol.fsUuid;
@@ -2284,9 +2287,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
@Override
public void benchmark(String volId, IVoldTaskListener listener) {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
try {
mVold.benchmark(volId, new IVoldTaskListener.Stub() {
@@ -2323,9 +2326,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
@Override
public void partitionPublic(String diskId) {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
try {
@@ -2336,9 +2339,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
@Override
public void partitionPrivate(String diskId) {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
enforceAdminUser();
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
@@ -2350,9 +2353,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
@Override
public void partitionMixed(String diskId, int ratio) {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
enforceAdminUser();
final CountDownLatch latch = findOrCreateDiskScanLatch(diskId);
@@ -2364,9 +2367,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void setVolumeNickname(String fsUuid, String nickname) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
Objects.requireNonNull(fsUuid);
synchronized (mLock) {
@@ -2377,9 +2380,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void setVolumeUserFlags(String fsUuid, int flags, int mask) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
Objects.requireNonNull(fsUuid);
synchronized (mLock) {
@@ -2390,9 +2393,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void forgetVolume(String fsUuid) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
Objects.requireNonNull(fsUuid);
@@ -2414,9 +2417,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void forgetAllVolumes() {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
synchronized (mLock) {
for (int i = 0; i < mRecords.size(); i++) {
@@ -2446,9 +2449,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
@Override
public void fstrim(int flags, IVoldTaskListener listener) {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
try {
// Block based checkpoint process runs fstrim. So, if checkpoint is in progress
@@ -2581,6 +2584,8 @@ class StorageManagerService extends IStorageManager.Stub
"charging_required", DEFAULT_CHARGING_REQUIRED);
mMinGCSleepTime = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
"min_gc_sleeptime", DEFAULT_MIN_GC_SLEEPTIME);
+ mTargetDirtyRatio = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+ "target_dirty_ratio", DEFAULT_TARGET_DIRTY_RATIO);
// If we use the smart idle maintenance, we need to turn off GC in the traditional idle
// maintenance to avoid the conflict
@@ -2721,10 +2726,11 @@ class StorageManagerService extends IStorageManager.Stub
", dirty reclaim rate: " + mDirtyReclaimRate +
", segment reclaim weight: " + mSegmentReclaimWeight +
", period(min): " + sSmartIdleMaintPeriod +
- ", min gc sleep time(ms): " + mMinGCSleepTime);
+ ", min gc sleep time(ms): " + mMinGCSleepTime +
+ ", target dirty ratio: " + mTargetDirtyRatio);
mVold.setGCUrgentPace(avgWriteAmount, mMinSegmentsThreshold, mDirtyReclaimRate,
mSegmentReclaimWeight, sSmartIdleMaintPeriod,
- mMinGCSleepTime);
+ mMinGCSleepTime, mTargetDirtyRatio);
} else {
Slog.i(TAG, "Skipping smart idle maintenance - block based checkpoint in progress");
}
@@ -2737,9 +2743,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void setDebugFlags(int flags, int mask) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
if ((mask & (StorageManager.DEBUG_ADOPTABLE_FORCE_ON
| StorageManager.DEBUG_ADOPTABLE_FORCE_OFF)) != 0) {
@@ -2807,9 +2813,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) {
- enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
final VolumeInfo from;
final VolumeInfo to;
@@ -3013,12 +3019,12 @@ class StorageManagerService extends IStorageManager.Stub
mVold.commitChanges();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
/**
* Check if we should be mounting with checkpointing or are checkpointing now
*/
@Override
public boolean needsCheckpoint() throws RemoteException {
- enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
return mVold.needsCheckpoint();
}
@@ -3035,9 +3041,9 @@ class StorageManagerService extends IStorageManager.Stub
mVold.abortChanges(message, retry);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
@Override
public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
mVold.createUserKey(userId, serialNumber, ephemeral);
@@ -3046,9 +3052,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
@Override
public void destroyUserKey(int userId) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
mVold.destroyUserKey(userId);
@@ -3065,6 +3071,7 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
/*
* Add this secret to the set of ways we can recover a user's disk
* encryption key. Changing the secret for a disk encryption key is done in
@@ -3075,7 +3082,6 @@ class StorageManagerService extends IStorageManager.Stub
*/
@Override
public void addUserKeyAuth(int userId, int serialNumber, byte[] secret) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
mVold.addUserKeyAuth(userId, serialNumber, encodeBytes(secret));
@@ -3084,6 +3090,7 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
/*
* Store a user's disk encryption key without secret binding. Removing the
* secret for a disk encryption key is done in two phases. First, this
@@ -3093,7 +3100,6 @@ class StorageManagerService extends IStorageManager.Stub
*/
@Override
public void clearUserKeyAuth(int userId, int serialNumber, byte[] secret) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
mVold.clearUserKeyAuth(userId, serialNumber, encodeBytes(secret));
@@ -3102,13 +3108,13 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
/*
* Delete all bindings of a user's disk encryption key except the most
* recently added one.
*/
@Override
public void fixateNewestUserKeyAuth(int userId) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
mVold.fixateNewestUserKeyAuth(userId);
@@ -3152,6 +3158,7 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
@Override
public void lockUserKey(int userId) {
// Do not lock user 0 data for headless system user
@@ -3160,7 +3167,6 @@ class StorageManagerService extends IStorageManager.Stub
throw new IllegalArgumentException("Headless system user data cannot be locked..");
}
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
if (!isUserKeyUnlocked(userId)) {
Slog.d(TAG, "User " + userId + "'s CE storage is already locked");
@@ -3215,9 +3221,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
@Override
public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
prepareUserStorageInternal(volumeUuid, userId, serialNumber, flags);
@@ -3258,9 +3264,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
@Override
public void destroyUserStorage(String volumeUuid, int userId, int flags) {
- enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
try {
mVold.destroyUserStorage(volumeUuid, userId, flags);
@@ -4305,9 +4311,9 @@ class StorageManagerService extends IStorageManager.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE)
@Override
public int getExternalStorageMountMode(int uid, String packageName) {
- enforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE);
return mStorageManagerInternal.getExternalStorageMountMode(uid, packageName);
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 7cf790ad5b54..ef784bb278c0 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -160,6 +160,7 @@ public class Watchdog implements Dumpable {
public static final String[] AIDL_INTERFACE_PREFIXES_OF_INTEREST = new String[] {
"android.hardware.biometrics.face.IFace/",
"android.hardware.biometrics.fingerprint.IFingerprint/",
+ "android.hardware.input.processor.IInputProcessor/",
"android.hardware.light.ILights/",
"android.hardware.power.IPower/",
"android.hardware.power.stats.IPowerStats/",
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8368b4dfe070..61c0c75d6965 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2855,6 +2855,14 @@ public final class ActiveServices {
return -1;
}
ServiceRecord s = res.record;
+ final AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
+ final ProcessServiceRecord clientPsr = b.client.mServices;
+ if (clientPsr.numberOfConnections() >= mAm.mConstants.mMaxServiceConnectionsPerProcess) {
+ Slog.w(TAG, "bindService exceeded max service connection number per process, "
+ + "callerApp:" + callerApp.processName
+ + " intent:" + service);
+ return 0;
+ }
// The package could be frozen (meaning it's doing surgery), defer the actual
// binding until the package is unfrozen.
@@ -2905,7 +2913,6 @@ public final class ActiveServices {
mAm.grantImplicitAccess(callerApp.userId, service,
callerApp.uid, UserHandle.getAppId(s.appInfo.uid));
- AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage, res.aliasComponent);
@@ -2916,7 +2923,6 @@ public final class ActiveServices {
if (activity != null) {
activity.addConnection(c);
}
- final ProcessServiceRecord clientPsr = b.client.mServices;
clientPsr.addConnection(c);
c.startAssociationIfNeeded();
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index c3720965e7f6..13a13f2f4b3c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -196,6 +196,8 @@ final class ActivityManagerConstants extends ContentObserver {
static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000;
static final boolean DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE = true;
+ static final int DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS = 3000;
+
/**
* Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
*/
@@ -335,6 +337,9 @@ final class ActivityManagerConstants extends ContentObserver {
private static final String KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS =
"service_bind_almost_perceptible_timeout_ms";
+ private static final String KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS =
+ "max_service_connections_per_process";
+
// Maximum number of cached processes we will allow.
public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -687,6 +692,12 @@ final class ActivityManagerConstants extends ContentObserver {
*/
volatile String mComponentAliasOverrides = DEFAULT_COMPONENT_ALIAS_OVERRIDES;
+ /**
+ * The max number of outgoing ServiceConnection a process is allowed to bind to a service
+ * (or multiple services).
+ */
+ volatile int mMaxServiceConnectionsPerProcess = DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS;
+
private final ActivityManagerService mService;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -990,6 +1001,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_NETWORK_ACCESS_TIMEOUT_MS:
updateNetworkAccessTimeoutMs();
break;
+ case KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS:
+ updateMaxServiceConnectionsPerProcess();
+ break;
default:
break;
}
@@ -1633,6 +1647,13 @@ final class ActivityManagerConstants extends ContentObserver {
}
}
+ private void updateMaxServiceConnectionsPerProcess() {
+ mMaxServiceConnectionsPerProcess = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS,
+ DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
+ }
+
@NeverCompile // Avoid size overhead of debugging code.
void dump(PrintWriter pw) {
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
@@ -1779,6 +1800,8 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mServiceBindAlmostPerceptibleTimeoutMs);
pw.print(" "); pw.print(KEY_NETWORK_ACCESS_TIMEOUT_MS);
pw.print("="); pw.println(mNetworkAccessTimeoutMs);
+ pw.print(" "); pw.print(KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
+ pw.print("="); pw.println(mMaxServiceConnectionsPerProcess);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e49e63acd388..4aec577c65d6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17848,6 +17848,47 @@ public class ActivityManagerService extends IActivityManager.Stub
}
/**
+ * Set an app's background restriction level.
+ * This interface is intended for the shell command to use.
+ */
+ void setBackgroundRestrictionLevel(String packageName, int uid, int userId,
+ @RestrictionLevel int level, int reason, int subReason) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != SYSTEM_UID && callingUid != ROOT_UID && callingUid != SHELL_UID) {
+ throw new SecurityException(
+ "No permission to change app restriction level");
+ }
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ final int curBucket = mUsageStatsService.getAppStandbyBucket(packageName, userId,
+ SystemClock.elapsedRealtime());
+ mAppRestrictionController.applyRestrictionLevel(packageName, uid, level,
+ null /* trackerInfo */, curBucket, true /* allowUpdateBucket */,
+ reason, subReason);
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ /**
+ * Get an app's background restriction level.
+ * This interface is intended for the shell command to use.
+ */
+ @RestrictionLevel int getBackgroundRestrictionLevel(String packageName, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != SYSTEM_UID && callingUid != ROOT_UID && callingUid != SHELL_UID) {
+ throw new SecurityException(
+ "Don't have permission to query app background restriction level");
+ }
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ return mInternal.getRestrictionLevel(packageName, userId);
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ /**
* Force the settings cache to be loaded
*/
void refreshSettingsCache() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index a3ae35eb1811..6609d4a91f21 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -23,6 +23,10 @@ import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
import static android.app.WaitResult.launchStateToString;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER;
+import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.os.Process.INVALID_UID;
import static android.view.Display.INVALID_DISPLAY;
import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
@@ -350,6 +354,10 @@ final class ActivityManagerShellCommand extends ShellCommand {
return runSetBgAbusiveUids(pw);
case "list-bg-exemptions-config":
return runListBgExemptionsConfig(pw);
+ case "set-bg-restriction-level":
+ return runSetBgRestrictionLevel(pw);
+ case "get-bg-restriction-level":
+ return runGetBgRestrictionLevel(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -3374,6 +3382,79 @@ final class ActivityManagerShellCommand extends ShellCommand {
return 0;
}
+ private @ActivityManager.RestrictionLevel int restrictionNameToLevel(String name) {
+ String lower = name.toLowerCase();
+ switch (lower) {
+ case "unrestricted":
+ return ActivityManager.RESTRICTION_LEVEL_UNRESTRICTED;
+ case "exempted":
+ return ActivityManager.RESTRICTION_LEVEL_EXEMPTED;
+ case "adaptive_bucket":
+ return ActivityManager.RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
+ case "restricted_bucket":
+ return ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
+ case "background_restricted":
+ return ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED;
+ case "hibernation":
+ return ActivityManager.RESTRICTION_LEVEL_HIBERNATION;
+ default:
+ return ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
+ }
+ }
+
+ int runSetBgRestrictionLevel(PrintWriter pw) throws RemoteException {
+ int userId = UserHandle.USER_CURRENT;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ String packageName = getNextArgRequired();
+ final String value = getNextArgRequired();
+ final int level = restrictionNameToLevel(value);
+ if (level == ActivityManager.RESTRICTION_LEVEL_UNKNOWN) {
+ pw.println("Error: invalid restriction level");
+ return -1;
+ }
+
+ int uid = INVALID_UID;
+ try {
+ final PackageManager pm = mInternal.mContext.getPackageManager();
+ uid = pm.getPackageUidAsUser(packageName,
+ PackageManager.PackageInfoFlags.of(MATCH_ANY_USER), userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ pw.println("Error: userId:" + userId + " package:" + packageName + " is not found");
+ return -1;
+ }
+ mInternal.setBackgroundRestrictionLevel(packageName, uid, userId, level,
+ REASON_MAIN_FORCED_BY_USER, REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED);
+ return 0;
+ }
+
+ int runGetBgRestrictionLevel(PrintWriter pw) throws RemoteException {
+ int userId = UserHandle.USER_CURRENT;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ final String packageName = getNextArgRequired();
+ final @ActivityManager.RestrictionLevel int level =
+ mInternal.getBackgroundRestrictionLevel(packageName, userId);
+ pw.println(ActivityManager.restrictionLevelToName(level));
+ return 0;
+ }
+
private Resources getResources(PrintWriter pw) throws RemoteException {
// system resources does not contain all the device configuration, construct it manually.
Configuration config = mInterface.getConfiguration();
@@ -3726,6 +3807,10 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" Without arguments, it resets to the value defined by platform.");
pw.println(" set-bg-abusive-uids [uid=percentage][,uid=percentage...]");
pw.println(" Force setting the battery usage of the given UID.");
+ pw.println(" set-bg-restriction-level [--user <USER_ID>] <PACKAGE> unrestricted|exempted|adaptive_bucket|restricted_bucket|background_restricted|hibernation");
+ pw.println(" Set an app's background restriction level which in turn map to a app standby bucket.");
+ pw.println(" get-bg-restriction-level [--user <USER_ID>] <PACKAGE>");
+ pw.println(" Get an app's background restriction level.");
pw.println();
Intent.printIntentArgsHelp(pw, "");
}
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 6076eb1f69ee..e0690bf37fd5 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -2151,7 +2151,7 @@ public final class AppRestrictionController {
return AppBackgroundRestrictionsInfo.SDK_UNKNOWN;
}
- private void applyRestrictionLevel(String pkgName, int uid,
+ void applyRestrictionLevel(String pkgName, int uid,
@RestrictionLevel int level, TrackerInfo trackerInfo,
int curBucket, boolean allowUpdateBucket, int reason, int subReason) {
int curLevel;
@@ -2790,13 +2790,6 @@ public final class AppRestrictionController {
if (isOnSystemDeviceIdleAllowlist(uid)) {
return REASON_SYSTEM_ALLOW_LISTED;
}
- if (isOnDeviceIdleAllowlist(uid)) {
- return REASON_ALLOWLISTED_PACKAGE;
- }
- final ActivityManagerInternal am = mInjector.getActivityManagerInternal();
- if (am.isAssociatedCompanionApp(UserHandle.getUserId(uid), uid)) {
- return REASON_COMPANION_DEVICE_MANAGER;
- }
if (UserManager.isDeviceInDemoMode(mContext)) {
return REASON_DEVICE_DEMO_MODE;
}
@@ -2805,6 +2798,7 @@ public final class AppRestrictionController {
.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)) {
return REASON_DISALLOW_APPS_CONTROL;
}
+ final ActivityManagerInternal am = mInjector.getActivityManagerInternal();
if (am.isDeviceOwner(uid)) {
return REASON_DEVICE_OWNER;
}
@@ -2822,14 +2816,9 @@ public final class AppRestrictionController {
final AppOpsManager appOpsManager = mInjector.getAppOpsManager();
final PackageManagerInternal pm = mInjector.getPackageManagerInternal();
final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
+ // Check each packages to see if any of them is in the "fixed" exemption cases.
for (String pkg : packages) {
- if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN,
- uid, pkg) == AppOpsManager.MODE_ALLOWED) {
- return REASON_OP_ACTIVATE_VPN;
- } else if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN,
- uid, pkg) == AppOpsManager.MODE_ALLOWED) {
- return REASON_OP_ACTIVATE_PLATFORM_VPN;
- } else if (isSystemModule(pkg)) {
+ if (isSystemModule(pkg)) {
return REASON_SYSTEM_MODULE;
} else if (isCarrierApp(pkg)) {
return REASON_CARRIER_PRIVILEGED_APP;
@@ -2843,6 +2832,16 @@ public final class AppRestrictionController {
return REASON_ACTIVE_DEVICE_ADMIN;
}
}
+ // Loop the packages again, and check the user-configurable exemptions.
+ for (String pkg : packages) {
+ if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN,
+ uid, pkg) == AppOpsManager.MODE_ALLOWED) {
+ return REASON_OP_ACTIVATE_VPN;
+ } else if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN,
+ uid, pkg) == AppOpsManager.MODE_ALLOWED) {
+ return REASON_OP_ACTIVATE_PLATFORM_VPN;
+ }
+ }
}
if (isRoleHeldByUid(RoleManager.ROLE_DIALER, uid)) {
return REASON_ROLE_DIALER;
@@ -2850,6 +2849,12 @@ public final class AppRestrictionController {
if (isRoleHeldByUid(RoleManager.ROLE_EMERGENCY, uid)) {
return REASON_ROLE_EMERGENCY;
}
+ if (isOnDeviceIdleAllowlist(uid)) {
+ return REASON_ALLOWLISTED_PACKAGE;
+ }
+ if (am.isAssociatedCompanionApp(UserHandle.getUserId(uid), uid)) {
+ return REASON_COMPANION_DEVICE_MANAGER;
+ }
return REASON_DENIED;
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 43d0de9855fe..0cd1bfa3740a 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -2125,8 +2125,9 @@ public final class BroadcastQueue {
// app just because it's stopped at a breakpoint.
final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
+ long timeoutDurationMs = now - r.receiverTime;
Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
- + ", started " + (now - r.receiverTime) + "ms ago");
+ + ", started " + timeoutDurationMs + "ms ago");
r.receiverTime = now;
if (!debugging) {
r.anrCount++;
@@ -2158,7 +2159,9 @@ public final class BroadcastQueue {
}
if (app != null) {
- anrMessage = "Broadcast of " + r.intent.toString();
+ anrMessage =
+ "Broadcast of " + r.intent.toString() + ", waited " + timeoutDurationMs
+ + "ms";
}
if (mPendingBroadcast == r) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 132309e8efc4..42792bf64f44 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2269,7 +2269,9 @@ public final class ProcessList {
final boolean inBgRestricted = ast.isAppBackgroundRestricted(
app.info.uid, app.info.packageName);
if (inBgRestricted) {
- mAppsInBackgroundRestricted.add(app);
+ synchronized (mService) {
+ mAppsInBackgroundRestricted.add(app);
+ }
}
app.mState.setBackgroundRestricted(inBgRestricted);
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 7ffea26638f5..e4224edac790 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -91,6 +91,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
+import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.EventLog;
@@ -145,7 +146,7 @@ class UserController implements Handler.Callback {
// Amount of time we wait for observers to handle a user switch before
// giving up on them and unfreezing the screen.
- static final int USER_SWITCH_TIMEOUT_MS = 3 * 1000;
+ static final int DEFAULT_USER_SWITCH_TIMEOUT_MS = 3 * 1000;
/**
* Amount of time we wait for an observer to handle a user switch before we log a warning. This
@@ -182,9 +183,11 @@ class UserController implements Handler.Callback {
// UI thread message constants
static final int START_USER_SWITCH_UI_MSG = 1000;
- // If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
- // USER_SWITCH_TIMEOUT_MS, an error is reported. Usually it indicates a problem in the observer
- // when it never calls back.
+ /**
+ * If a callback wasn't called within USER_SWITCH_CALLBACKS_TIMEOUT_MS after
+ * {@link #getUserSwitchTimeoutMs}, an error is reported. Usually it indicates a problem in the
+ * observer when it never calls back.
+ */
private static final int USER_SWITCH_CALLBACKS_TIMEOUT_MS = 5 * 1000;
/**
@@ -348,7 +351,7 @@ class UserController implements Handler.Callback {
private String mSwitchingToSystemUserMessage;
/**
- * Callbacks that are still active after {@link #USER_SWITCH_TIMEOUT_MS}
+ * Callbacks that are still active after {@link #getUserSwitchTimeoutMs}
*/
@GuardedBy("mLock")
private ArraySet<String> mTimeoutUserSwitchCallbacks;
@@ -1642,7 +1645,7 @@ class UserController implements Handler.Callback {
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
oldUserId, userId, uss));
mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
- oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
+ oldUserId, userId, uss), getUserSwitchTimeoutMs());
}
if (userInfo.preCreated) {
@@ -1955,6 +1958,7 @@ class UserController implements Handler.Callback {
mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
}
final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
+ final long userSwitchTimeoutMs = getUserSwitchTimeoutMs();
final long dispatchStartedTime = SystemClock.elapsedRealtime();
for (int i = 0; i < observerCount; i++) {
final long dispatchStartedTimeForObserver = SystemClock.elapsedRealtime();
@@ -1978,7 +1982,7 @@ class UserController implements Handler.Callback {
long totalDelay = SystemClock.elapsedRealtime()
- dispatchStartedTime;
- if (totalDelay > USER_SWITCH_TIMEOUT_MS) {
+ if (totalDelay > userSwitchTimeoutMs) {
Slogf.e(TAG, "User switch timeout: observer " + name
+ "'s result was received " + totalDelay
+ " ms after dispatchUserSwitch.");
@@ -3109,6 +3113,19 @@ class UserController implements Handler.Callback {
return bOptions;
}
+ private static int getUserSwitchTimeoutMs() {
+ final String userSwitchTimeoutMs = SystemProperties.get(
+ "debug.usercontroller.user_switch_timeout_ms");
+ if (!TextUtils.isEmpty(userSwitchTimeoutMs)) {
+ try {
+ return Integer.parseInt(userSwitchTimeoutMs);
+ } catch (NumberFormatException ignored) {
+ // Ignored.
+ }
+ }
+ return DEFAULT_USER_SWITCH_TIMEOUT_MS;
+ }
+
/**
* Uptime when any user was being unlocked most recently. 0 if no users have been unlocked
* yet. To avoid lock contention (since it's used by OomAdjuster), it's volatile internally.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 42d8778522c5..7c02531d5407 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1792,11 +1792,11 @@ public class AudioService extends IAudioService.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @see AudioManager#setSupportedSystemUsages(int[])
*/
public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
- enforceModifyAudioRoutingPermission();
verifySystemUsages(systemUsages);
synchronized (mSupportedSystemUsagesLock) {
@@ -1805,11 +1805,11 @@ public class AudioService extends IAudioService.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @see AudioManager#getSupportedSystemUsages()
*/
public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
- enforceModifyAudioRoutingPermission();
synchronized (mSupportedSystemUsagesLock) {
return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
}
@@ -1823,6 +1823,7 @@ public class AudioService extends IAudioService.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
* platform configuration file.
@@ -1830,10 +1831,10 @@ public class AudioService extends IAudioService.Stub
@NonNull
public List<AudioProductStrategy> getAudioProductStrategies() {
// verify permissions
- enforceModifyAudioRoutingPermission();
return AudioProductStrategy.getAudioProductStrategies();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
* platform configuration file.
@@ -1841,7 +1842,6 @@ public class AudioService extends IAudioService.Stub
@NonNull
public List<AudioVolumeGroup> getAudioVolumeGroups() {
// verify permissions
- enforceModifyAudioRoutingPermission();
return AudioVolumeGroup.getAudioVolumeGroups();
}
@@ -2723,9 +2723,9 @@ public class AudioService extends IAudioService.Stub
return status;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
public int removePreferredDevicesForStrategy(int strategy) {
- enforceModifyAudioRoutingPermission();
final String logString =
String.format("removePreferredDeviceForStrategy strat:%d", strategy);
sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
@@ -2737,12 +2737,12 @@ public class AudioService extends IAudioService.Stub
return status;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
* @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
*/
public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
- enforceModifyAudioRoutingPermission();
List<AudioDeviceAttributes> devices = new ArrayList<>();
final long identity = Binder.clearCallingIdentity();
final int status = AudioSystem.getDevicesForRoleAndStrategy(
@@ -2810,9 +2810,9 @@ public class AudioService extends IAudioService.Stub
return status;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
public int clearPreferredDevicesForCapturePreset(int capturePreset) {
- enforceModifyAudioRoutingPermission();
final String logString = String.format(
"removePreferredDeviceForCapturePreset source:%d", capturePreset);
sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
@@ -2824,11 +2824,11 @@ public class AudioService extends IAudioService.Stub
return status;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @see AudioManager#getPreferredDevicesForCapturePreset(int)
*/
public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
- enforceModifyAudioRoutingPermission();
List<AudioDeviceAttributes> devices = new ArrayList<>();
final long identity = Binder.clearCallingIdentity();
final int status = AudioSystem.getDevicesForRoleAndCapturePreset(
@@ -3558,10 +3558,10 @@ public class AudioService extends IAudioService.Stub
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
String callingPackage, String attributionTag) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(attr, "attr must not be null");
final int volumeGroup = getVolumeGroupIdForAttributes(attr);
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
@@ -3601,9 +3601,9 @@ public class AudioService extends IAudioService.Stub
return null;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getVolumeIndexForAttributes(attr) */
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(attr, "attr must not be null");
final int volumeGroup = getVolumeGroupIdForAttributes(attr);
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
@@ -3613,16 +3613,16 @@ public class AudioService extends IAudioService.Stub
return vgs.getVolumeIndex();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(attr, "attr must not be null");
return AudioSystem.getMaxVolumeIndexForAttributes(attr);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(attr, "attr must not be null");
return AudioSystem.getMinVolumeIndexForAttributes(attr);
}
@@ -3664,9 +3664,9 @@ public class AudioService extends IAudioService.Stub
attributionTag, Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND)
/** @see AudioManager#isUltrasoundSupported() */
public boolean isUltrasoundSupported() {
- enforceAccessUltrasoundPermission();
return AudioSystem.isUltrasoundSupported();
}
@@ -4438,10 +4438,10 @@ public class AudioService extends IAudioService.Stub
return AudioSystem.getMasterMute();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#setMasterMute(boolean, int) */
public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
String attributionTag) {
- enforceModifyAudioRoutingPermission();
setMasterMuteInternal(mute, flags, callingPackage,
Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
}
@@ -4483,9 +4483,9 @@ public class AudioService extends IAudioService.Stub
return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
/** Get last audible volume before stream was muted. */
public int getLastAudibleStreamVolume(int streamType) {
- enforceQueryStatePermission();
ensureValidStreamType(streamType);
int device = getDeviceForStream(streamType);
return (mStreamStates[streamType].getIndex(device) + 5) / 10;
@@ -5332,9 +5332,9 @@ public class AudioService extends IAudioService.Stub
mModeDispatchers.unregister(dispatcher);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
/** @see AudioManager#isPstnCallAudioInterceptable() */
public boolean isPstnCallAudioInterceptable() {
- enforceCallAudioInterceptionPermission();
boolean uplinkDeviceFound = false;
boolean downlinkDeviceFound = false;
@@ -6689,6 +6689,7 @@ public class AudioService extends IAudioService.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
* @param device the audio device to be affected
@@ -6697,7 +6698,6 @@ public class AudioService extends IAudioService.Stub
public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
@AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
// verify permissions
- enforceModifyAudioRoutingPermission();
// verify arguments
Objects.requireNonNull(device);
AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
@@ -6847,12 +6847,12 @@ public class AudioService extends IAudioService.Stub
@Retention(RetentionPolicy.SOURCE)
public @interface ConnectionState {}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/**
* see AudioManager.setWiredDeviceConnectionState()
*/
public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
@ConnectionState int state, String caller) {
- enforceModifyAudioRoutingPermission();
if (state != CONNECTION_STATE_CONNECTED
&& state != CONNECTION_STATE_DISCONNECTED) {
throw new IllegalArgumentException("Invalid state " + state);
@@ -8970,27 +8970,27 @@ public class AudioService extends IAudioService.Stub
return mSpatializerHelper.isAvailable();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device) {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
- enforceModifyDefaultAudioEffectsPermission();
mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
}
@@ -8999,9 +8999,9 @@ public class AudioService extends IAudioService.Stub
return mSpatializerHelper.isHeadTrackerAvailable();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setSpatializerEnabled(boolean) */
public void setSpatializerEnabled(boolean enabled) {
- enforceModifyDefaultAudioEffectsPermission();
mSpatializerHelper.setFeatureEnabled(enabled);
}
@@ -9027,18 +9027,18 @@ public class AudioService extends IAudioService.Stub
mSpatializerHelper.unregisterStateCallback(cb);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
public void registerSpatializerHeadTrackingCallback(
@NonNull ISpatializerHeadTrackingModeCallback cb) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(cb);
mSpatializerHelper.registerHeadTrackingModeCallback(cb);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
public void unregisterSpatializerHeadTrackingCallback(
@NonNull ISpatializerHeadTrackingModeCallback cb) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(cb);
mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
}
@@ -9050,76 +9050,76 @@ public class AudioService extends IAudioService.Stub
mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
public void registerHeadToSoundstagePoseCallback(
@NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(cb);
mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
public void unregisterHeadToSoundstagePoseCallback(
@NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(cb);
mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#getSpatializerCompatibleAudioDevices() */
public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.getCompatibleAudioDevices();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(ada);
mSpatializerHelper.addCompatibleAudioDevice(ada);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(ada);
mSpatializerHelper.removeCompatibleAudioDevice(ada);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#getSupportedHeadTrackingModes() */
public int[] getSupportedHeadTrackingModes() {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.getSupportedHeadTrackingModes();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#getHeadTrackingMode() */
public int getActualHeadTrackingMode() {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.getActualHeadTrackingMode();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#getDesiredHeadTrackingMode() */
public int getDesiredHeadTrackingMode() {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.getDesiredHeadTrackingMode();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setGlobalTransform */
public void setSpatializerGlobalTransform(@NonNull float[] transform) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(transform);
mSpatializerHelper.setGlobalTransform(transform);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#recenterHeadTracker() */
public void recenterHeadTracker() {
- enforceModifyDefaultAudioEffectsPermission();
mSpatializerHelper.recenterHeadTracker();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setDesiredHeadTrackingMode */
public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
- enforceModifyDefaultAudioEffectsPermission();
switch(mode) {
case Spatializer.HEAD_TRACKING_MODE_DISABLED:
case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
@@ -9131,36 +9131,36 @@ public class AudioService extends IAudioService.Stub
mSpatializerHelper.setDesiredHeadTrackingMode(mode);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setEffectParameter */
public void setSpatializerParameter(int key, @NonNull byte[] value) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(value);
mSpatializerHelper.setEffectParameter(key, value);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#getEffectParameter */
public void getSpatializerParameter(int key, @NonNull byte[] value) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(value);
mSpatializerHelper.getEffectParameter(key, value);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#getOutput */
public int getSpatializerOutput() {
- enforceModifyDefaultAudioEffectsPermission();
return mSpatializerHelper.getOutput();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#setOnSpatializerOutputChangedListener */
public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(cb);
mSpatializerHelper.registerSpatializerOutputCallback(cb);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
/** @see Spatializer#clearOnSpatializerOutputChangedListener */
public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
- enforceModifyDefaultAudioEffectsPermission();
Objects.requireNonNull(cb);
mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
}
@@ -9268,9 +9268,9 @@ public class AudioService extends IAudioService.Stub
cb.dispatchOnMutedUntilConnection(device, usages); } catch (RemoteException e) { } });
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getMutingExpectedDevice */
public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
- enforceModifyAudioRoutingPermission();
synchronized (mMuteAwaitConnectionLock) {
return mMutingExpectedDevice;
}
@@ -9308,10 +9308,10 @@ public class AudioService extends IAudioService.Stub
final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
new RemoteCallbackList<IMuteAwaitConnectionCallback>();
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#registerMuteAwaitConnectionCallback */
public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
boolean register) {
- enforceModifyAudioRoutingPermission();
if (register) {
mMuteAwaitConnectionDispatchers.register(cb);
} else {
@@ -10817,9 +10817,9 @@ public class AudioService extends IAudioService.Stub
return AudioManager.SUCCESS;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioPolicy#getFocusStack() */
public List<AudioFocusInfo> getFocusStack() {
- enforceModifyAudioRoutingPermission();
return mMediaFocusControl.getFocusStack();
}
@@ -11582,11 +11582,11 @@ public class AudioService extends IAudioService.Stub
AudioSystem.setAudioHalPids(pidsArray);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
//======================
// Multi Audio Focus
//======================
public void setMultiAudioFocusEnabled(boolean enabled) {
- enforceModifyAudioRoutingPermission();
if (mMediaFocusControl != null) {
boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
if (mafEnabled != enabled) {
@@ -11685,10 +11685,10 @@ public class AudioService extends IAudioService.Stub
return delayMillis;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#addAssistantServicesUids(int []) */
@Override
public void addAssistantServicesUids(int [] assistantUids) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(assistantUids);
synchronized (mSettingsLock) {
@@ -11696,20 +11696,20 @@ public class AudioService extends IAudioService.Stub
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#removeAssistantServicesUids(int []) */
@Override
public void removeAssistantServicesUids(int [] assistantUids) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(assistantUids);
synchronized (mSettingsLock) {
removeAssistantServiceUidsLocked(assistantUids);
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getAssistantServicesUids() */
@Override
public int[] getAssistantServicesUids() {
- enforceModifyAudioRoutingPermission();
int [] assistantUids;
synchronized (mSettingsLock) {
assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
@@ -11717,10 +11717,10 @@ public class AudioService extends IAudioService.Stub
return assistantUids;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#setActiveAssistantServiceUids(int []) */
@Override
public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
- enforceModifyAudioRoutingPermission();
Objects.requireNonNull(activeAssistantUids);
synchronized (mSettingsLock) {
mActiveAssistantServiceUids = activeAssistantUids;
@@ -11728,10 +11728,10 @@ public class AudioService extends IAudioService.Stub
updateActiveAssistantServiceUids();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
/** @see AudioManager#getActiveAssistantServiceUids() */
@Override
public int[] getActiveAssistantServiceUids() {
- enforceModifyAudioRoutingPermission();
int [] activeAssistantUids;
synchronized (mSettingsLock) {
activeAssistantUids = mActiveAssistantServiceUids.clone();
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index bc550d311370..d2016c473bf4 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -173,10 +173,10 @@ public class AuthService extends SystemService {
}
private final class AuthServiceImpl extends IAuthService.Stub {
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) throws RemoteException {
- Utils.checkPermission(getContext(), TEST_BIOMETRIC);
final long identity = Binder.clearCallingIdentity();
try {
@@ -187,10 +187,10 @@ public class AuthService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
throws RemoteException {
- Utils.checkPermission(getContext(), TEST_BIOMETRIC);
final long identity = Binder.clearCallingIdentity();
try {
@@ -202,9 +202,9 @@ public class AuthService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public String getUiPackage() {
- Utils.checkPermission(getContext(), TEST_BIOMETRIC);
return getContext().getResources()
.getString(R.string.config_biometric_prompt_ui_package);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 4767969bd3ed..689ddd2fb9ee 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -491,10 +491,10 @@ public class BiometricService extends SystemService {
* sensor arbitration, threading, etc.
*/
private final class BiometricServiceWrapper extends IBiometricService.Stub {
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) throws RemoteException {
- checkInternalPermission();
for (BiometricSensor sensor : mSensors) {
if (sensor.id == sensorId) {
@@ -506,10 +506,10 @@ public class BiometricService extends SystemService {
return null;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
throws RemoteException {
- checkInternalPermission();
final List<SensorPropertiesInternal> sensors = new ArrayList<>();
for (BiometricSensor sensor : mSensors) {
@@ -523,17 +523,17 @@ public class BiometricService extends SystemService {
return sensors;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void onReadyForAuthentication(long requestId, int cookie) {
- checkInternalPermission();
mHandler.post(() -> handleOnReadyForAuthentication(requestId, cookie));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long authenticate(IBinder token, long operationId, int userId,
IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
- checkInternalPermission();
if (token == null || receiver == null || opPackageName == null || promptInfo == null) {
Slog.e(TAG, "Unable to authenticate, one or more null arguments");
@@ -561,9 +561,9 @@ public class BiometricService extends SystemService {
return requestId;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void cancelAuthentication(IBinder token, String opPackageName, long requestId) {
- checkInternalPermission();
SomeArgs args = SomeArgs.obtain();
args.arg1 = token;
@@ -573,10 +573,10 @@ public class BiometricService extends SystemService {
mHandler.post(() -> handleCancelAuthentication(requestId));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public int canAuthenticate(String opPackageName, int userId, int callingUserId,
@Authenticators.Types int authenticators) {
- checkInternalPermission();
Slog.d(TAG, "canAuthenticate: User=" + userId
+ ", Caller=" + callingUserId
@@ -596,9 +596,9 @@ public class BiometricService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public boolean hasEnrolledBiometrics(int userId, String opPackageName) {
- checkInternalPermission();
try {
for (BiometricSensor sensor : mSensors) {
@@ -613,11 +613,11 @@ public class BiometricService extends SystemService {
return false;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public synchronized void registerAuthenticator(int id, int modality,
@Authenticators.Types int strength,
@NonNull IBiometricAuthenticator authenticator) {
- checkInternalPermission();
Slog.d(TAG, "Registering ID: " + id
+ " Modality: " + modality
@@ -660,10 +660,10 @@ public class BiometricService extends SystemService {
mBiometricStrengthController.updateStrengths();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void registerEnabledOnKeyguardCallback(
IBiometricEnabledOnKeyguardCallback callback, int callingUserId) {
- checkInternalPermission();
mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
try {
@@ -674,17 +674,17 @@ public class BiometricService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void invalidateAuthenticatorIds(int userId, int fromSensorId,
IInvalidationCallback callback) {
- checkInternalPermission();
InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long[] getAuthenticatorIds(int callingUserId) {
- checkInternalPermission();
final List<Long> authenticatorIds = new ArrayList<>();
for (BiometricSensor sensor : mSensors) {
@@ -712,10 +712,10 @@ public class BiometricService extends SystemService {
return result;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId,
int userId, byte[] hardwareAuthToken) {
- checkInternalPermission();
// Check originating strength
if (!Utils.isAtLeastStrength(getSensorForId(fromSensorId).getCurrentStrength(),
@@ -751,9 +751,9 @@ public class BiometricService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public int getCurrentStrength(int sensorId) {
- checkInternalPermission();
for (BiometricSensor sensor : mSensors) {
if (sensor.id == sensorId) {
@@ -764,6 +764,7 @@ public class BiometricService extends SystemService {
return Authenticators.EMPTY_SET;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public int getCurrentModality(
String opPackageName,
@@ -771,7 +772,6 @@ public class BiometricService extends SystemService {
int callingUserId,
@Authenticators.Types int authenticators) {
- checkInternalPermission();
Slog.d(TAG, "getCurrentModality: User=" + userId
+ ", Caller=" + callingUserId
@@ -791,9 +791,9 @@ public class BiometricService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public int getSupportedModalities(@Authenticators.Types int authenticators) {
- checkInternalPermission();
Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators);
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 75d09f205192..79e65cc6d2e5 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
@@ -138,10 +138,10 @@ public class FaceService extends SystemService {
* Receives the incoming binder calls from FaceManager.
*/
private final class FaceServiceWrapper extends IFaceService.Stub {
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -153,9 +153,9 @@ public class FaceService extends SystemService {
return provider.createTestSession(sensorId, callback, opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ProtoOutputStream proto = new ProtoOutputStream();
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -166,18 +166,18 @@ public class FaceService extends SystemService {
return proto.getBytes();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
String opPackageName) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
return FaceService.this.getSensorProperties();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public FaceSensorPropertiesInternal getSensorProperties(int sensorId,
@NonNull String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -189,10 +189,10 @@ public class FaceService extends SystemService {
return provider.getSensorProperties(sensorId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void generateChallenge(IBinder token, int sensorId, int userId,
IFaceServiceReceiver receiver, String opPackageName) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -203,10 +203,10 @@ public class FaceService extends SystemService {
provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
long challenge) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -217,11 +217,11 @@ public class FaceService extends SystemService {
provider.scheduleRevokeChallenge(sensorId, userId, token, opPackageName, challenge);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public long enroll(int userId, final IBinder token, final byte[] hardwareAuthToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures, Surface previewSurface, boolean debugConsent) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -233,18 +233,18 @@ public class FaceService extends SystemService {
receiver, opPackageName, disabledFeatures, previewSurface, debugConsent);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public long enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
// TODO(b/145027036): Implement this.
return -1;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void cancelEnrollment(final IBinder token, long requestId) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -255,11 +255,11 @@ public class FaceService extends SystemService {
provider.second.cancelEnrollment(provider.first, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long authenticate(final IBinder token, final long operationId, int userId,
final IFaceServiceReceiver receiver, final String opPackageName,
boolean isKeyguardBypassEnabled) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
// TODO(b/152413782): If the sensor supports face detect and the device is encrypted or
// lockdown, something wrong happened. See similar path in FingerprintService.
@@ -285,10 +285,10 @@ public class FaceService extends SystemService {
statsClient, isKeyguard, isKeyguardBypassEnabled);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long detectFace(final IBinder token, final int userId,
final IFaceServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (!Utils.isKeyguard(getContext(), opPackageName)) {
Slog.w(TAG, "detectFace called from non-sysui package: " + opPackageName);
return -1;
@@ -312,12 +312,12 @@ public class FaceService extends SystemService {
BiometricsProtoEnums.CLIENT_KEYGUARD);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
IBinder token, long operationId, int userId,
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
int cookie, boolean allowBackgroundAuthentication) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -333,9 +333,9 @@ public class FaceService extends SystemService {
allowBackgroundAuthentication, isKeyguardBypassEnabled);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void startPreparedClient(int sensorId, int cookie) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -346,10 +346,10 @@ public class FaceService extends SystemService {
provider.startPreparedClient(sensorId, cookie);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void cancelAuthentication(final IBinder token, final String opPackageName,
final long requestId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -360,10 +360,10 @@ public class FaceService extends SystemService {
provider.second.cancelAuthentication(provider.first, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void cancelFaceDetect(final IBinder token, final String opPackageName,
final long requestId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (!Utils.isKeyguard(getContext(), opPackageName)) {
Slog.w(TAG, "cancelFaceDetect called from non-sysui package: "
+ opPackageName);
@@ -379,10 +379,10 @@ public class FaceService extends SystemService {
provider.second.cancelFaceDetect(provider.first, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void cancelAuthenticationFromService(int sensorId, final IBinder token,
final String opPackageName, final long requestId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -393,10 +393,10 @@ public class FaceService extends SystemService {
provider.cancelAuthentication(sensorId, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void remove(final IBinder token, final int faceId, final int userId,
final IFaceServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -408,10 +408,10 @@ public class FaceService extends SystemService {
opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void removeAll(final IBinder token, final int userId,
final IFaceServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final FaceServiceReceiver internalReceiver = new FaceServiceReceiver() {
int sensorsFinishedRemoving = 0;
@@ -441,10 +441,10 @@ public class FaceService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
mLockoutResetDispatcher.addCallback(callback, opPackageName);
}
@@ -501,9 +501,9 @@ public class FaceService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public boolean isHardwareDetected(int sensorId, String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final long token = Binder.clearCallingIdentity();
try {
@@ -518,9 +518,9 @@ public class FaceService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (userId != UserHandle.getCallingUserId()) {
Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
@@ -535,9 +535,9 @@ public class FaceService extends SystemService {
return provider.getEnrolledFaces(sensorId, userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (userId != UserHandle.getCallingUserId()) {
Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
@@ -552,9 +552,9 @@ public class FaceService extends SystemService {
return provider.getEnrolledFaces(sensorId, userId).size() > 0;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -565,10 +565,10 @@ public class FaceService extends SystemService {
return provider.getLockoutModeForUser(sensorId, userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void invalidateAuthenticatorId(int sensorId, int userId,
IInvalidationCallback callback) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -578,9 +578,9 @@ public class FaceService extends SystemService {
provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long getAuthenticatorId(int sensorId, int userId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -591,10 +591,10 @@ public class FaceService extends SystemService {
return provider.getAuthenticatorId(sensorId, userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void resetLockout(IBinder token, int sensorId, int userId, byte[] hardwareAuthToken,
String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -605,11 +605,11 @@ public class FaceService extends SystemService {
provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void setFeature(final IBinder token, int userId, int feature, boolean enabled,
final byte[] hardwareAuthToken, IFaceServiceReceiver receiver,
final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -621,10 +621,10 @@ public class FaceService extends SystemService {
hardwareAuthToken, receiver, opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override
public void getFeature(final IBinder token, int userId, int feature,
IFaceServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -667,10 +667,10 @@ public class FaceService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void registerAuthenticators(
@NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
// Some HAL might not be started before the system service and will cause the code below
// to wait, and some of the operations below might take a significant amount of time to
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
index 9bd7476abca2..73c272f7a779 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
@@ -138,26 +138,26 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
mRandom = new Random();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void setTestHalEnabled(boolean enabled) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mProvider.setTestHalEnabled(enabled);
mSensor.setTestHalEnabled(enabled);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void startEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
null /* previewSurface */, false /* debugConsent */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void finishEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
int nextRandomId = mRandom.nextInt();
while (mEnrollmentIds.contains(nextRandomId)) {
@@ -169,9 +169,9 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
.onEnrollmentProgress(nextRandomId, 0 /* remaining */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void acceptAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
// Fake authentication with any of the existing faces
List<Face> faces = FaceUtils.getInstance(mSensorId)
@@ -185,17 +185,17 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
HardwareAuthTokenUtils.toHardwareAuthToken(new byte[69]));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void rejectAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mSensor.getSessionForUser(userId).getHalSessionCallback().onAuthenticationFailed();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
// TODO(b/178414967): replace with notifyAuthenticationFrame and notifyEnrollmentFrame.
@Override
public void notifyAcquired(int userId, int acquireInfo) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
BaseFrame data = new BaseFrame();
data.acquiredInfo = (byte) acquireInfo;
@@ -209,17 +209,17 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
authenticationFrame);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyError(int userId, int errorCode) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mSensor.getSessionForUser(userId).getHalSessionCallback().onError((byte) errorCode,
0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void cleanupInternalState(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
Slog.d(TAG, "cleanupInternalState: " + userId);
mProvider.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
index e7483b3eeae3..14af216a9dc5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
@@ -127,25 +127,25 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
mRandom = new Random();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void setTestHalEnabled(boolean enabled) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mFace10.setTestHalEnabled(enabled);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void startEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mFace10.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
mContext.getOpPackageName(), new int[0] /* disabledFeatures */,
null /* previewSurface */, false /* debugConsent */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void finishEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
int nextRandomId = mRandom.nextInt();
while (mEnrollmentIds.contains(nextRandomId)) {
@@ -157,9 +157,9 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
nextRandomId /* faceId */, userId, 0);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void acceptAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
// Fake authentication with any of the existing fingers
List<Face> faces = FaceUtils.getLegacyInstance(mSensorId)
@@ -173,30 +173,30 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void rejectAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* faceId */, userId, null);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyAcquired(int userId, int acquireInfo) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mHalResultController.onAcquired(0 /* deviceId */, userId, acquireInfo, 0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyError(int userId, int errorCode) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mHalResultController.onError(0 /* deviceId */, userId, errorCode, 0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void cleanupInternalState(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mFace10.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 17b63736029e..64a01360b842 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -177,10 +177,10 @@ public class FingerprintService extends SystemService {
* Receives the incoming binder calls from FingerprintManager.
*/
private final IFingerprintService.Stub mServiceWrapper = new IFingerprintService.Stub() {
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
- Utils.checkPermission(getContext(), TEST_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -192,9 +192,9 @@ public class FingerprintService extends SystemService {
return provider.createTestSession(sensorId, callback, opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ProtoOutputStream proto = new ProtoOutputStream();
final ServiceProvider provider = getProviderForSensor(sensorId);
@@ -216,10 +216,10 @@ public class FingerprintService extends SystemService {
return FingerprintService.this.getSensorProperties();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId,
@NonNull String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -230,10 +230,10 @@ public class FingerprintService extends SystemService {
return provider.getSensorProperties(sensorId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public void generateChallenge(IBinder token, int sensorId, int userId,
IFingerprintServiceReceiver receiver, String opPackageName) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -244,10 +244,10 @@ public class FingerprintService extends SystemService {
provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
long challenge) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -259,11 +259,11 @@ public class FingerprintService extends SystemService {
challenge);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public long enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken,
final int userId, final IFingerprintServiceReceiver receiver,
final String opPackageName, @FingerprintManager.EnrollReason int enrollReason) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -275,9 +275,9 @@ public class FingerprintService extends SystemService {
receiver, opPackageName, enrollReason);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public void cancelEnrollment(final IBinder token, long requestId) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -452,10 +452,10 @@ public class FingerprintService extends SystemService {
new CancellationSignal(), executor, promptCallback, operationId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public long detectFingerprint(final IBinder token, final int userId,
final IFingerprintServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (!Utils.isKeyguard(getContext(), opPackageName)) {
Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName);
return -1;
@@ -479,11 +479,11 @@ public class FingerprintService extends SystemService {
BiometricsProtoEnums.CLIENT_KEYGUARD);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
long requestId, int cookie, boolean allowBackgroundAuthentication) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -498,9 +498,9 @@ public class FingerprintService extends SystemService {
allowBackgroundAuthentication);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void startPreparedClient(int sensorId, int cookie) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -541,10 +541,10 @@ public class FingerprintService extends SystemService {
provider.second.cancelAuthentication(provider.first, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void cancelFingerprintDetect(final IBinder token, final String opPackageName,
final long requestId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (!Utils.isKeyguard(getContext(), opPackageName)) {
Slog.w(TAG, "cancelFingerprintDetect called from non-sysui package: "
+ opPackageName);
@@ -562,11 +562,11 @@ public class FingerprintService extends SystemService {
provider.second.cancelAuthentication(provider.first, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
final String opPackageName, final long requestId) {
- Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
Slog.d(TAG, "cancelAuthenticationFromService, sensorId: " + sensorId);
@@ -579,10 +579,10 @@ public class FingerprintService extends SystemService {
provider.cancelAuthentication(sensorId, token, requestId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public void remove(final IBinder token, final int fingerId, final int userId,
final IFingerprintServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
if (provider == null) {
@@ -593,10 +593,10 @@ public class FingerprintService extends SystemService {
opPackageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void removeAll(final IBinder token, final int userId,
final IFingerprintServiceReceiver receiver, final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final FingerprintServiceReceiver internalReceiver = new FingerprintServiceReceiver() {
int sensorsFinishedRemoving = 0;
@@ -626,10 +626,10 @@ public class FingerprintService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
final String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
mLockoutResetDispatcher.addCallback(callback, opPackageName);
}
@@ -710,9 +710,9 @@ public class FingerprintService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public boolean isHardwareDetected(int sensorId, String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -723,9 +723,9 @@ public class FingerprintService extends SystemService {
return provider.isHardwareDetected(sensorId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override // Binder call
public void rename(final int fingerId, final int userId, final String name) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
return;
}
@@ -779,8 +779,8 @@ public class FingerprintService extends SystemService {
.isEmpty();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
public boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -791,9 +791,9 @@ public class FingerprintService extends SystemService {
return provider.getEnrolledFingerprints(sensorId, userId).size() > 0;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -803,10 +803,10 @@ public class FingerprintService extends SystemService {
return provider.getLockoutModeForUser(sensorId, userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void invalidateAuthenticatorId(int sensorId, int userId,
IInvalidationCallback callback) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -816,9 +816,9 @@ public class FingerprintService extends SystemService {
provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public long getAuthenticatorId(int sensorId, int userId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -828,10 +828,10 @@ public class FingerprintService extends SystemService {
return provider.getAuthenticatorId(sensorId, userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT)
@Override // Binder call
public void resetLockout(IBinder token, int sensorId, int userId,
@Nullable byte[] hardwareAuthToken, String opPackageName) {
- Utils.checkPermission(getContext(), RESET_FINGERPRINT_LOCKOUT);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -842,28 +842,28 @@ public class FingerprintService extends SystemService {
provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override
public boolean isClientActive() {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
return mGestureAvailabilityDispatcher.isAnySensorActive();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override
public void addClientActiveCallback(IFingerprintClientActiveCallback callback) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
mGestureAvailabilityDispatcher.registerCallback(callback);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
@Override
public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) {
- Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
mGestureAvailabilityDispatcher.removeCallback(callback);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void registerAuthenticators(
@NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
// Some HAL might not be started before the system service and will cause the code below
// to wait, and some of the operations below might take a significant amount of time to
@@ -885,10 +885,10 @@ public class FingerprintService extends SystemService {
thread.quitSafely();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void addAuthenticatorsRegisteredCallback(
IFingerprintAuthenticatorsRegisteredCallback callback) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
if (callback == null) {
Slog.e(TAG, "addAuthenticatorsRegisteredCallback, callback is null");
return;
@@ -907,10 +907,10 @@ public class FingerprintService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void onPointerDown(long requestId, int sensorId, int x, int y,
float minor, float major) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -920,9 +920,9 @@ public class FingerprintService extends SystemService {
provider.onPointerDown(requestId, sensorId, x, y, minor, major);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void onPointerUp(long requestId, int sensorId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -932,9 +932,9 @@ public class FingerprintService extends SystemService {
provider.onPointerUp(requestId, sensorId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void onUiReady(long requestId, int sensorId) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider == null) {
@@ -944,18 +944,18 @@ public class FingerprintService extends SystemService {
provider.onUiReady(requestId, sensorId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
for (ServiceProvider provider : mServiceProviders) {
provider.setUdfpsOverlayController(controller);
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
public void setSidefpsController(@NonNull ISidefpsController controller) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
for (ServiceProvider provider : mServiceProviders) {
provider.setSidefpsController(controller);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index ba7202fec93b..4181b99f9aba 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -131,25 +131,25 @@ class BiometricTestSessionImpl extends ITestSession.Stub {
mRandom = new Random();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void setTestHalEnabled(boolean enabled) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mProvider.setTestHalEnabled(enabled);
mSensor.setTestHalEnabled(enabled);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void startEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mProvider.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
mContext.getOpPackageName(), FingerprintManager.ENROLL_ENROLL);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void finishEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
int nextRandomId = mRandom.nextInt();
while (mEnrollmentIds.contains(nextRandomId)) {
@@ -161,9 +161,9 @@ class BiometricTestSessionImpl extends ITestSession.Stub {
.onEnrollmentProgress(nextRandomId, 0 /* remaining */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void acceptAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
// Fake authentication with any of the existing fingers
List<Fingerprint> fingerprints = FingerprintUtils.getInstance(mSensorId)
@@ -177,32 +177,32 @@ class BiometricTestSessionImpl extends ITestSession.Stub {
HardwareAuthTokenUtils.toHardwareAuthToken(new byte[69]));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void rejectAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mSensor.getSessionForUser(userId).getHalSessionCallback().onAuthenticationFailed();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyAcquired(int userId, int acquireInfo) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mSensor.getSessionForUser(userId).getHalSessionCallback()
.onAcquired((byte) acquireInfo, 0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyError(int userId, int errorCode) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mSensor.getSessionForUser(userId).getHalSessionCallback().onError((byte) errorCode,
0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void cleanupInternalState(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
Slog.d(TAG, "cleanupInternalState: " + userId);
mProvider.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
index a58bb8981cf6..682c00536e10 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
@@ -132,24 +132,24 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
mRandom = new Random();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void setTestHalEnabled(boolean enabled) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mFingerprint21.setTestHalEnabled(enabled);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void startEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mFingerprint21.scheduleEnroll(mSensorId, new Binder(), new byte[69], userId, mReceiver,
mContext.getOpPackageName(), FingerprintManager.ENROLL_ENROLL);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void finishEnroll(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
int nextRandomId = mRandom.nextInt();
while (mEnrollmentIds.contains(nextRandomId)) {
@@ -161,9 +161,9 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
nextRandomId /* fingerId */, userId, 0);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void acceptAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
// Fake authentication with any of the existing fingers
List<Fingerprint> fingerprints = FingerprintUtils.getLegacyInstance(mSensorId)
@@ -177,30 +177,30 @@ public class BiometricTestSessionImpl extends ITestSession.Stub {
mHalResultController.onAuthenticated(0 /* deviceId */, fid, userId, hat);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void rejectAuthentication(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mHalResultController.onAuthenticated(0 /* deviceId */, 0 /* fingerId */, userId, null);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyAcquired(int userId, int acquireInfo) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mHalResultController.onAcquired(0 /* deviceId */, acquireInfo, 0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void notifyError(int userId, int errorCode) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mHalResultController.onError(0 /* deviceId */, errorCode, 0 /* vendorCode */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
@Override
public void cleanupInternalState(int userId) {
- Utils.checkPermission(mContext, TEST_BIOMETRIC);
mFingerprint21.scheduleInternalCleanup(mSensorId, userId, new ClientMonitorCallback() {
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
index d684bb843967..ff1e7628c0bd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
@@ -55,9 +55,9 @@ public class IrisService extends SystemService {
* Receives the incoming binder calls from IrisManager.
*/
private final class IrisServiceWrapper extends IIrisService.Stub {
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void registerAuthenticators(@NonNull List<SensorPropertiesInternal> hidlSensors) {
- Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
// Some HAL might not be started before the system service and will cause the code below
// to wait, and some of the operations below might take a significant amount of time to
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 75b4eb4de5d6..781920c8d4c0 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -119,6 +119,13 @@ public final class ContentService extends IContentService.Stub {
@EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.S_V2)
public static final long ACCOUNT_ACCESS_CHECK_CHANGE_ID = 201794303L;
+ /**
+ * Enables checking for authority access for the calling uid on all sync-related APIs.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+ public static final long AUTHORITY_ACCESS_CHECK_CHANGE_ID = 207133734L;
+
public static class Lifecycle extends SystemService {
private ContentService mService;
@@ -608,6 +615,9 @@ public final class ContentService extends IContentService.Stub {
if (!hasAccountAccess(true, account, callingUid)) {
return;
}
+ if (!hasAuthorityAccess(authority, callingUid, userId)) {
+ return;
+ }
validateExtras(callingUid, extras);
final int syncExemption = getSyncExemptionAndCleanUpExtrasForCaller(callingUid, extras);
@@ -661,6 +671,9 @@ public final class ContentService extends IContentService.Stub {
if (!hasAccountAccess(true, request.getAccount(), callingUid)) {
return;
}
+ if (!hasAuthorityAccess(request.getProvider(), callingUid, userId)) {
+ return;
+ }
final Bundle extras = request.getBundle();
validateExtras(callingUid, extras);
@@ -863,7 +876,12 @@ public final class ContentService extends IContentService.Stub {
"no permission to read the sync settings for user " + userId);
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+ final int callingUid = Binder.getCallingUid();
+ if (!hasAccountAccess(true, account, callingUid)) {
+ return false;
+ }
+ if (!hasAuthorityAccess(providerName, callingUid, userId)) {
return false;
}
@@ -897,6 +915,9 @@ public final class ContentService extends IContentService.Stub {
if (!hasAccountAccess(true, account, callingUid)) {
return;
}
+ if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+ return;
+ }
final int syncExemptionFlag = getSyncExemptionForCaller(callingUid);
@@ -924,16 +945,19 @@ public final class ContentService extends IContentService.Stub {
"no permission to write the sync settings");
final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getCallingUserId();
if (!hasAccountAccess(true, account, callingUid)) {
return;
}
+ if (!hasAuthorityAccess(authority, callingUid, userId)) {
+ return;
+ }
validateExtras(callingUid, extras);
pollFrequency = clampPeriod(pollFrequency);
long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
- int userId = UserHandle.getCallingUserId();
final long identityToken = clearCallingIdentity();
try {
SyncStorageEngine.EndPoint info =
@@ -958,13 +982,16 @@ public final class ContentService extends IContentService.Stub {
"no permission to write the sync settings");
final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getCallingUserId();
if (!hasAccountAccess(true, account, callingUid)) {
return;
}
+ if (!hasAuthorityAccess(authority, callingUid, userId)) {
+ return;
+ }
validateExtras(callingUid, extras);
- int userId = UserHandle.getCallingUserId();
final long identityToken = clearCallingIdentity();
try {
getSyncManager().removePeriodicSync(
@@ -986,11 +1013,16 @@ public final class ContentService extends IContentService.Stub {
}
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+ final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getCallingUserId();
+ if (!hasAccountAccess(true, account, callingUid)) {
return new ArrayList<>(); // return a new empty list for consistent behavior
}
+ if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+ return new ArrayList<>();
+ }
- int userId = UserHandle.getCallingUserId();
final long identityToken = clearCallingIdentity();
try {
return getSyncManager().getPeriodicSyncs(
@@ -1015,9 +1047,14 @@ public final class ContentService extends IContentService.Stub {
"no permission to read the sync settings for user " + userId);
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
"no permission to read the sync settings");
- if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+ final int callingUid = Binder.getCallingUid();
+ if (!hasAccountAccess(true, account, callingUid)) {
return SyncStorageEngine.AuthorityInfo.NOT_SYNCABLE; // to keep behavior consistent
}
+ if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+ return SyncStorageEngine.AuthorityInfo.NOT_SYNCABLE;
+ }
final long identityToken = clearCallingIdentity();
try {
@@ -1052,6 +1089,9 @@ public final class ContentService extends IContentService.Stub {
if (!hasAccountAccess(true, account, callingUid)) {
return;
}
+ if (!hasAuthorityAccess(providerName, callingUid, userId)) {
+ return;
+ }
final long identityToken = clearCallingIdentity();
try {
@@ -1114,11 +1154,16 @@ public final class ContentService extends IContentService.Stub {
public boolean isSyncActive(Account account, String authority, ComponentName cname) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
- if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+ final int callingUid = Binder.getCallingUid();
+ final int userId = UserHandle.getCallingUserId();
+ if (!hasAccountAccess(true, account, callingUid)) {
+ return false;
+ }
+ if (!hasAuthorityAccess(authority, callingUid, userId)) {
return false;
}
- int userId = UserHandle.getCallingUserId();
final long identityToken = clearCallingIdentity();
try {
return getSyncManager().getSyncStorageEngine().isSyncActive(
@@ -1147,13 +1192,17 @@ public final class ContentService extends IContentService.Stub {
final boolean canAccessAccounts =
mContext.checkCallingOrSelfPermission(Manifest.permission.GET_ACCOUNTS)
== PackageManager.PERMISSION_GRANTED;
+ final List<SyncInfo> results;
+ final int callingUid = Binder.getCallingUid();
final long identityToken = clearCallingIdentity();
try {
- return getSyncManager().getSyncStorageEngine()
+ results = getSyncManager().getSyncStorageEngine()
.getCurrentSyncsCopy(userId, canAccessAccounts);
} finally {
restoreCallingIdentity(identityToken);
}
+ results.removeIf(i -> !hasAuthorityAccess(i.authority, callingUid, userId));
+ return results;
}
@Override
@@ -1177,7 +1226,12 @@ public final class ContentService extends IContentService.Stub {
"no permission to read the sync stats for user " + userId);
mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
"no permission to read the sync stats");
- if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+ final int callingUid = Binder.getCallingUid();
+ if (!hasAccountAccess(true, account, callingUid)) {
+ return null;
+ }
+ if (!hasAuthorityAccess(authority, callingUid, userId)) {
return null;
}
@@ -1207,7 +1261,12 @@ public final class ContentService extends IContentService.Stub {
"no permission to read the sync stats");
enforceCrossUserPermission(userId,
"no permission to retrieve the sync settings for user " + userId);
- if (!hasAccountAccess(true, account, Binder.getCallingUid())) {
+
+ final int callingUid = Binder.getCallingUid();
+ if (!hasAccountAccess(true, account, callingUid)) {
+ return false;
+ }
+ if (!hasAuthorityAccess(authority, callingUid, userId)) {
return false;
}
@@ -1441,6 +1500,30 @@ public final class ContentService extends IContentService.Stub {
}
}
+ /**
+ * Checks to see if the given authority is accessible by the caller.
+ *
+ * @param authority the authority to be accessed
+ * @param uid the uid trying to access the authority
+ * @param userId the user id for which to access the authority
+ * @return {@code true} if the authority is accessible by the caller, {@code false} otherwise
+ */
+ private boolean hasAuthorityAccess(@Nullable String authority, int uid, @UserIdInt int userId) {
+ if (TextUtils.isEmpty(authority)) {
+ return true;
+ }
+ if (!CompatChanges.isChangeEnabled(AUTHORITY_ACCESS_CHECK_CHANGE_ID, uid)) {
+ return true;
+ }
+ // Since #getSyncAdapterPackagesForAuthorityAsUser would filter out the packages
+ // that aren't visible to the callers, using this to check if the given authority
+ // is accessible by the callers.
+ final String[] syncAdapterPackages =
+ getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+ return !ArrayUtils.isEmpty(syncAdapterPackages);
+ }
+
+
private static int normalizeSyncable(int syncable) {
if (syncable > 0) {
return SyncStorageEngine.AuthorityInfo.SYNCABLE;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 05341e0f876e..dedc56ac9b41 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -523,10 +523,12 @@ final class LogicalDisplay {
// Set the layer stack.
device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack);
// Also inform whether the device is the same one sent to inputflinger for its layerstack.
+ // Prevent displays that are disabled from receiving input.
// TODO(b/188914255): Remove once input can dispatch against device vs layerstack.
device.setDisplayFlagsLocked(t,
- device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE
- ? SurfaceControl.DISPLAY_RECEIVES_INPUT : 0);
+ (isEnabled() && device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE)
+ ? SurfaceControl.DISPLAY_RECEIVES_INPUT
+ : 0);
// Set the color mode and allowed display mode.
if (device == mPrimaryDisplayDevice) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index fcb2eb45a6bd..9f447657cd83 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -203,7 +203,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
}
private void handleMediaProjectionStoppedLocked(IBinder appToken) {
- VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
+ VirtualDisplayDevice device = mVirtualDisplayDevices.get(appToken);
if (device != null) {
Slog.i(TAG, "Virtual display device released because media projection stopped: "
+ device.mName);
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 223b8c181fea..6e304163995b 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -1666,11 +1666,9 @@ public final class ColorDisplayService extends SystemService {
return true;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean isSaturationActivated() {
- getContext().enforceCallingPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to get display saturation level");
final long token = Binder.clearCallingIdentity();
try {
return !mGlobalSaturationTintController.isActivatedStateNotSet()
@@ -1680,11 +1678,9 @@ public final class ColorDisplayService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setAppSaturationLevel(String packageName, int level) {
- getContext().enforceCallingPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set display saturation level");
final String callingPackageName = LocalServices.getService(PackageManagerInternal.class)
.getNameForUid(Binder.getCallingUid());
final long token = Binder.clearCallingIdentity();
@@ -1695,10 +1691,8 @@ public final class ColorDisplayService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
public int getTransformCapabilities() {
- getContext().enforceCallingPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to query transform capabilities");
final long token = Binder.clearCallingIdentity();
try {
return getTransformCapabilitiesInternal();
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index ae9c64b48006..326d720927ab 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -64,11 +64,10 @@ public final class FontManagerService extends IFontManager.Stub {
private static final String FONT_FILES_DIR = "/data/fonts/files";
private static final String CONFIG_XML_FILE = "/data/fonts/config/config.xml";
+ @android.annotation.EnforcePermission(android.Manifest.permission.UPDATE_FONTS)
@RequiresPermission(Manifest.permission.UPDATE_FONTS)
@Override
public FontConfig getFontConfig() {
- getContext().enforceCallingPermission(Manifest.permission.UPDATE_FONTS,
- "UPDATE_FONTS permission required.");
return getSystemFontConfig();
}
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index e222c644da9e..d238dae634ad 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -27,8 +27,6 @@ import android.view.InputWindowHandle;
import android.view.SurfaceControl;
import android.view.WindowManager;
-import com.android.server.policy.WindowManagerPolicy;
-
/**
* An internal implementation of an {@link InputMonitor} that uses a spy window.
*
@@ -69,9 +67,7 @@ class GestureMonitorSpyWindow {
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setInputWindowInfo(mInputSurface, mWindowHandle);
- // Gesture monitor should be above handwriting event surface, hence setting it to
- // WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1
- t.setLayer(mInputSurface, WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER + 1);
+ t.setLayer(mInputSurface, Integer.MAX_VALUE);
t.setPosition(mInputSurface, 0, 0);
t.setCrop(mInputSurface, null /* crop to parent surface */);
t.show(mInputSurface);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0f0579cc3fa5..44aefccaeaf6 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -396,7 +396,7 @@ public class InputManagerService extends IInputManager.Stub
}
NativeInputManagerService getNativeService(InputManagerService service) {
- return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
+ return new NativeInputManagerService.NativeImpl(service, mLooper.getQueue());
}
void registerLocalService(InputManagerInternal localService) {
@@ -843,14 +843,17 @@ public class InputManagerService extends IInputManager.Stub
* When input dispatches focus to the apps, the touch mode state
* will be sent together with the focus change (but each one in its own event).
*
- * @param inTouchMode true if the device is in touch mode
- * @param pid the pid of the process that requested to switch touch mode state
- * @param uid the uid of the process that requested to switch touch mode state
+ * @param inTouchMode true if the device is in touch mode
+ * @param pid the pid of the process that requested to switch touch mode state
+ * @param uid the uid of the process that requested to switch touch mode state
* @param hasPermission if set to {@code true} then no further authorization will be performed
+ * @param displayId the target display (ignored if device is configured with per display
+ * touch mode enabled)
* @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
*/
- public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission) {
- return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission);
+ public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission,
+ int displayId) {
+ return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission, displayId);
}
@Override // Binder call
@@ -3031,6 +3034,13 @@ public class InputManagerService extends IInputManager.Stub
return names.toArray(new String[0]);
}
+ // Native callback.
+ @SuppressWarnings("unused")
+ private boolean isPerDisplayTouchModeEnabled() {
+ return mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_perDisplayFocusEnabled);
+ }
+
/**
* Flatten a map into a string list, with value positioned directly next to the
* key.
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 3d1e4410f742..325c3089f89a 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -16,7 +16,6 @@
package com.android.server.input;
-import android.content.Context;
import android.hardware.display.DisplayViewport;
import android.hardware.input.InputSensorInfo;
import android.hardware.lights.Light;
@@ -64,7 +63,19 @@ public interface NativeInputManagerService {
void setInputFilterEnabled(boolean enable);
- boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission);
+ /**
+ * Set the touch mode state for the display passed as argument.
+ *
+ * @param inTouchMode true if the device is in touch mode
+ * @param pid the pid of the process that requested to switch touch mode state
+ * @param uid the uid of the process that requested to switch touch mode state
+ * @param hasPermission if set to {@code true} then no further authorization will be performed
+ * @param displayId the target display (ignored if device is configured with per display
+ * touch mode enabled)
+ * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
+ */
+ boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission,
+ int displayId);
void setMaximumObscuringOpacityForTouch(float opacity);
@@ -194,12 +205,11 @@ public interface NativeInputManagerService {
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final long mPtr;
- NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
- mPtr = init(service, context, messageQueue);
+ NativeImpl(InputManagerService service, MessageQueue messageQueue) {
+ mPtr = init(service, messageQueue);
}
- private native long init(InputManagerService service, Context context,
- MessageQueue messageQueue);
+ private native long init(InputManagerService service, MessageQueue messageQueue);
@Override
public native void start();
@@ -240,7 +250,7 @@ public interface NativeInputManagerService {
@Override
public native boolean setInTouchMode(boolean inTouchMode, int pid, int uid,
- boolean hasPermission);
+ boolean hasPermission, int displayId);
@Override
public native void setMaximumObscuringOpacityForTouch(float opacity);
diff --git a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
index 24b8e340dee9..816d08af2814 100644
--- a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
+++ b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
@@ -31,6 +31,8 @@ import android.util.Xml;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
+import libcore.io.IoUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -102,11 +104,11 @@ final class AdditionalSubtypeUtils {
*
* @param allSubtypes {@link ArrayMap} from IME ID to additional subtype list. Passing an empty
* map deletes the file.
- * @param methodMap {@link ArrayMap} from IME ID to {@link InputMethodInfo}.
- * @param userId The user ID to be associated with.
+ * @param methodMap {@link ArrayMap} from IME ID to {@link InputMethodInfo}.
+ * @param userId The user ID to be associated with.
*/
static void save(ArrayMap<String, List<InputMethodSubtype>> allSubtypes,
- ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+ ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
final File inputMethodDir = getInputMethodDir(userId);
if (allSubtypes.isEmpty()) {
@@ -172,11 +174,13 @@ final class AdditionalSubtypeUtils {
out.endTag(null, NODE_SUBTYPES);
out.endDocument();
subtypesFile.finishWrite(fos);
- } catch (java.io.IOException e) {
+ } catch (IOException e) {
Slog.w(TAG, "Error writing subtypes", e);
if (fos != null) {
subtypesFile.failWrite(fos);
}
+ } finally {
+ IoUtils.closeQuietly(fos);
}
}
@@ -189,7 +193,7 @@ final class AdditionalSubtypeUtils {
*
* @param allSubtypes {@link ArrayMap} from IME ID to additional subtype list. This parameter
* will be used to return the result.
- * @param userId The user ID to be associated with.
+ * @param userId The user ID to be associated with.
*/
static void load(@NonNull ArrayMap<String, List<InputMethodSubtype>> allSubtypes,
@UserIdInt int userId) {
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 5438faa8793e..8180e66166d9 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -27,8 +27,6 @@ import android.view.InputWindowHandle;
import android.view.SurfaceControl;
import android.view.WindowManager;
-import com.android.server.policy.WindowManagerPolicy;
-
final class HandwritingEventReceiverSurface {
public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName();
@@ -38,8 +36,7 @@ final class HandwritingEventReceiverSurface {
// is above gesture monitors, then edge-back and swipe-up gestures won't work when this surface
// is intercepting.
// TODO(b/217538817): Specify the ordering in WM by usage.
- private static final int HANDWRITING_SURFACE_LAYER =
- WindowManagerPolicy.INPUT_DISPLAY_OVERLAY_LAYER;
+ private static final int HANDWRITING_SURFACE_LAYER = Integer.MAX_VALUE - 1;
private final InputWindowHandle mWindowHandle;
private final InputChannel mClientChannel;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
index 68753ab909b3..295793569a25 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
@@ -22,7 +22,6 @@ import static com.android.server.inputmethod.SubtypeUtils.SUBTYPE_MODE_KEYBOARD;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Slog;
@@ -199,7 +198,8 @@ final class InputMethodInfoUtils {
* @param methodMap Map from the IME ID to {@link InputMethodInfo}.
* @param systemSpeechRecognizerPackageName System speech recognizer configured by the system
* config.
- * @param currentDefaultVoiceImeId IME ID currently set to
+ * @param currentDefaultVoiceImeId the default voice IME id, which may be {@code null} or
+ * the value assigned for
* {@link Settings.Secure#DEFAULT_VOICE_INPUT_METHOD}
* @return {@link InputMethodInfo} that is found in {@code methodMap} and most suitable for
* the system voice IME.
@@ -294,7 +294,7 @@ final class InputMethodInfoUtils {
for (int i = 0; i < imis.size(); ++i) {
if (isSystemImeThatHasSubtypeOf(imis.get(i), context,
true /* checkDefaultAttribute */, fallbackLocale,
- true /* checkCountry */, SubtypeUtils.SUBTYPE_MODE_KEYBOARD)) {
+ true /* checkCountry */, SUBTYPE_MODE_KEYBOARD)) {
return fallbackLocale;
}
}
@@ -305,7 +305,7 @@ final class InputMethodInfoUtils {
for (int i = 0; i < imis.size(); ++i) {
if (isSystemImeThatHasSubtypeOf(imis.get(i), context,
false /* checkDefaultAttribute */, fallbackLocale,
- true /* checkCountry */, SubtypeUtils.SUBTYPE_MODE_KEYBOARD)) {
+ true /* checkCountry */, SUBTYPE_MODE_KEYBOARD)) {
return fallbackLocale;
}
}
@@ -323,10 +323,7 @@ final class InputMethodInfoUtils {
if (checkDefaultAttribute && !imi.isDefault(context)) {
return false;
}
- if (!SubtypeUtils.containsSubtypeOf(imi, requiredLocale, checkCountry,
- requiredSubtypeMode)) {
- return false;
- }
- return true;
+ return SubtypeUtils.containsSubtypeOf(imi, requiredLocale, checkCountry,
+ requiredSubtypeMode);
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 0aaf9c7928f7..8cd35d506c97 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -59,6 +59,7 @@ import android.annotation.AnyThread;
import android.annotation.BinderThread;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
+import android.annotation.EnforcePermission;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -294,6 +295,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final IWindowManager mIWindowManager;
private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid =
new SparseBooleanArray(0);
+ private final SparseBooleanArray mLoggedDeniedIsInputMethodPickerShownForTestForUid =
+ new SparseBooleanArray(0);
final WindowManagerInternal mWindowManagerInternal;
final PackageManagerInternal mPackageManagerInternal;
final InputManagerInternal mInputManagerInternal;
@@ -1465,6 +1468,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
public void onUidRemoved(int uid) {
synchronized (ImfLock.class) {
mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid);
+ mLoggedDeniedIsInputMethodPickerShownForTestForUid.delete(uid);
}
}
@@ -3169,7 +3173,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
// TODO: Move this clearing calling identity block to setImeWindowStatus after making sure
- // all updateSystemUi happens on system previlege.
+ // all updateSystemUi happens on system privilege.
final long ident = Binder.clearCallingIdentity();
try {
if (!mCurPerceptible) {
@@ -3356,14 +3360,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#showSoftInput");
synchronized (ImfLock.class) {
- if (!calledFromValidUserLocked()) {
+ if (!canInteractWithImeLocked(uid, client, "showSoftInput")) {
return false;
}
final long ident = Binder.clearCallingIdentity();
try {
- if (!canInteractWithImeLocked(uid, client, "showSoftInput")) {
- return false;
- }
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
return showCurrentInputLocked(windowToken, flags, resultReceiver, reason);
} finally {
@@ -3382,7 +3383,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
"InputMethodManagerService#startStylusHandwriting");
int uid = Binder.getCallingUid();
synchronized (ImfLock.class) {
- if (!calledFromValidUserLocked()) {
+ if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting")) {
return;
}
if (!hasSupportedStylusLocked()) {
@@ -3392,9 +3393,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
final long ident = Binder.clearCallingIdentity();
try {
- if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting")) {
- return;
- }
if (!mBindingController.supportsStylusHandwriting()) {
Slog.w(TAG,
"Stylus HW unsupported by IME. Ignoring startStylusHandwriting()");
@@ -3430,19 +3428,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
Objects.requireNonNull(windowToken, "windowToken must not be null");
synchronized (ImfLock.class) {
- if (!calledFromValidUserLocked()) {
+ if (mCurFocusedWindow != windowToken || mCurPerceptible == perceptible) {
return;
}
- final long ident = Binder.clearCallingIdentity();
- try {
- if (mCurFocusedWindow == windowToken
- && mCurPerceptible != perceptible) {
- mCurPerceptible = perceptible;
- updateSystemUiLocked(mImeWindowVis, mBackDisposition);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ mCurPerceptible = perceptible;
+ Binder.withCleanCallingIdentity(() ->
+ updateSystemUiLocked(mImeWindowVis, mBackDisposition));
}
}
@@ -3494,29 +3485,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#hideSoftInput");
synchronized (ImfLock.class) {
- if (!InputMethodManagerService.this.calledFromValidUserLocked()) {
+ if (!canInteractWithImeLocked(uid, client, "hideSoftInput")) {
return false;
}
final long ident = Binder.clearCallingIdentity();
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
- // We need to check if this is the current client with
- // focus in the window manager, to allow this call to
- // be made before input is started in it.
- final ClientState cs = mClients.get(client.asBinder());
- if (cs == null) {
- throw new IllegalArgumentException("unknown client " + client.asBinder());
- }
- if (!isImeClientFocused(windowToken, cs)) {
- if (DEBUG) {
- Slog.w(TAG, "Ignoring hideSoftInput of uid " + uid + ": " + client);
- }
- return false;
- }
- }
-
if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
return InputMethodManagerService.this.hideCurrentInputLocked(windowToken,
flags, resultReceiver, reason);
@@ -3983,12 +3957,15 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("ImfLock.class")
private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
- // TODO(yukawa): multi-display support.
final int uid = Binder.getCallingUid();
if (mCurFocusedWindowClient != null && client != null
&& mCurFocusedWindowClient.client.asBinder() == client.asBinder()) {
return true;
- } else if (getCurIntentLocked() != null && InputMethodUtils.checkIfPackageBelongsToUid(
+ }
+ if (mSettings.getCurrentUserId() != UserHandle.getUserId(uid)) {
+ return false;
+ }
+ if (getCurIntentLocked() != null && InputMethodUtils.checkIfPackageBelongsToUid(
mAppOpsManager,
uid,
getCurIntentLocked().getComponent().getPackageName())) {
@@ -4001,9 +3978,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
public void showInputMethodPickerFromClient(IInputMethodClient client,
int auxiliarySubtypeMode) {
synchronized (ImfLock.class) {
- if (!calledFromValidUserLocked()) {
- return;
- }
if (!canShowInputMethodPickerLocked(client)) {
Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
+ Binder.getCallingUid() + ": " + client);
@@ -4019,15 +3993,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ @EnforcePermission(Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public void showInputMethodPickerFromSystem(IInputMethodClient client, int auxiliarySubtypeMode,
int displayId) {
- if (mContext.checkCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(
- "showInputMethodPickerFromSystem requires WRITE_SECURE_SETTINGS "
- + "permission");
- }
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)
@@ -4038,6 +4007,18 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
* A test API for CTS to make sure that the input method menu is showing.
*/
public boolean isInputMethodPickerShownForTest() {
+ if (mContext.checkCallingPermission(android.Manifest.permission.TEST_INPUT_METHOD)
+ != PackageManager.PERMISSION_GRANTED) {
+ final int callingUid = Binder.getCallingUid();
+ synchronized (ImfLock.class) {
+ if (!mLoggedDeniedIsInputMethodPickerShownForTestForUid.get(callingUid)) {
+ EventLog.writeEvent(0x534e4554, "237317525", callingUid, "");
+ mLoggedDeniedIsInputMethodPickerShownForTestForUid.put(callingUid, true);
+ }
+ }
+ throw new SecurityException(
+ "isInputMethodPickerShownForTest requires TEST_INPUT_METHOD permission");
+ }
synchronized (ImfLock.class) {
return mMenuController.isisInputMethodPickerShownForTestLocked();
}
@@ -4180,10 +4161,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
false /* onlyCurrentIme */, mMethodMap.get(getSelectedMethodIdLocked()),
mCurrentSubtype);
- if (nextSubtype == null) {
- return false;
- }
- return true;
+ return nextSubtype != null;
}
}
@@ -4298,9 +4276,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
});
}
+ @EnforcePermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW)
@Override
public void removeImeSurface() {
- mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null);
mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE).sendToTarget();
}
@@ -4482,22 +4460,16 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
* a stylus deviceId is not already registered on device.
*/
@BinderThread
- @RequiresPermission(Manifest.permission.INJECT_EVENTS)
+ @EnforcePermission(Manifest.permission.INJECT_EVENTS)
@Override
public void addVirtualStylusIdForTestSession(IInputMethodClient client) {
- mContext.enforceCallingPermission(
- Manifest.permission.INJECT_EVENTS,
- "Using addVirtualStylusIdForTestSession() requires INJECT_EVENTS.");
int uid = Binder.getCallingUid();
synchronized (ImfLock.class) {
- if (!calledFromValidUserLocked()) {
+ if (!canInteractWithImeLocked(uid, client, "addVirtualStylusIdForTestSession")) {
return;
}
final long ident = Binder.clearCallingIdentity();
try {
- if (!canInteractWithImeLocked(uid, client, "addVirtualStylusIdForTestSession")) {
- return;
- }
if (!mBindingController.supportsStylusHandwriting()) {
Slog.w(TAG, "Stylus HW unsupported by IME. Ignoring addVirtualStylusId()");
return;
@@ -5560,10 +5532,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void onImeParentChanged() {
synchronized (ImfLock.class) {
- // Hide the IME method menu when the IME surface parent will change in
- // case seeing the dialog dismiss flickering during the next focused window
- // starting the input connection.
- mMenuController.hideInputMethodMenu();
+ // Hide the IME method menu only when the IME surface parent is changed by the
+ // input target changed, in case seeing the dialog dismiss flickering during
+ // the next focused window starting the input connection.
+ if (mLastImeTargetWindow != mCurFocusedWindow) {
+ mMenuController.hideInputMethodMenu();
+ }
}
}
@@ -6108,25 +6082,26 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
}
synchronized (ImfLock.class) {
- final PrintWriter pr = shellCommand.getOutPrintWriter();
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
- for (int userId : userIds) {
- final List<InputMethodInfo> methods = all
- ? getInputMethodListLocked(userId, DirectBootAwareness.AUTO)
- : getEnabledInputMethodListLocked(userId);
- if (userIds.length > 1) {
- pr.print("User #");
- pr.print(userId);
- pr.println(":");
- }
- for (InputMethodInfo info : methods) {
- if (brief) {
- pr.println(info.getId());
- } else {
- pr.print(info.getId());
+ try (PrintWriter pr = shellCommand.getOutPrintWriter()) {
+ for (int userId : userIds) {
+ final List<InputMethodInfo> methods = all
+ ? getInputMethodListLocked(userId, DirectBootAwareness.AUTO)
+ : getEnabledInputMethodListLocked(userId);
+ if (userIds.length > 1) {
+ pr.print("User #");
+ pr.print(userId);
pr.println(":");
- info.dump(pr::println, " ");
+ }
+ for (InputMethodInfo info : methods) {
+ if (brief) {
+ pr.println(info.getId());
+ } else {
+ pr.print(info.getId());
+ pr.println(":");
+ info.dump(pr::println, " ");
+ }
}
}
}
@@ -6136,8 +6111,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
/**
* Handles {@code adb shell ime enable} and {@code adb shell ime disable}.
+ *
* @param shellCommand {@link ShellCommand} object that is handling this command.
- * @param enabled {@code true} if the command was {@code adb shell ime enable}.
+ * @param enabled {@code true} if the command was {@code adb shell ime enable}.
* @return Exit code of the command.
*/
@BinderThread
@@ -6146,18 +6122,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@NonNull ShellCommand shellCommand, boolean enabled) {
final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
final String imeId = shellCommand.getNextArgRequired();
- final PrintWriter out = shellCommand.getOutPrintWriter();
- final PrintWriter error = shellCommand.getErrPrintWriter();
boolean hasFailed = false;
- synchronized (ImfLock.class) {
- final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
- mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
- for (int userId : userIds) {
- if (!userHasDebugPriv(userId, shellCommand)) {
- continue;
+ try (PrintWriter out = shellCommand.getOutPrintWriter();
+ PrintWriter error = shellCommand.getErrPrintWriter()) {
+ synchronized (ImfLock.class) {
+ final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+ mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+ for (int userId : userIds) {
+ if (!userHasDebugPriv(userId, shellCommand)) {
+ continue;
+ }
+ hasFailed |= !handleShellCommandEnableDisableInputMethodInternalLocked(
+ userId, imeId, enabled, out, error);
}
- hasFailed |= !handleShellCommandEnableDisableInputMethodInternalLocked(
- userId, imeId, enabled, out, error);
}
}
return hasFailed ? ShellCommandResult.FAILURE : ShellCommandResult.SUCCESS;
@@ -6249,7 +6226,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
+ " failed due to its unrecognized IME ID.");
return false;
}
-
out.print("Input method ");
out.print(imeId);
out.print(": ");
@@ -6262,6 +6238,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
/**
* Handles {@code adb shell ime set}.
+ *
* @param shellCommand {@link ShellCommand} object that is handling this command.
* @return Exit code of the command.
*/
@@ -6270,32 +6247,34 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
private int handleShellCommandSetInputMethod(@NonNull ShellCommand shellCommand) {
final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
final String imeId = shellCommand.getNextArgRequired();
- final PrintWriter out = shellCommand.getOutPrintWriter();
- final PrintWriter error = shellCommand.getErrPrintWriter();
boolean hasFailed = false;
- synchronized (ImfLock.class) {
- final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
- mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
- for (int userId : userIds) {
- if (!userHasDebugPriv(userId, shellCommand)) {
- continue;
- }
- boolean failedToSelectUnknownIme = !switchToInputMethodLocked(imeId, userId);
- if (failedToSelectUnknownIme) {
- error.print("Unknown input method ");
- error.print(imeId);
- error.print(" cannot be selected for user #");
- error.println(userId);
- // Also print this failure into logcat for better debuggability.
- Slog.e(TAG, "\"ime set " + imeId + "\" for user #" + userId
- + " failed due to its unrecognized IME ID.");
- } else {
- out.print("Input method ");
- out.print(imeId);
- out.print(" selected for user #");
- out.println(userId);
+ try (PrintWriter out = shellCommand.getOutPrintWriter();
+ PrintWriter error = shellCommand.getErrPrintWriter()) {
+ synchronized (ImfLock.class) {
+ final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+ mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+ for (int userId : userIds) {
+ if (!userHasDebugPriv(userId, shellCommand)) {
+ continue;
+ }
+ boolean failedToSelectUnknownIme = !switchToInputMethodLocked(imeId,
+ userId);
+ if (failedToSelectUnknownIme) {
+ error.print("Unknown input method ");
+ error.print(imeId);
+ error.print(" cannot be selected for user #");
+ error.println(userId);
+ // Also print this failure into logcat for better debuggability.
+ Slog.e(TAG, "\"ime set " + imeId + "\" for user #" + userId
+ + " failed due to its unrecognized IME ID.");
+ } else {
+ out.print("Input method ");
+ out.print(imeId);
+ out.print(" selected for user #");
+ out.println(userId);
+ }
+ hasFailed |= failedToSelectUnknownIme;
}
- hasFailed |= failedToSelectUnknownIme;
}
}
return hasFailed ? ShellCommandResult.FAILURE : ShellCommandResult.SUCCESS;
@@ -6309,70 +6288,72 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@ShellCommandResult
private int handleShellCommandResetInputMethod(@NonNull ShellCommand shellCommand) {
- final PrintWriter out = shellCommand.getOutPrintWriter();
final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
synchronized (ImfLock.class) {
- final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
- mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
- for (int userId : userIds) {
- if (!userHasDebugPriv(userId, shellCommand)) {
- continue;
- }
- final String nextIme;
- final List<InputMethodInfo> nextEnabledImes;
- if (userId == mSettings.getCurrentUserId()) {
- hideCurrentInputLocked(mCurFocusedWindow, 0, null,
- SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
- mBindingController.unbindCurrentMethod();
- // Reset the current IME
- resetSelectedInputMethodAndSubtypeLocked(null);
- // Also reset the settings of the current IME
- mSettings.putSelectedInputMethod(null);
- // Disable all enabled IMEs.
- for (InputMethodInfo inputMethodInfo :
- mSettings.getEnabledInputMethodListLocked()) {
- setInputMethodEnabledLocked(inputMethodInfo.getId(), false);
+ try (PrintWriter out = shellCommand.getOutPrintWriter()) {
+ final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
+ mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
+ for (int userId : userIds) {
+ if (!userHasDebugPriv(userId, shellCommand)) {
+ continue;
}
- // Re-enable with default enabled IMEs.
- for (InputMethodInfo imi : InputMethodInfoUtils.getDefaultEnabledImes(
- mContext, mMethodList)) {
- setInputMethodEnabledLocked(imi.getId(), true);
+ final String nextIme;
+ final List<InputMethodInfo> nextEnabledImes;
+ if (userId == mSettings.getCurrentUserId()) {
+ hideCurrentInputLocked(mCurFocusedWindow, 0, null,
+ SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
+ mBindingController.unbindCurrentMethod();
+ // Reset the current IME
+ resetSelectedInputMethodAndSubtypeLocked(null);
+ // Also reset the settings of the current IME
+ mSettings.putSelectedInputMethod(null);
+ // Disable all enabled IMEs.
+ for (InputMethodInfo inputMethodInfo :
+ mSettings.getEnabledInputMethodListLocked()) {
+ setInputMethodEnabledLocked(inputMethodInfo.getId(), false);
+ }
+ // Re-enable with default enabled IMEs.
+ for (InputMethodInfo imi : InputMethodInfoUtils.getDefaultEnabledImes(
+ mContext, mMethodList)) {
+ setInputMethodEnabledLocked(imi.getId(), true);
+ }
+ updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
+ InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
+ getPackageManagerForUser(mContext, mSettings.getCurrentUserId()),
+ mSettings.getEnabledInputMethodListLocked());
+ nextIme = mSettings.getSelectedInputMethod();
+ nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
+ } else {
+ final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
+ final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
+ final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
+ new ArrayMap<>();
+ AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
+ queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
+ methodMap, methodList, DirectBootAwareness.AUTO);
+ final InputMethodSettings settings = new InputMethodSettings(
+ mContext.getResources(), mContext.getContentResolver(), methodMap,
+ userId, false);
+
+ nextEnabledImes = InputMethodInfoUtils.getDefaultEnabledImes(mContext,
+ methodList);
+ nextIme = InputMethodInfoUtils.getMostApplicableDefaultIME(
+ nextEnabledImes).getId();
+
+ // Reset enabled IMEs.
+ settings.putEnabledInputMethodsStr("");
+ nextEnabledImes.forEach(
+ imi -> settings.appendAndPutEnabledInputMethodLocked(
+ imi.getId(), false));
+
+ // Reset selected IME.
+ settings.putSelectedInputMethod(nextIme);
+ settings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
}
- updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
- InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
- getPackageManagerForUser(mContext, mSettings.getCurrentUserId()),
- mSettings.getEnabledInputMethodListLocked());
- nextIme = mSettings.getSelectedInputMethod();
- nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
- } else {
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
- final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
- new ArrayMap<>();
- AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
- queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
- methodMap, methodList, DirectBootAwareness.AUTO);
- final InputMethodSettings settings = new InputMethodSettings(
- mContext.getResources(), mContext.getContentResolver(), methodMap,
- userId, false);
-
- nextEnabledImes = InputMethodInfoUtils.getDefaultEnabledImes(mContext,
- methodList);
- nextIme = InputMethodInfoUtils.getMostApplicableDefaultIME(
- nextEnabledImes).getId();
-
- // Reset enabled IMEs.
- settings.putEnabledInputMethodsStr("");
- nextEnabledImes.forEach(imi -> settings.appendAndPutEnabledInputMethodLocked(
- imi.getId(), false));
-
- // Reset selected IME.
- settings.putSelectedInputMethod(nextIme);
- settings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
+ out.println("Reset current and enabled IMEs for user #" + userId);
+ out.println(" Selected: " + nextIme);
+ nextEnabledImes.forEach(ime -> out.println(" Enabled: " + ime.getId()));
}
- out.println("Reset current and enabled IMEs for user #" + userId);
- out.println(" Selected: " + nextIme);
- nextEnabledImes.forEach(ime -> out.println(" Enabled: " + ime.getId()));
}
}
return ShellCommandResult.SUCCESS;
@@ -6387,23 +6368,26 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@ShellCommandResult
private int handleShellCommandTraceInputMethod(@NonNull ShellCommand shellCommand) {
final String cmd = shellCommand.getNextArgRequired();
- final PrintWriter pw = shellCommand.getOutPrintWriter();
- switch (cmd) {
- case "start":
- ImeTracing.getInstance().startTrace(pw);
- break; // proceed to the next step to update the IME client processes.
- case "stop":
- ImeTracing.getInstance().stopTrace(pw);
- break; // proceed to the next step to update the IME client processes.
- case "save-for-bugreport":
- ImeTracing.getInstance().saveForBugreport(pw);
- return ShellCommandResult.SUCCESS; // no need to update the IME client processes.
- default:
- pw.println("Unknown command: " + cmd);
- pw.println("Input method trace options:");
- pw.println(" start: Start tracing");
- pw.println(" stop: Stop tracing");
- return ShellCommandResult.FAILURE; // no need to update the IME client processes.
+ try (PrintWriter pw = shellCommand.getOutPrintWriter()) {
+ switch (cmd) {
+ case "start":
+ ImeTracing.getInstance().startTrace(pw);
+ break; // proceed to the next step to update the IME client processes.
+ case "stop":
+ ImeTracing.getInstance().stopTrace(pw);
+ break; // proceed to the next step to update the IME client processes.
+ case "save-for-bugreport":
+ ImeTracing.getInstance().saveForBugreport(pw);
+ // no need to update the IME client processes.
+ return ShellCommandResult.SUCCESS;
+ default:
+ pw.println("Unknown command: " + cmd);
+ pw.println("Input method trace options:");
+ pw.println(" start: Start tracing");
+ pw.println(" stop: Stop tracing");
+ // no need to update the IME client processes.
+ return ShellCommandResult.FAILURE;
+ }
}
boolean isImeTraceEnabled = ImeTracing.getInstance().isEnabled();
ArrayMap<IBinder, ClientState> clients;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index 70132670e68e..3373f0c436f9 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -142,7 +142,7 @@ final class InputMethodUtils {
}
continue;
}
- ApplicationInfo ai = null;
+ ApplicationInfo ai;
try {
ai = packageManagerForUser.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(
diff --git a/services/core/java/com/android/server/inputmethod/SubtypeUtils.java b/services/core/java/com/android/server/inputmethod/SubtypeUtils.java
index eb85dd011288..7085868e4f61 100644
--- a/services/core/java/com/android/server/inputmethod/SubtypeUtils.java
+++ b/services/core/java/com/android/server/inputmethod/SubtypeUtils.java
@@ -85,8 +85,8 @@ final class SubtypeUtils {
continue;
}
}
- if (mode == SUBTYPE_MODE_ANY || TextUtils.isEmpty(mode) ||
- mode.equalsIgnoreCase(subtype.getMode())) {
+ if (mode == SUBTYPE_MODE_ANY || TextUtils.isEmpty(mode)
+ || mode.equalsIgnoreCase(subtype.getMode())) {
return true;
}
}
@@ -237,17 +237,20 @@ final class SubtypeUtils {
/**
* If there are no selected subtypes, tries finding the most applicable one according to the
* given locale.
- * @param subtypes this function will search the most applicable subtype in subtypes
- * @param mode subtypes will be filtered by mode
- * @param locale subtypes will be filtered by locale
- * @param canIgnoreLocaleAsLastResort if this function can't find the most applicable subtype,
- * it will return the first subtype matched with mode
+ *
+ * @param subtypes a list of {@link InputMethodSubtype} to search
+ * @param mode the mode used for filtering subtypes
+ * @param locale the locale used for filtering subtypes
+ * @param canIgnoreLocaleAsLastResort when set to {@code true}, if this function can't find the
+ * most applicable subtype, it will return the first subtype
+ * matched with mode
+ *
* @return the most applicable subtypeId
*/
static InputMethodSubtype findLastResortApplicableSubtypeLocked(
Resources res, List<InputMethodSubtype> subtypes, String mode, String locale,
boolean canIgnoreLocaleAsLastResort) {
- if (subtypes == null || subtypes.size() == 0) {
+ if (subtypes == null || subtypes.isEmpty()) {
return null;
}
if (TextUtils.isEmpty(locale)) {
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index c6ea5123d903..25d7d9f766a1 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -938,10 +938,9 @@ public class LocationManagerService extends ILocationManager.Stub implements
return mLocalService.getGnssTimeMillis();
}
+ @android.annotation.EnforcePermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION})
@Override
public void injectLocation(Location location) {
- mContext.enforceCallingPermission(permission.LOCATION_HARDWARE, null);
- mContext.enforceCallingPermission(ACCESS_FINE_LOCATION, null);
Preconditions.checkArgument(location.isComplete());
@@ -1150,10 +1149,9 @@ public class LocationManagerService extends ILocationManager.Stub implements
return Collections.singletonList(identity.getPackageName());
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
@Override
public void setExtraLocationControllerPackage(String packageName) {
- mContext.enforceCallingPermission(permission.LOCATION_HARDWARE,
- permission.LOCATION_HARDWARE + " permission required");
synchronized (mLock) {
mExtraLocationControllerPackage = packageName;
}
@@ -1166,10 +1164,9 @@ public class LocationManagerService extends ILocationManager.Stub implements
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
@Override
public void setExtraLocationControllerPackageEnabled(boolean enabled) {
- mContext.enforceCallingPermission(permission.LOCATION_HARDWARE,
- permission.LOCATION_HARDWARE + " permission required");
synchronized (mLock) {
mExtraLocationControllerPackageEnabled = enabled;
}
@@ -1224,10 +1221,10 @@ public class LocationManagerService extends ILocationManager.Stub implements
return mLocalService.isProviderEnabledForUser(provider, userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
@Override
@RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
public void setAutomotiveGnssSuspended(boolean suspended) {
- mContext.enforceCallingPermission(permission.CONTROL_AUTOMOTIVE_GNSS, null);
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
throw new IllegalStateException(
@@ -1237,10 +1234,10 @@ public class LocationManagerService extends ILocationManager.Stub implements
mGnssManagerService.setAutomotiveGnssSuspended(suspended);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
@Override
@RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS)
public boolean isAutomotiveGnssSuspended() {
- mContext.enforceCallingPermission(permission.CONTROL_AUTOMOTIVE_GNSS, null);
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
throw new IllegalStateException(
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
index c040ad02282d..3cb3431e906b 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
@@ -44,11 +44,15 @@ import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
import android.os.Process;
import android.os.RemoteException;
+import android.os.WorkSource;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.location.ClientBrokerProto;
import java.util.Collections;
@@ -127,6 +131,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
private static final long CHANGE_ID_AUTH_STATE_DENIED = 181350407L;
+ private static final long WAKELOCK_TIMEOUT_MILLIS = 5 * 1000;
/*
* The context of the service.
@@ -157,7 +162,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
* The remote callback interface for this client. This will be set to null whenever the
* client connection is closed (either explicitly or via binder death).
*/
- private IContextHubClientCallback mCallbackInterface = null;
+ private IContextHubClientCallback mCallbackInterface;
/*
* True if the client is still registered with the Context Hub Service, false otherwise.
@@ -165,10 +170,21 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
private boolean mRegistered = true;
/**
- * String containing an attribution tag that was denoted in the {@link Context} of the
- * creator of this broker. This is used when attributing the permissions usage of the broker.
+ * String containing an attribution tag that was denoted in the {@link Context} of the creator
+ * of this broker. This is used when attributing the permissions usage of the broker.
*/
- private @Nullable String mAttributionTag;
+ @Nullable private String mAttributionTag;
+
+ /** Wakelock held while nanoapp message are in flight to the client */
+ @GuardedBy("mWakeLock")
+ private final WakeLock mWakeLock;
+
+ /**
+ * True if {@link #mWakeLock} is open for acquisition. It is set to false after the client is
+ * unregistered.
+ */
+ @GuardedBy("mWakeLock")
+ private boolean mIsWakeLockActive = true;
/*
* Internal interface used to invoke client callbacks.
@@ -210,13 +226,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
/*
* True if a PendingIntent has been cancelled.
*/
- private AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false);
+ private final AtomicBoolean mIsPendingIntentCancelled = new AtomicBoolean(false);
/**
* True if a permissions query has been issued and is being processed. Used to prevent too many
* queries from being issued by a single client at once.
*/
- private AtomicBoolean mIsPermQueryIssued = new AtomicBoolean(false);
+ private final AtomicBoolean mIsPermQueryIssued = new AtomicBoolean(false);
/*
* Map containing all nanoapps this client has a messaging channel with and whether it is
@@ -266,7 +282,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
/*
* Helper class to manage registered PendingIntent requests from the client.
*/
- private class PendingIntentRequest {
+ private static class PendingIntentRequest {
/*
* The PendingIntent object to request, null if there is no open request.
*/
@@ -344,27 +360,60 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
mUid = Binder.getCallingUid();
mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ PowerManager powerManager = context.getSystemService(PowerManager.class);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ mWakeLock.setWorkSource(new WorkSource(mUid, mPackage));
+ mWakeLock.setReferenceCounted(true);
+
startMonitoringOpChanges();
sendHostEndpointConnectedEvent();
}
/* package */ ContextHubClientBroker(
- Context context, IContextHubWrapper contextHubProxy,
- ContextHubClientManager clientManager, ContextHubInfo contextHubInfo,
- short hostEndPointId, IContextHubClientCallback callback, String attributionTag,
- ContextHubTransactionManager transactionManager, String packageName) {
- this(context, contextHubProxy, clientManager, contextHubInfo, hostEndPointId, callback,
- attributionTag, transactionManager, null /* pendingIntent */, 0 /* nanoAppId */,
+ Context context,
+ IContextHubWrapper contextHubProxy,
+ ContextHubClientManager clientManager,
+ ContextHubInfo contextHubInfo,
+ short hostEndPointId,
+ IContextHubClientCallback callback,
+ String attributionTag,
+ ContextHubTransactionManager transactionManager,
+ String packageName) {
+ this(
+ context,
+ contextHubProxy,
+ clientManager,
+ contextHubInfo,
+ hostEndPointId,
+ callback,
+ attributionTag,
+ transactionManager,
+ /* pendingIntent= */ null,
+ /* nanoAppId= */ 0,
packageName);
}
/* package */ ContextHubClientBroker(
- Context context, IContextHubWrapper contextHubProxy,
- ContextHubClientManager clientManager, ContextHubInfo contextHubInfo,
- short hostEndPointId, PendingIntent pendingIntent, long nanoAppId,
- String attributionTag, ContextHubTransactionManager transactionManager) {
- this(context, contextHubProxy, clientManager, contextHubInfo, hostEndPointId,
- null /* callback */, attributionTag, transactionManager, pendingIntent, nanoAppId,
+ Context context,
+ IContextHubWrapper contextHubProxy,
+ ContextHubClientManager clientManager,
+ ContextHubInfo contextHubInfo,
+ short hostEndPointId,
+ PendingIntent pendingIntent,
+ long nanoAppId,
+ String attributionTag,
+ ContextHubTransactionManager transactionManager) {
+ this(
+ context,
+ contextHubProxy,
+ clientManager,
+ contextHubInfo,
+ hostEndPointId,
+ /* callback= */ null,
+ attributionTag,
+ transactionManager,
+ pendingIntent,
+ nanoAppId,
pendingIntent.getCreatorPackage());
}
@@ -560,7 +609,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
* Notifies the client of a hub reset event if the connection is open.
*/
/* package */ void onHubReset() {
- invokeCallback(callback -> callback.onHubReset());
+ invokeCallback(IContextHubClientCallback::onHubReset);
sendPendingIntent(() -> createIntent(ContextHubManager.EVENT_HUB_RESET));
// Re-send the host endpoint connected event as the Context Hub restarted.
@@ -588,7 +637,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
* @return true if the given PendingIntent is currently registered, false otherwise
*/
/* package */ boolean hasPendingIntent(PendingIntent intent, long nanoAppId) {
- PendingIntent pendingIntent = null;
+ PendingIntent pendingIntent;
long intentNanoAppId;
synchronized (this) {
pendingIntent = mPendingIntentRequest.getPendingIntent();
@@ -634,7 +683,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
*/
/* package */ boolean notePermissions(List<String> permissions, String noteMessage) {
for (String permission : permissions) {
- int opCode = mAppOpsManager.permissionToOpCode(permission);
+ int opCode = AppOpsManager.permissionToOpCode(permission);
if (opCode != AppOpsManager.OP_NONE) {
try {
if (mAppOpsManager.noteOp(opCode, mUid, mPackage, mAttributionTag, noteMessage)
@@ -787,6 +836,7 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
private synchronized void invokeCallback(CallbackConsumer consumer) {
if (mCallbackInterface != null) {
try {
+ acquireWakeLock();
consumer.accept(mCallbackInterface);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while invoking client callback (host endpoint ID = "
@@ -850,19 +900,29 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
* Sends a PendingIntent with extra Intent data
*
* @param pendingIntent the PendingIntent
- * @param intent the extra Intent data
+ * @param intent the extra Intent data
*/
private void doSendPendingIntent(PendingIntent pendingIntent, Intent intent) {
try {
String requiredPermission = Manifest.permission.ACCESS_CONTEXT_HUB;
+ acquireWakeLock();
pendingIntent.send(
- mContext, 0 /* code */, intent, null /* onFinished */, null /* Handler */,
- requiredPermission, null /* options */);
+ mContext,
+ /* code= */ 0,
+ intent,
+ /* onFinished= */ this,
+ /* handler= */ null,
+ requiredPermission,
+ /* options= */ null);
} catch (PendingIntent.CanceledException e) {
mIsPendingIntentCancelled.set(true);
// The PendingIntent is no longer valid
- Log.w(TAG, "PendingIntent has been canceled, unregistering from client"
- + " (host endpoint ID " + mHostEndPointId + ")");
+ Log.w(
+ TAG,
+ "PendingIntent has been canceled, unregistering from client"
+ + " (host endpoint ID "
+ + mHostEndPointId
+ + ")");
close();
}
}
@@ -882,13 +942,14 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
mCallbackInterface.asBinder().unlinkToDeath(this, 0 /* flags */);
mCallbackInterface = null;
}
+ // The client is only unregistered and cleared when there is NOT any PendingIntent
if (!mPendingIntentRequest.hasPendingIntent() && mRegistered) {
mClientManager.unregisterClient(mHostEndPointId);
mRegistered = false;
+ mAppOpsManager.stopWatchingMode(this);
+ mContextHubProxy.onHostEndpointDisconnected(mHostEndPointId);
+ releaseWakeLockOnExit();
}
- mAppOpsManager.stopWatchingMode(this);
-
- mContextHubProxy.onHostEndpointDisconnected(mHostEndPointId);
}
private String authStateToString(@ContextHubManager.AuthorizationState int state) {
@@ -939,41 +1000,46 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
@Override
public String toString() {
- String out = "[ContextHubClient ";
- out += "endpointID: " + getHostEndPointId() + ", ";
- out += "contextHub: " + getAttachedContextHubId() + ", ";
+ StringBuilder out = new StringBuilder("[ContextHubClient ");
+ out.append("endpointID: ").append(getHostEndPointId()).append(", ");
+ out.append("contextHub: ").append(getAttachedContextHubId()).append(", ");
if (mAttributionTag != null) {
- out += "attributionTag: " + getAttributionTag() + ", ";
+ out.append("attributionTag: ").append(getAttributionTag()).append(", ");
}
if (mPendingIntentRequest.isValid()) {
- out += "intentCreatorPackage: " + mPackage + ", ";
- out += "nanoAppId: 0x" + Long.toHexString(mPendingIntentRequest.getNanoAppId());
+ out.append("intentCreatorPackage: ").append(mPackage).append(", ");
+ out.append("nanoAppId: 0x")
+ .append(Long.toHexString(mPendingIntentRequest.getNanoAppId()));
} else {
- out += "package: " + mPackage;
+ out.append("package: ").append(mPackage);
}
if (mMessageChannelNanoappIdMap.size() > 0) {
- out += " messageChannelNanoappSet: (";
+ out.append(" messageChannelNanoappSet: (");
Iterator<Map.Entry<Long, Integer>> it =
mMessageChannelNanoappIdMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Long, Integer> entry = it.next();
- out += "0x" + Long.toHexString(entry.getKey()) + " auth state: "
- + authStateToString(entry.getValue());
+ out.append("0x")
+ .append(Long.toHexString(entry.getKey()))
+ .append(" auth state: ")
+ .append(authStateToString(entry.getValue()));
if (it.hasNext()) {
- out += ",";
+ out.append(",");
}
}
- out += ")";
+ out.append(")");
}
- out += "]";
-
- return out;
+ synchronized (mWakeLock) {
+ out.append("wakelock: ").append(mWakeLock);
+ }
+ out.append("]");
+ return out.toString();
}
/** Callback that arrives when direct-call message callback delivery completed */
@Override
public void callbackFinished() {
- // TODO(b/202447392): pending implementation.
+ releaseWakeLock();
}
@Override
@@ -983,6 +1049,62 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
int resultCode,
String resultData,
Bundle resultExtras) {
- // TODO(b/202447392): pending implementation.
+ releaseWakeLock();
+ }
+
+ private void acquireWakeLock() {
+ Binder.withCleanCallingIdentity(
+ () -> {
+ synchronized (mWakeLock) {
+ if (mIsWakeLockActive) {
+ mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+ }
+ }
+ });
+ }
+
+ /**
+ * Releases the wakelock.
+ *
+ * <p>The check-and-release operation should be atomic to avoid overly release.
+ */
+ private void releaseWakeLock() {
+ Binder.withCleanCallingIdentity(
+ () -> {
+ synchronized (mWakeLock) {
+ if (mWakeLock.isHeld()) {
+ try {
+ mWakeLock.release();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Releasing the wakelock fails - ", e);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Releases the wakelock for all the acquisitions during cleanup.
+ *
+ * <p>The check-and-release operation should be atomic to avoid overly release.
+ */
+ private void releaseWakeLockOnExit() {
+ Binder.withCleanCallingIdentity(
+ () -> {
+ synchronized (mWakeLock) {
+ mIsWakeLockActive = false;
+ while (mWakeLock.isHeld()) {
+ try {
+ mWakeLock.release();
+ } catch (RuntimeException e) {
+ Log.e(
+ TAG,
+ "Releasing the wakelock for all acquisitions fails - ",
+ e);
+ break;
+ }
+ }
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 367dc2c4e20a..3ad5fc149d86 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -465,9 +465,9 @@ public class ContextHubService extends IContextHubService.Stub {
new ContextHubShellCommand(mContext, this).exec(this, in, out, err, args, callback, result);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public int registerCallback(IContextHubCallback callback) throws RemoteException {
- checkPermissions();
mCallbacksList.register(callback);
Log.d(TAG, "Added callback, total callbacks " +
@@ -475,15 +475,15 @@ public class ContextHubService extends IContextHubService.Stub {
return 0;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public int[] getContextHubHandles() throws RemoteException {
- checkPermissions();
return ContextHubServiceUtil.createPrimitiveIntArray(mContextHubIdToInfoMap.keySet());
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
- checkPermissions();
if (!mContextHubIdToInfoMap.containsKey(contextHubHandle)) {
Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in getContextHubInfo");
return null;
@@ -492,6 +492,7 @@ public class ContextHubService extends IContextHubService.Stub {
return mContextHubIdToInfoMap.get(contextHubHandle);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Returns a List of ContextHubInfo object describing the available hubs.
*
@@ -499,7 +500,6 @@ public class ContextHubService extends IContextHubService.Stub {
*/
@Override
public List<ContextHubInfo> getContextHubs() throws RemoteException {
- checkPermissions();
return mContextHubInfoList;
}
@@ -563,9 +563,9 @@ public class ContextHubService extends IContextHubService.Stub {
};
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) throws RemoteException {
- checkPermissions();
if (mContextHubWrapper == null) {
return -1;
}
@@ -590,9 +590,9 @@ public class ContextHubService extends IContextHubService.Stub {
return 0;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public int unloadNanoApp(int nanoAppHandle) throws RemoteException {
- checkPermissions();
if (mContextHubWrapper == null) {
return -1;
}
@@ -615,17 +615,17 @@ public class ContextHubService extends IContextHubService.Stub {
return 0;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) throws RemoteException {
- checkPermissions();
return mNanoAppStateManager.getNanoAppInstanceInfo(nanoAppHandle);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public int[] findNanoAppOnHub(
int contextHubHandle, NanoAppFilter filter) throws RemoteException {
- checkPermissions();
ArrayList<Integer> foundInstances = new ArrayList<>();
if (filter != null) {
@@ -667,10 +667,10 @@ public class ContextHubService extends IContextHubService.Stub {
return true;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@Override
public int sendMessage(int contextHubHandle, int nanoAppHandle, ContextHubMessage msg)
throws RemoteException {
- checkPermissions();
if (mContextHubWrapper == null) {
return -1;
}
@@ -849,6 +849,7 @@ public class ContextHubService extends IContextHubService.Stub {
return mContextHubIdToInfoMap.containsKey(contextHubId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Creates and registers a client at the service for the specified Context Hub.
*
@@ -865,7 +866,6 @@ public class ContextHubService extends IContextHubService.Stub {
public IContextHubClient createClient(
int contextHubId, IContextHubClientCallback clientCallback,
@Nullable String attributionTag, String packageName) throws RemoteException {
- checkPermissions();
if (!isValidContextHubId(contextHubId)) {
throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
}
@@ -878,6 +878,7 @@ public class ContextHubService extends IContextHubService.Stub {
contextHubInfo, clientCallback, attributionTag, mTransactionManager, packageName);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Creates and registers a PendingIntent client at the service for the specified Context Hub.
*
@@ -893,7 +894,6 @@ public class ContextHubService extends IContextHubService.Stub {
public IContextHubClient createPendingIntentClient(
int contextHubId, PendingIntent pendingIntent, long nanoAppId,
@Nullable String attributionTag) throws RemoteException {
- checkPermissions();
if (!isValidContextHubId(contextHubId)) {
throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
}
@@ -903,6 +903,7 @@ public class ContextHubService extends IContextHubService.Stub {
contextHubInfo, pendingIntent, nanoAppId, attributionTag, mTransactionManager);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Loads a nanoapp binary at the specified Context hub.
*
@@ -915,7 +916,6 @@ public class ContextHubService extends IContextHubService.Stub {
public void loadNanoAppOnHub(
int contextHubId, IContextHubTransactionCallback transactionCallback,
NanoAppBinary nanoAppBinary) throws RemoteException {
- checkPermissions();
if (!checkHalProxyAndContextHubId(
contextHubId, transactionCallback, ContextHubTransaction.TYPE_LOAD_NANOAPP)) {
return;
@@ -932,6 +932,7 @@ public class ContextHubService extends IContextHubService.Stub {
mTransactionManager.addTransaction(transaction);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Unloads a nanoapp from the specified Context Hub.
*
@@ -944,7 +945,6 @@ public class ContextHubService extends IContextHubService.Stub {
public void unloadNanoAppFromHub(
int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
throws RemoteException {
- checkPermissions();
if (!checkHalProxyAndContextHubId(
contextHubId, transactionCallback, ContextHubTransaction.TYPE_UNLOAD_NANOAPP)) {
return;
@@ -955,6 +955,7 @@ public class ContextHubService extends IContextHubService.Stub {
mTransactionManager.addTransaction(transaction);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Enables a nanoapp at the specified Context Hub.
*
@@ -967,7 +968,6 @@ public class ContextHubService extends IContextHubService.Stub {
public void enableNanoApp(
int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
throws RemoteException {
- checkPermissions();
if (!checkHalProxyAndContextHubId(
contextHubId, transactionCallback, ContextHubTransaction.TYPE_ENABLE_NANOAPP)) {
return;
@@ -978,6 +978,7 @@ public class ContextHubService extends IContextHubService.Stub {
mTransactionManager.addTransaction(transaction);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Disables a nanoapp at the specified Context Hub.
*
@@ -990,7 +991,6 @@ public class ContextHubService extends IContextHubService.Stub {
public void disableNanoApp(
int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
throws RemoteException {
- checkPermissions();
if (!checkHalProxyAndContextHubId(
contextHubId, transactionCallback, ContextHubTransaction.TYPE_DISABLE_NANOAPP)) {
return;
@@ -1001,6 +1001,7 @@ public class ContextHubService extends IContextHubService.Stub {
mTransactionManager.addTransaction(transaction);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
/**
* Queries for a list of nanoapps from the specified Context hub.
*
@@ -1011,7 +1012,6 @@ public class ContextHubService extends IContextHubService.Stub {
@Override
public void queryNanoApps(int contextHubId, IContextHubTransactionCallback transactionCallback)
throws RemoteException {
- checkPermissions();
if (!checkHalProxyAndContextHubId(
contextHubId, transactionCallback, ContextHubTransaction.TYPE_QUERY_NANOAPPS)) {
return;
diff --git a/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java b/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
index 8732065ea009..e4bc78827269 100644
--- a/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
+++ b/services/core/java/com/android/server/location/gnss/NtpTimeHelper.java
@@ -29,8 +29,6 @@ import android.util.NtpTrustedTime;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import java.util.Date;
-
/**
* Handles inject NTP time to GNSS.
*
@@ -194,18 +192,18 @@ class NtpTimeHelper {
return false;
}
- long time = ntpResult.getTimeMillis();
- long timeReference = ntpResult.getElapsedRealtimeMillis();
- long certainty = ntpResult.getCertaintyMillis();
-
+ long unixEpochTimeMillis = ntpResult.getTimeMillis();
+ long timeReferenceMillis = ntpResult.getElapsedRealtimeMillis();
+ int uncertaintyMillis = ntpResult.getUncertaintyMillis();
if (DEBUG) {
- long now = System.currentTimeMillis();
- Log.d(TAG, "NTP server returned: " + time + " (" + new Date(time) + ")"
- + " ntpResult: " + ntpResult + " system time offset: " + (time - now));
+ long currentTimeMillis = System.currentTimeMillis();
+ Log.d(TAG, "NTP server returned: " + unixEpochTimeMillis
+ + " ntpResult: " + ntpResult
+ + " system time offset: " + (unixEpochTimeMillis - currentTimeMillis));
}
- // Ok to cast to int, as can't rollover in practice
- mHandler.post(() -> mCallback.injectTime(time, timeReference, (int) certainty));
+ mHandler.post(() -> mCallback.injectTime(unixEpochTimeMillis, timeReferenceMillis,
+ uncertaintyMillis));
return true;
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ee8a23c08b4a..e9ef8a7bfde1 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1588,6 +1588,11 @@ public class LockSettingsService extends ILockSettings.Stub {
return;
}
+ // Don't send empty credentials on unlock.
+ if (credential.isNone()) {
+ return;
+ }
+
// A profile with a unified lock screen stores a randomly generated credential, so skip it.
// Its parent will send credentials for the profile, as it stores the unified lock
// credential.
@@ -1595,12 +1600,10 @@ public class LockSettingsService extends ILockSettings.Stub {
return;
}
- // RecoverableKeyStoreManager expects null for empty credential.
- final byte[] secret = credential.isNone() ? null : credential.getCredential();
// Send credentials for the user and any child profiles that share its lock screen.
for (int profileId : getProfilesWithSameLockScreen(userId)) {
mRecoverableKeyStoreManager.lockScreenSecretAvailable(
- credential.getType(), secret, profileId);
+ credential.getType(), credential.getCredential(), profileId);
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index d5a759d6c604..76032f45a405 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -43,7 +43,6 @@ class LockSettingsShellCommand extends ShellCommand {
private static final String COMMAND_SET_PIN = "set-pin";
private static final String COMMAND_SET_PASSWORD = "set-password";
private static final String COMMAND_CLEAR = "clear";
- private static final String COMMAND_SP = "sp";
private static final String COMMAND_SET_DISABLED = "set-disabled";
private static final String COMMAND_VERIFY = "verify";
private static final String COMMAND_GET_DISABLED = "get-disabled";
@@ -125,9 +124,6 @@ class LockSettingsShellCommand extends ShellCommand {
case COMMAND_CLEAR:
success = runClear();
break;
- case COMMAND_SP:
- runChangeSp();
- break;
case COMMAND_SET_DISABLED:
runSetDisabled();
break;
@@ -224,20 +220,6 @@ class LockSettingsShellCommand extends ShellCommand {
mNew = getNextArg();
}
- private void runChangeSp() {
- if (mNew != null ) {
- if ("1".equals(mNew)) {
- mLockPatternUtils.enableSyntheticPassword();
- getOutPrintWriter().println("Synthetic password enabled");
- } else if ("0".equals(mNew)) {
- mLockPatternUtils.disableSyntheticPassword();
- getOutPrintWriter().println("Synthetic password disabled");
- }
- }
- getOutPrintWriter().println(String.format("SP Enabled = %b",
- mLockPatternUtils.isSyntheticPasswordEnabled()));
- }
-
private LockscreenCredential getOldCredential() {
if (TextUtils.isEmpty(mOld)) {
return LockscreenCredential.createNone();
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 8161503652ff..ec66599ebe82 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -44,7 +44,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.CredentialType;
import com.android.server.LocalServices;
import com.android.server.PersistentDataBlockManagerInternal;
import com.android.server.utils.WatchableImpl;
@@ -71,7 +70,6 @@ class LockSettingsStorage extends WatchableImpl {
private static final String TAG = "LockSettingsStorage";
private static final String TABLE = "locksettings";
- private static final boolean DEBUG = false;
private static final String COLUMN_KEY = "name";
private static final String COLUMN_USERID = "user";
@@ -84,11 +82,10 @@ class LockSettingsStorage extends WatchableImpl {
COLUMN_KEY, COLUMN_VALUE
};
- private static final String SYSTEM_DIRECTORY = "/system/";
private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
private static final String REBOOT_ESCROW_FILE = "reboot.escrow.key";
- private static final String REBOOT_ESCROW_SERVER_BLOB = "reboot.escrow.server.blob.key";
+ private static final String REBOOT_ESCROW_SERVER_BLOB_FILE = "reboot.escrow.server.blob.key";
private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
@@ -108,39 +105,6 @@ class LockSettingsStorage extends WatchableImpl {
private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
- @VisibleForTesting
- public static class CredentialHash {
-
- private CredentialHash(byte[] hash, @CredentialType int type) {
- if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
- if (hash == null) {
- throw new IllegalArgumentException("Empty hash for CredentialHash");
- }
- } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
- if (hash != null) {
- throw new IllegalArgumentException(
- "None type CredentialHash should not have hash");
- }
- }
- this.hash = hash;
- this.type = type;
- }
-
- static CredentialHash create(byte[] hash, int type) {
- if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
- throw new IllegalArgumentException("Bad type for CredentialHash");
- }
- return new CredentialHash(hash, type);
- }
-
- static CredentialHash createEmptyHash() {
- return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE);
- }
-
- byte[] hash;
- @CredentialType int type;
- }
-
public LockSettingsStorage(Context context) {
mContext = context;
mOpenHelper = new DatabaseHelper(context);
@@ -259,13 +223,7 @@ class LockSettingsStorage extends WatchableImpl {
}
public void removeChildProfileLock(int userId) {
- if (DEBUG)
- Slog.e(TAG, "Remove child profile lock for user: " + userId);
- try {
- deleteFile(getChildProfileLockFile(userId));
- } catch (Exception e) {
- e.printStackTrace();
- }
+ deleteFile(getChildProfileLockFile(userId));
}
public void writeChildProfileLock(int userId, byte[] lock) {
@@ -297,39 +255,39 @@ class LockSettingsStorage extends WatchableImpl {
}
public void writeRebootEscrowServerBlob(byte[] serverBlob) {
- writeFile(getRebootEscrowServerBlob(), serverBlob);
+ writeFile(getRebootEscrowServerBlobFile(), serverBlob);
}
public byte[] readRebootEscrowServerBlob() {
- return readFile(getRebootEscrowServerBlob());
+ return readFile(getRebootEscrowServerBlobFile());
}
public boolean hasRebootEscrowServerBlob() {
- return hasFile(getRebootEscrowServerBlob());
+ return hasFile(getRebootEscrowServerBlobFile());
}
public void removeRebootEscrowServerBlob() {
- deleteFile(getRebootEscrowServerBlob());
+ deleteFile(getRebootEscrowServerBlobFile());
}
- private boolean hasFile(String name) {
- byte[] contents = readFile(name);
+ private boolean hasFile(File path) {
+ byte[] contents = readFile(path);
return contents != null && contents.length > 0;
}
- private byte[] readFile(String name) {
+ private byte[] readFile(File path) {
int version;
synchronized (mCache) {
- if (mCache.hasFile(name)) {
- return mCache.peekFile(name);
+ if (mCache.hasFile(path)) {
+ return mCache.peekFile(path);
}
version = mCache.getVersion();
}
- byte[] stored = null;
- try (RandomAccessFile raf = new RandomAccessFile(name, "r")) {
- stored = new byte[(int) raf.length()];
- raf.readFully(stored, 0, stored.length);
+ byte[] data = null;
+ try (RandomAccessFile raf = new RandomAccessFile(path, "r")) {
+ data = new byte[(int) raf.length()];
+ raf.readFully(data, 0, data.length);
raf.close();
} catch (FileNotFoundException suppressed) {
// readFile() is also called by hasFile() to check the existence of files, in this
@@ -337,8 +295,8 @@ class LockSettingsStorage extends WatchableImpl {
} catch (IOException e) {
Slog.e(TAG, "Cannot read file " + e);
}
- mCache.putFileIfUnchanged(name, stored, version);
- return stored;
+ mCache.putFileIfUnchanged(path, data, version);
+ return data;
}
private void fsyncDirectory(File directory) {
@@ -352,23 +310,21 @@ class LockSettingsStorage extends WatchableImpl {
}
}
- private void writeFile(String name, byte[] hash) {
+ private void writeFile(File path, byte[] data) {
synchronized (mFileWriteLock) {
RandomAccessFile raf = null;
try {
- // Write the hash to file, requiring each write to be synchronized to the
+ // Write the data to the file, requiring each write to be synchronized to the
// underlying storage device immediately to avoid data loss in case of power loss.
- // This also ensures future secdiscard operation on the file succeeds since the
- // file would have been allocated on flash.
- raf = new RandomAccessFile(name, "rws");
- // Truncate the file if pattern is null, to clear the lock
- if (hash == null || hash.length == 0) {
+ raf = new RandomAccessFile(path, "rws");
+ // Truncate the file if the data is empty.
+ if (data == null || data.length == 0) {
raf.setLength(0);
} else {
- raf.write(hash, 0, hash.length);
+ raf.write(data, 0, data.length);
}
raf.close();
- fsyncDirectory((new File(name)).getAbsoluteFile().getParentFile());
+ fsyncDirectory(path.getParentFile());
} catch (IOException e) {
Slog.e(TAG, "Error writing to file " + e);
} finally {
@@ -380,74 +336,66 @@ class LockSettingsStorage extends WatchableImpl {
}
}
}
- mCache.putFile(name, hash);
+ mCache.putFile(path, data);
dispatchChange(this);
}
}
- private void deleteFile(String name) {
- if (DEBUG) Slog.e(TAG, "Delete file " + name);
+ private void deleteFile(File path) {
synchronized (mFileWriteLock) {
- File file = new File(name);
- if (file.exists()) {
- file.delete();
- mCache.putFile(name, null);
+ if (path.exists()) {
+ // Zeroize the file to try to make its contents unrecoverable. This is *not*
+ // guaranteed to be effective, and in fact it usually isn't, but it doesn't hurt.
+ try (RandomAccessFile raf = new RandomAccessFile(path, "rws")) {
+ final int fileSize = (int) raf.length();
+ raf.write(new byte[fileSize]);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failed to zeroize " + path, e);
+ }
+ path.delete();
+ dispatchChange(this);
+ mCache.putFile(path, null);
}
- dispatchChange(this);
}
}
@VisibleForTesting
- String getChildProfileLockFile(int userId) {
- return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
+ File getChildProfileLockFile(int userId) {
+ return getLockCredentialFileForUser(userId, CHILD_PROFILE_LOCK_FILE);
}
@VisibleForTesting
- String getRebootEscrowFile(int userId) {
- return getLockCredentialFilePathForUser(userId, REBOOT_ESCROW_FILE);
+ File getRebootEscrowFile(int userId) {
+ return getLockCredentialFileForUser(userId, REBOOT_ESCROW_FILE);
}
@VisibleForTesting
- String getRebootEscrowServerBlob() {
+ File getRebootEscrowServerBlobFile() {
// There is a single copy of server blob for all users.
- return getLockCredentialFilePathForUser(UserHandle.USER_SYSTEM, REBOOT_ESCROW_SERVER_BLOB);
+ return getLockCredentialFileForUser(UserHandle.USER_SYSTEM, REBOOT_ESCROW_SERVER_BLOB_FILE);
}
- private String getLockCredentialFilePathForUser(int userId, String basename) {
- String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
- SYSTEM_DIRECTORY;
+ private File getLockCredentialFileForUser(int userId, String fileName) {
if (userId == 0) {
- // Leave it in the same place for user 0
- return dataSystemDirectory + basename;
+ // The files for user 0 are stored directly in /data/system, since this is where they
+ // originally were, and they haven't been moved yet.
+ return new File(Environment.getDataSystemDirectory(), fileName);
} else {
- return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
+ return new File(Environment.getUserSystemDirectory(userId), fileName);
}
}
public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
ensureSyntheticPasswordDirectoryForUser(userId);
- writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
+ writeFile(getSyntheticPasswordStateFileForUser(userId, handle, name), data);
}
public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
- return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
+ return readFile(getSyntheticPasswordStateFileForUser(userId, handle, name));
}
public void deleteSyntheticPasswordState(int userId, long handle, String name) {
- String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
- File file = new File(path);
- if (file.exists()) {
- try (RandomAccessFile raf = new RandomAccessFile(path, "rws")) {
- final int fileSize = (int) raf.length();
- raf.write(new byte[fileSize]);
- } catch (Exception e) {
- Slog.w(TAG, "Failed to zeroize " + path, e);
- } finally {
- file.delete();
- dispatchChange(this);
- }
- mCache.putFile(path, null);
- }
+ deleteFile(getSyntheticPasswordStateFileForUser(userId, handle, name));
}
public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
@@ -481,7 +429,7 @@ class LockSettingsStorage extends WatchableImpl {
@VisibleForTesting
protected File getSyntheticPasswordDirectoryForUser(int userId) {
- return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
+ return new File(Environment.getDataSystemDeDirectory(userId), SYNTHETIC_PASSWORD_DIRECTORY);
}
/** Ensure per-user directory for synthetic password state exists */
@@ -492,12 +440,9 @@ class LockSettingsStorage extends WatchableImpl {
}
}
- @VisibleForTesting
- protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
- String name) {
- final File baseDir = getSyntheticPasswordDirectoryForUser(userId);
- final String baseName = formatSimple("%016x.%s", handle, name);
- return new File(baseDir, baseName).getAbsolutePath();
+ private File getSyntheticPasswordStateFileForUser(int userId, long handle, String name) {
+ String fileName = formatSimple("%016x.%s", handle, name);
+ return new File(getSyntheticPasswordDirectoryForUser(userId), fileName);
}
public void removeUser(int userId) {
@@ -523,7 +468,7 @@ class LockSettingsStorage extends WatchableImpl {
// The directory itself will be deleted as part of user deletion operation by the
// framework, so only need to purge cache here.
//TODO: (b/34600579) invoke secdiscardable
- mCache.purgePath(spStateDir.getAbsolutePath());
+ mCache.purgePath(spStateDir);
} finally {
db.endTransaction();
}
@@ -704,7 +649,7 @@ class LockSettingsStorage extends WatchableImpl {
final UserManager um = UserManager.get(mContext);
for (UserInfo user : um.getUsers()) {
File userPath = getSyntheticPasswordDirectoryForUser(user.id);
- pw.println(String.format("User %d [%s]:", user.id, userPath.getAbsolutePath()));
+ pw.println(String.format("User %d [%s]:", user.id, userPath));
pw.increaseIndent();
File[] files = userPath.listFiles();
if (files != null) {
@@ -817,20 +762,21 @@ class LockSettingsStorage extends WatchableImpl {
remove(CacheKey.TYPE_KEY_VALUE, key, userId);
}
- byte[] peekFile(String fileName) {
- return copyOf((byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */));
+ byte[] peekFile(File path) {
+ return copyOf((byte[]) peek(CacheKey.TYPE_FILE, path.toString(), -1 /* userId */));
}
- boolean hasFile(String fileName) {
- return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+ boolean hasFile(File path) {
+ return contains(CacheKey.TYPE_FILE, path.toString(), -1 /* userId */);
}
- void putFile(String key, byte[] value) {
- put(CacheKey.TYPE_FILE, key, copyOf(value), -1 /* userId */);
+ void putFile(File path, byte[] data) {
+ put(CacheKey.TYPE_FILE, path.toString(), copyOf(data), -1 /* userId */);
}
- void putFileIfUnchanged(String key, byte[] value, int version) {
- putIfUnchanged(CacheKey.TYPE_FILE, key, copyOf(value), -1 /* userId */, version);
+ void putFileIfUnchanged(File path, byte[] data, int version) {
+ putIfUnchanged(CacheKey.TYPE_FILE, path.toString(), copyOf(data), -1 /* userId */,
+ version);
}
void setFetched(int userId) {
@@ -888,10 +834,11 @@ class LockSettingsStorage extends WatchableImpl {
return data != null ? Arrays.copyOf(data, data.length) : null;
}
- synchronized void purgePath(String path) {
+ synchronized void purgePath(File path) {
+ final String pathStr = path.toString();
for (int i = mCache.size() - 1; i >= 0; i--) {
CacheKey entry = mCache.keyAt(i);
- if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
+ if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(pathStr)) {
mCache.removeAt(i);
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index 2cb89b314b33..ec0d9856486d 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -122,7 +122,7 @@ public class KeySyncTask implements Runnable {
* @param recoverableKeyStoreDb Database where the keys are stored.
* @param userId The uid of the user whose profile has been unlocked.
* @param credentialType The type of credential as defined in {@code LockPatternUtils}
- * @param credential The credential, encoded as a {@link String}.
+ * @param credential The credential, encoded as a byte array
* @param credentialUpdated signals weather credentials were updated.
* @param platformKeyManager platform key manager
* @param testOnlyInsecureCertificateHelper utility class used for end-to-end tests
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index b49bced4e567..e620c80b8e28 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -900,14 +900,13 @@ public class RecoverableKeyStoreManager {
/**
* This function can only be used inside LockSettingsService.
*
- * @param storedHashType from {@code CredentialHash}
- * @param credential - unencrypted byte array. Password length should be at most 16 symbols
- * {@code mPasswordMaxLength}
- * @param userId for user who just unlocked the device.
+ * @param credentialType the type of credential, as defined in {@code LockPatternUtils}
+ * @param credential the credential, encoded as a byte array
+ * @param userId the ID of the user to whom the credential belongs
* @hide
*/
public void lockScreenSecretAvailable(
- int storedHashType, @NonNull byte[] credential, int userId) {
+ int credentialType, @NonNull byte[] credential, int userId) {
// So as not to block the critical path unlocking the phone, defer to another thread.
try {
mExecutorService.schedule(KeySyncTask.newInstance(
@@ -916,7 +915,7 @@ public class RecoverableKeyStoreManager {
mSnapshotStorage,
mListenersStorage,
userId,
- storedHashType,
+ credentialType,
credential,
/*credentialUpdated=*/ false),
SYNC_DELAY_MILLIS,
@@ -934,13 +933,13 @@ public class RecoverableKeyStoreManager {
/**
* This function can only be used inside LockSettingsService.
*
- * @param storedHashType from {@code CredentialHash}
- * @param credential - unencrypted byte array
- * @param userId for the user whose lock screen credentials were changed.
+ * @param credentialType the type of the new credential, as defined in {@code LockPatternUtils}
+ * @param credential the new credential, encoded as a byte array
+ * @param userId the ID of the user whose credential was changed
* @hide
*/
public void lockScreenSecretChanged(
- int storedHashType,
+ int credentialType,
@Nullable byte[] credential,
int userId) {
// So as not to block the critical path unlocking the phone, defer to another thread.
@@ -951,7 +950,7 @@ public class RecoverableKeyStoreManager {
mSnapshotStorage,
mListenersStorage,
userId,
- storedHashType,
+ credentialType,
credential,
/*credentialUpdated=*/ true),
SYNC_DELAY_MILLIS,
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f2a12b468fef..99a488c27dbb 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -4035,6 +4035,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
fout.decreaseIndent();
+ fout.println("Network to interfaces:");
+ fout.increaseIndent();
+ for (int i = 0; i < mNetworkToIfaces.size(); ++i) {
+ final int key = mNetworkToIfaces.keyAt(i);
+ fout.println(key + ": " + mNetworkToIfaces.get(key));
+ }
+ fout.decreaseIndent();
+
fout.println();
mStatLogger.dump(fout);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e35e4c9b178b..1369f27e9e46 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1795,6 +1795,7 @@ public class NotificationManagerService extends SystemService {
if (userHandle >= 0) {
cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, true, userHandle,
REASON_PROFILE_TURNED_OFF, null);
+ mSnoozeHelper.clearData(userHandle);
}
} else if (action.equals(Intent.ACTION_USER_PRESENT)) {
// turn off LED when user passes through lock screen
@@ -3386,11 +3387,9 @@ public class NotificationManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
@Override
public void setToastRateLimitingEnabled(boolean enable) {
- getContext().enforceCallingPermission(
- android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING,
- "App doesn't have the permission to enable/disable toast rate limiting");
synchronized (mToastQueue) {
int uid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 1b669322e553..12324bff0c7a 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -17,6 +17,7 @@
package com.android.server.notification;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -176,9 +177,8 @@ public final class PermissionHelper {
mPermManager.revokeRuntimePermission(packageName, NOTIFICATION_PERMISSION,
userId, TAG);
}
- int flagMask = userSet || !grant
- ? FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT :
- FLAG_PERMISSION_USER_SET;
+ int flagMask = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED;
+ flagMask = userSet || !grant ? flagMask | FLAG_PERMISSION_GRANTED_BY_DEFAULT : flagMask;
if (userSet) {
mPermManager.updatePermissionFlags(packageName, NOTIFICATION_PERMISSION,
flagMask, FLAG_PERMISSION_USER_SET, true, userId);
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index 15d7c1e7a210..61936df4a124 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -16,7 +16,6 @@
package com.android.server.notification;
import android.annotation.NonNull;
-import android.annotation.UserIdInt;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -25,7 +24,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Binder;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
@@ -38,18 +36,15 @@ import android.util.TypedXmlSerializer;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.util.XmlUtils;
import com.android.server.pm.PackageManagerService;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -59,7 +54,7 @@ import java.util.Set;
/**
* NotificationManagerService helper for handling snoozed notifications.
*/
-public class SnoozeHelper {
+public final class SnoozeHelper {
public static final int XML_SNOOZED_NOTIFICATION_VERSION = 1;
static final int CONCURRENT_SNOOZE_LIMIT = 500;
@@ -68,8 +63,6 @@ public class SnoozeHelper {
private static final String XML_SNOOZED_NOTIFICATION = "notification";
private static final String XML_SNOOZED_NOTIFICATION_CONTEXT = "context";
- private static final String XML_SNOOZED_NOTIFICATION_PKG = "pkg";
- private static final String XML_SNOOZED_NOTIFICATION_USER_ID = "user-id";
private static final String XML_SNOOZED_NOTIFICATION_KEY = "key";
//the time the snoozed notification should be reposted
private static final String XML_SNOOZED_NOTIFICATION_TIME = "time";
@@ -91,24 +84,19 @@ public class SnoozeHelper {
private AlarmManager mAm;
private final ManagedServices.UserProfiles mUserProfiles;
- // User id | package name : notification key : record.
- private ArrayMap<String, ArrayMap<String, NotificationRecord>>
- mSnoozedNotifications = new ArrayMap<>();
- // User id | package name : notification key : time-milliseconds .
+ // notification key : record.
+ private ArrayMap<String, NotificationRecord> mSnoozedNotifications = new ArrayMap<>();
+ // notification key : time-milliseconds .
// This member stores persisted snoozed notification trigger times. it persists through reboots
// It should have the notifications that haven't expired or re-posted yet
- private final ArrayMap<String, ArrayMap<String, Long>>
- mPersistedSnoozedNotifications = new ArrayMap<>();
- // User id | package name : notification key : creation ID .
+ private final ArrayMap<String, Long> mPersistedSnoozedNotifications = new ArrayMap<>();
+ // notification key : creation ID.
// This member stores persisted snoozed notification trigger context for the assistant
// it persists through reboots.
// It should have the notifications that haven't expired or re-posted yet
- private final ArrayMap<String, ArrayMap<String, String>>
+ private final ArrayMap<String, String>
mPersistedSnoozedNotificationsWithContext = new ArrayMap<>();
- // notification key : package.
- private ArrayMap<String, String> mPackages = new ArrayMap<>();
- // key : userId
- private ArrayMap<String, Integer> mUsers = new ArrayMap<>();
+
private Callback mCallback;
private final Object mLock = new Object();
@@ -125,21 +113,9 @@ public class SnoozeHelper {
mUserProfiles = userProfiles;
}
- private String getPkgKey(@UserIdInt int userId, String pkg) {
- return userId + "|" + pkg;
- }
-
- void cleanupPersistedContext(String key){
- synchronized (mLock) {
- int userId = mUsers.get(key);
- String pkg = mPackages.get(key);
- removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
- }
- }
-
protected boolean canSnooze(int numberToSnooze) {
synchronized (mLock) {
- if ((mPackages.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
+ if ((mSnoozedNotifications.size() + numberToSnooze) > CONCURRENT_SNOOZE_LIMIT) {
return false;
}
}
@@ -150,11 +126,7 @@ public class SnoozeHelper {
protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) {
Long time = null;
synchronized (mLock) {
- ArrayMap<String, Long> snoozed =
- mPersistedSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (snoozed != null) {
- time = snoozed.get(key);
- }
+ time = mPersistedSnoozedNotifications.get(key);
}
if (time == null) {
time = 0L;
@@ -164,29 +136,26 @@ public class SnoozeHelper {
protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) {
synchronized (mLock) {
- ArrayMap<String, String> snoozed =
- mPersistedSnoozedNotificationsWithContext.get(getPkgKey(userId, pkg));
- if (snoozed != null) {
- return snoozed.get(key);
- }
+ return mPersistedSnoozedNotificationsWithContext.get(key);
}
- return null;
}
protected boolean isSnoozed(int userId, String pkg, String key) {
synchronized (mLock) {
- return mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))
- && mSnoozedNotifications.get(getPkgKey(userId, pkg)).containsKey(key);
+ return mSnoozedNotifications.containsKey(key);
}
}
protected Collection<NotificationRecord> getSnoozed(int userId, String pkg) {
synchronized (mLock) {
- if (mSnoozedNotifications.containsKey(getPkgKey(userId, pkg))) {
- return mSnoozedNotifications.get(getPkgKey(userId, pkg)).values();
+ ArrayList snoozed = new ArrayList();
+ for (NotificationRecord r : mSnoozedNotifications.values()) {
+ if (r.getUserId() == userId && r.getSbn().getPackageName().equals(pkg)) {
+ snoozed.add(r);
+ }
}
+ return snoozed;
}
- return Collections.EMPTY_LIST;
}
@NonNull
@@ -194,15 +163,11 @@ public class SnoozeHelper {
String groupKey, Integer userId) {
ArrayList<NotificationRecord> records = new ArrayList<>();
synchronized (mLock) {
- ArrayMap<String, NotificationRecord> allRecords =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (allRecords != null) {
- for (int i = 0; i < allRecords.size(); i++) {
- NotificationRecord r = allRecords.valueAt(i);
- String currentGroupKey = r.getSbn().getGroup();
- if (Objects.equals(currentGroupKey, groupKey)) {
- records.add(r);
- }
+ for (int i = 0; i < mSnoozedNotifications.size(); i++) {
+ NotificationRecord r = mSnoozedNotifications.valueAt(i);
+ if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId
+ && Objects.equals(r.getSbn().getGroup(), groupKey)) {
+ records.add(r);
}
}
}
@@ -211,31 +176,16 @@ public class SnoozeHelper {
protected NotificationRecord getNotification(String key) {
synchronized (mLock) {
- if (!mUsers.containsKey(key) || !mPackages.containsKey(key)) {
- Slog.w(TAG, "Snoozed data sets no longer agree for " + key);
- return null;
- }
- int userId = mUsers.get(key);
- String pkg = mPackages.get(key);
- ArrayMap<String, NotificationRecord> snoozed =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (snoozed == null) {
- return null;
- }
- return snoozed.get(key);
+ return mSnoozedNotifications.get(key);
}
}
protected @NonNull List<NotificationRecord> getSnoozed() {
synchronized (mLock) {
- // caller filters records based on the current user profiles and listener access, so just
- // return everything
+ // caller filters records based on the current user profiles and listener access,
+ // so just return everything
List<NotificationRecord> snoozed = new ArrayList<>();
- for (String userPkgKey : mSnoozedNotifications.keySet()) {
- ArrayMap<String, NotificationRecord> snoozedRecords =
- mSnoozedNotifications.get(userPkgKey);
- snoozed.addAll(snoozedRecords.values());
- }
+ snoozed.addAll(mSnoozedNotifications.values());
return snoozed;
}
}
@@ -244,15 +194,13 @@ public class SnoozeHelper {
* Snoozes a notification and schedules an alarm to repost at that time.
*/
protected void snooze(NotificationRecord record, long duration) {
- String pkg = record.getSbn().getPackageName();
String key = record.getKey();
- int userId = record.getUser().getIdentifier();
snooze(record);
- scheduleRepost(pkg, key, userId, duration);
+ scheduleRepost(key, duration);
Long activateAt = System.currentTimeMillis() + duration;
synchronized (mLock) {
- storeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications, activateAt);
+ mPersistedSnoozedNotifications.put(key, activateAt);
}
}
@@ -260,66 +208,33 @@ public class SnoozeHelper {
* Records a snoozed notification.
*/
protected void snooze(NotificationRecord record, String contextId) {
- int userId = record.getUser().getIdentifier();
if (contextId != null) {
synchronized (mLock) {
- storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
- userId, mPersistedSnoozedNotificationsWithContext, contextId);
+ mPersistedSnoozedNotificationsWithContext.put(record.getKey(), contextId);
}
}
snooze(record);
}
private void snooze(NotificationRecord record) {
- int userId = record.getUser().getIdentifier();
if (DEBUG) {
Slog.d(TAG, "Snoozing " + record.getKey());
}
synchronized (mLock) {
- storeRecordLocked(record.getSbn().getPackageName(), record.getKey(),
- userId, mSnoozedNotifications, record);
+ mSnoozedNotifications.put(record.getKey(), record);
}
}
- private <T> void storeRecordLocked(String pkg, String key, Integer userId,
- ArrayMap<String, ArrayMap<String, T>> targets, T object) {
-
- mPackages.put(key, pkg);
- mUsers.put(key, userId);
- ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg));
- if (keyToValue == null) {
- keyToValue = new ArrayMap<>();
- }
- keyToValue.put(key, object);
- targets.put(getPkgKey(userId, pkg), keyToValue);
- }
-
- private <T> T removeRecordLocked(String pkg, String key, Integer userId,
- ArrayMap<String, ArrayMap<String, T>> targets) {
- T object = null;
- ArrayMap<String, T> keyToValue = targets.get(getPkgKey(userId, pkg));
- if (keyToValue == null) {
- return null;
- }
- object = keyToValue.remove(key);
- if (keyToValue.size() == 0) {
- targets.remove(getPkgKey(userId, pkg));
- }
- return object;
- }
-
protected boolean cancel(int userId, String pkg, String tag, int id) {
synchronized (mLock) {
- ArrayMap<String, NotificationRecord> recordsForPkg =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (recordsForPkg != null) {
- final Set<Map.Entry<String, NotificationRecord>> records = recordsForPkg.entrySet();
- for (Map.Entry<String, NotificationRecord> record : records) {
- final StatusBarNotification sbn = record.getValue().getSbn();
- if (Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
- record.getValue().isCanceled = true;
- return true;
- }
+ final Set<Map.Entry<String, NotificationRecord>> records =
+ mSnoozedNotifications.entrySet();
+ for (Map.Entry<String, NotificationRecord> record : records) {
+ final StatusBarNotification sbn = record.getValue().getSbn();
+ if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId
+ && Objects.equals(sbn.getTag(), tag) && sbn.getId() == id) {
+ record.getValue().isCanceled = true;
+ return true;
}
}
}
@@ -336,11 +251,9 @@ public class SnoozeHelper {
if (includeCurrentProfiles) {
userIds = mUserProfiles.getCurrentProfileIds();
}
- for (ArrayMap<String, NotificationRecord> snoozedRecords : mSnoozedNotifications.values()) {
- for (NotificationRecord r : snoozedRecords.values()) {
- if (userIds.binarySearch(r.getUserId()) >= 0) {
- r.isCanceled = true;
- }
+ for (NotificationRecord r : mSnoozedNotifications.values()) {
+ if (userIds.binarySearch(r.getUserId()) >= 0) {
+ r.isCanceled = true;
}
}
}
@@ -348,14 +261,12 @@ public class SnoozeHelper {
protected boolean cancel(int userId, String pkg) {
synchronized (mLock) {
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (records == null) {
- return false;
- }
- int N = records.size();
- for (int i = 0; i < N; i++) {
- records.valueAt(i).isCanceled = true;
+ int n = mSnoozedNotifications.size();
+ for (int i = 0; i < n; i++) {
+ final NotificationRecord r = mSnoozedNotifications.valueAt(i);
+ if (r.getSbn().getPackageName().equals(pkg) && r.getUserId() == userId) {
+ r.isCanceled = true;
+ }
}
return true;
}
@@ -366,20 +277,17 @@ public class SnoozeHelper {
*/
protected void update(int userId, NotificationRecord record) {
synchronized (mLock) {
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, record.getSbn().getPackageName()));
- if (records == null) {
- return;
+ if (mSnoozedNotifications.containsKey(record.getKey())) {
+ mSnoozedNotifications.put(record.getKey(), record);
}
- records.put(record.getKey(), record);
}
}
protected void repost(String key, boolean muteOnReturn) {
synchronized (mLock) {
- Integer userId = mUsers.get(key);
- if (userId != null) {
- repost(key, userId, muteOnReturn);
+ final NotificationRecord r = mSnoozedNotifications.get(key);
+ if (r != null) {
+ repost(key, r.getUserId(), muteOnReturn);
}
}
}
@@ -387,43 +295,30 @@ public class SnoozeHelper {
protected void repost(String key, int userId, boolean muteOnReturn) {
NotificationRecord record;
synchronized (mLock) {
- final String pkg = mPackages.remove(key);
- mUsers.remove(key);
- removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotifications);
- removeRecordLocked(pkg, key, userId, mPersistedSnoozedNotificationsWithContext);
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (records == null) {
- return;
- }
- record = records.remove(key);
-
+ mPersistedSnoozedNotifications.remove(key);
+ mPersistedSnoozedNotificationsWithContext.remove(key);
+ record = mSnoozedNotifications.remove(key);
}
if (record != null && !record.isCanceled) {
- final PendingIntent pi = createPendingIntent(
- record.getSbn().getPackageName(), record.getKey(), userId);
+ final PendingIntent pi = createPendingIntent(record.getKey());
mAm.cancel(pi);
MetricsLogger.action(record.getLogMaker()
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
- mCallback.repost(userId, record, muteOnReturn);
+ mCallback.repost(record.getUserId(), record, muteOnReturn);
}
}
protected void repostGroupSummary(String pkg, int userId, String groupKey) {
synchronized (mLock) {
- ArrayMap<String, NotificationRecord> recordsByKey
- = mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (recordsByKey == null) {
- return;
- }
-
String groupSummaryKey = null;
- int N = recordsByKey.size();
- for (int i = 0; i < N; i++) {
- final NotificationRecord potentialGroupSummary = recordsByKey.valueAt(i);
- if (potentialGroupSummary.getSbn().isGroup()
+ int n = mSnoozedNotifications.size();
+ for (int i = 0; i < n; i++) {
+ final NotificationRecord potentialGroupSummary = mSnoozedNotifications.valueAt(i);
+ if (potentialGroupSummary.getSbn().getPackageName().equals(pkg)
+ && potentialGroupSummary.getUserId() == userId
+ && potentialGroupSummary.getSbn().isGroup()
&& potentialGroupSummary.getNotification().isGroupSummary()
&& groupKey.equals(potentialGroupSummary.getGroupKey())) {
groupSummaryKey = potentialGroupSummary.getKey();
@@ -432,16 +327,14 @@ public class SnoozeHelper {
}
if (groupSummaryKey != null) {
- NotificationRecord record = recordsByKey.remove(groupSummaryKey);
- mPackages.remove(groupSummaryKey);
- mUsers.remove(groupSummaryKey);
+ NotificationRecord record = mSnoozedNotifications.remove(groupSummaryKey);
if (record != null && !record.isCanceled) {
Runnable runnable = () -> {
MetricsLogger.action(record.getLogMaker()
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
.setType(MetricsProto.MetricsEvent.TYPE_OPEN));
- mCallback.repost(userId, record, false);
+ mCallback.repost(record.getUserId(), record, false);
};
runnable.run();
}
@@ -451,20 +344,40 @@ public class SnoozeHelper {
protected void clearData(int userId, String pkg) {
synchronized (mLock) {
- ArrayMap<String, NotificationRecord> records =
- mSnoozedNotifications.get(getPkgKey(userId, pkg));
- if (records == null) {
- return;
+ int n = mSnoozedNotifications.size();
+ for (int i = n - 1; i >= 0; i--) {
+ final NotificationRecord record = mSnoozedNotifications.valueAt(i);
+ if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) {
+ mSnoozedNotifications.removeAt(i);
+ mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
+ mPersistedSnoozedNotifications.remove(record.getKey());
+ Runnable runnable = () -> {
+ final PendingIntent pi = createPendingIntent(record.getKey());
+ mAm.cancel(pi);
+ MetricsLogger.action(record.getLogMaker()
+ .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
+ .setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
+ };
+ runnable.run();
+ }
}
- for (int i = records.size() - 1; i >= 0; i--) {
- final NotificationRecord r = records.removeAt(i);
- if (r != null) {
- mPackages.remove(r.getKey());
- mUsers.remove(r.getKey());
+ }
+ }
+
+ protected void clearData(int userId) {
+ synchronized (mLock) {
+ int n = mSnoozedNotifications.size();
+ for (int i = n - 1; i >= 0; i--) {
+ final NotificationRecord record = mSnoozedNotifications.valueAt(i);
+ if (record.getUserId() == userId) {
+ mSnoozedNotifications.removeAt(i);
+ mPersistedSnoozedNotificationsWithContext.remove(record.getKey());
+ mPersistedSnoozedNotifications.remove(record.getKey());
+
Runnable runnable = () -> {
- final PendingIntent pi = createPendingIntent(pkg, r.getKey(), userId);
+ final PendingIntent pi = createPendingIntent(record.getKey());
mAm.cancel(pi);
- MetricsLogger.action(r.getLogMaker()
+ MetricsLogger.action(record.getLogMaker()
.setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)
.setType(MetricsProto.MetricsEvent.TYPE_DISMISS));
};
@@ -474,47 +387,38 @@ public class SnoozeHelper {
}
}
- private PendingIntent createPendingIntent(String pkg, String key, int userId) {
+ private PendingIntent createPendingIntent(String key) {
return PendingIntent.getBroadcast(mContext,
REQUEST_CODE_REPOST,
new Intent(REPOST_ACTION)
.setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
.setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
- .putExtra(EXTRA_KEY, key)
- .putExtra(EXTRA_USER_ID, userId),
+ .putExtra(EXTRA_KEY, key),
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
public void scheduleRepostsForPersistedNotifications(long currentTime) {
synchronized (mLock) {
- for (ArrayMap<String, Long> snoozed : mPersistedSnoozedNotifications.values()) {
- for (int i = 0; i < snoozed.size(); i++) {
- String key = snoozed.keyAt(i);
- Long time = snoozed.valueAt(i);
- String pkg = mPackages.get(key);
- Integer userId = mUsers.get(key);
- if (time == null || pkg == null || userId == null) {
- Slog.w(TAG, "data out of sync: " + time + "|" + pkg + "|" + userId);
- continue;
- }
- if (time != null && time > currentTime) {
- scheduleRepostAtTime(pkg, key, userId, time);
- }
+ for (int i = 0; i < mPersistedSnoozedNotifications.size(); i++) {
+ String key = mPersistedSnoozedNotifications.keyAt(i);
+ Long time = mPersistedSnoozedNotifications.valueAt(i);
+ if (time != null && time > currentTime) {
+ scheduleRepostAtTime(key, time);
}
}
}
}
- private void scheduleRepost(String pkg, String key, int userId, long duration) {
- scheduleRepostAtTime(pkg, key, userId, System.currentTimeMillis() + duration);
+ private void scheduleRepost(String key, long duration) {
+ scheduleRepostAtTime(key, System.currentTimeMillis() + duration);
}
- private void scheduleRepostAtTime(String pkg, String key, int userId, long time) {
+ private void scheduleRepostAtTime(String key, long time) {
Runnable runnable = () -> {
final long identity = Binder.clearCallingIdentity();
try {
- final PendingIntent pi = createPendingIntent(pkg, key, userId);
+ final PendingIntent pi = createPendingIntent(key);
mAm.cancel(pi);
if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + new Date(time));
mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
@@ -528,37 +432,14 @@ public class SnoozeHelper {
public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) {
synchronized (mLock) {
pw.println("\n Snoozed notifications:");
- for (String userPkgKey : mSnoozedNotifications.keySet()) {
+ for (String key : mSnoozedNotifications.keySet()) {
pw.print(INDENT);
- pw.println("key: " + userPkgKey);
- ArrayMap<String, NotificationRecord> snoozedRecords =
- mSnoozedNotifications.get(userPkgKey);
- Set<String> snoozedKeys = snoozedRecords.keySet();
- for (String key : snoozedKeys) {
- pw.print(INDENT);
- pw.print(INDENT);
- pw.print(INDENT);
- pw.println(key);
- }
+ pw.println("key: " + key);
}
pw.println("\n Pending snoozed notifications");
- for (String userPkgKey : mPersistedSnoozedNotifications.keySet()) {
+ for (String key : mPersistedSnoozedNotifications.keySet()) {
pw.print(INDENT);
- pw.println("key: " + userPkgKey);
- ArrayMap<String, Long> snoozedRecords =
- mPersistedSnoozedNotifications.get(userPkgKey);
- if (snoozedRecords == null) {
- continue;
- }
- Set<String> snoozedKeys = snoozedRecords.keySet();
- for (String key : snoozedKeys) {
- pw.print(INDENT);
- pw.print(INDENT);
- pw.print(INDENT);
- pw.print(key);
- pw.print(INDENT);
- pw.println(snoozedRecords.get(key));
- }
+ pw.println("key: " + key + " until: " + mPersistedSnoozedNotifications.get(key));
}
}
}
@@ -589,37 +470,22 @@ public class SnoozeHelper {
void insert(T t) throws IOException;
}
- private <T> void writeXml(TypedXmlSerializer out,
- ArrayMap<String, ArrayMap<String, T>> targets, String tag,
- Inserter<T> attributeInserter)
- throws IOException {
- final int M = targets.size();
- for (int i = 0; i < M; i++) {
+ private <T> void writeXml(TypedXmlSerializer out, ArrayMap<String, T> targets, String tag,
+ Inserter<T> attributeInserter) throws IOException {
+ for (int j = 0; j < targets.size(); j++) {
+ String key = targets.keyAt(j);
// T is a String (snoozed until context) or Long (snoozed until time)
- ArrayMap<String, T> keyToValue = targets.valueAt(i);
- for (int j = 0; j < keyToValue.size(); j++) {
- String key = keyToValue.keyAt(j);
- T value = keyToValue.valueAt(j);
- String pkg = mPackages.get(key);
- Integer userId = mUsers.get(key);
-
- if (pkg == null || userId == null) {
- Slog.w(TAG, "pkg " + pkg + " or user " + userId + " missing for " + key);
- continue;
- }
+ T value = targets.valueAt(j);
- out.startTag(null, tag);
+ out.startTag(null, tag);
- attributeInserter.insert(value);
+ attributeInserter.insert(value);
- out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
- XML_SNOOZED_NOTIFICATION_VERSION);
- out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
- out.attribute(null, XML_SNOOZED_NOTIFICATION_PKG, pkg);
- out.attributeInt(null, XML_SNOOZED_NOTIFICATION_USER_ID, userId);
+ out.attributeInt(null, XML_SNOOZED_NOTIFICATION_VERSION_LABEL,
+ XML_SNOOZED_NOTIFICATION_VERSION);
+ out.attribute(null, XML_SNOOZED_NOTIFICATION_KEY, key);
- out.endTag(null, tag);
- }
+ out.endTag(null, tag);
}
}
@@ -639,16 +505,12 @@ public class SnoozeHelper {
== XML_SNOOZED_NOTIFICATION_VERSION) {
try {
final String key = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_KEY);
- final String pkg = parser.getAttributeValue(null, XML_SNOOZED_NOTIFICATION_PKG);
- final int userId = parser.getAttributeInt(
- null, XML_SNOOZED_NOTIFICATION_USER_ID, UserHandle.USER_ALL);
if (tag.equals(XML_SNOOZED_NOTIFICATION)) {
final Long time = parser.getAttributeLong(
null, XML_SNOOZED_NOTIFICATION_TIME, 0);
if (time > currentTime) { //only read new stuff
synchronized (mLock) {
- storeRecordLocked(
- pkg, key, userId, mPersistedSnoozedNotifications, time);
+ mPersistedSnoozedNotifications.put(key, time);
}
}
}
@@ -656,9 +518,7 @@ public class SnoozeHelper {
final String creationId = parser.getAttributeValue(
null, XML_SNOOZED_NOTIFICATION_CONTEXT_ID);
synchronized (mLock) {
- storeRecordLocked(
- pkg, key, userId, mPersistedSnoozedNotificationsWithContext,
- creationId);
+ mPersistedSnoozedNotificationsWithContext.put(key, creationId);
}
}
} catch (Exception e) {
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 84c7c5513319..da8992ae77f8 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -88,6 +88,7 @@ final class AppDataHelper {
* <p>
* <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
*/
+ @GuardedBy("mPm.mInstallLock")
public void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
prepareAppDataPostCommitLIF(pkg, 0 /* previousAppId */);
}
@@ -97,6 +98,7 @@ final class AppDataHelper {
* {@link #prepareAppData(Installer.Batch, AndroidPackage, int, int, int)}
* @see #prepareAppDataAfterInstallLIF(AndroidPackage)
*/
+ @GuardedBy("mPm.mInstallLock")
public void prepareAppDataPostCommitLIF(AndroidPackage pkg, int previousAppId) {
final PackageSetting ps;
synchronized (mPm.mLock) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
index 56582b98e8d3..8501c5e5d236 100644
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -128,6 +128,16 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
/**
+ * A mapping from the set of App IDs that query other App IDs via custom permissions to the
+ * list of packages that they can see.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseSetArray<Integer> mQueryableViaUsesPermission;
+ @NonNull
+ protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesPermissionSnapshot;
+
+ /**
* Handler for running reasonably short background tasks such as building the initial
* visibility cache.
*/
@@ -217,6 +227,10 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
return mQueryableViaUsesLibrary.contains(callingAppId, targetAppId);
}
+ protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
+ return mQueryableViaUsesPermission.contains(callingAppId, targetAppId);
+ }
+
protected boolean isQueryableViaComponentWhenRequireRecompute(
ArrayMap<String, ? extends PackageStateInternal> existingSettings,
PackageStateInternal callingPkgSetting,
@@ -323,7 +337,8 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
return false;
} else if (Process.isSdkSandboxUid(callingAppId)) {
// we only allow sdk sandbox processes access to forcequeryable packages
- return !isForceQueryable(targetPkgSetting.getAppId());
+ return !isForceQueryable(targetPkgSetting.getAppId())
+ && !isImplicitlyQueryable(callingAppId, targetPkgSetting.getAppId());
}
if (mCacheReady) { // use cache
if (!shouldFilterApplicationUsingCache(callingUid,
@@ -627,6 +642,22 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
}
}
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesPermission");
+ }
+ if (isQueryableViaUsesPermission(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queryable for permission users");
+ }
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
return true;
} finally {
if (DEBUG_TRACING) {
@@ -762,6 +793,13 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
expandPackages);
}
+ protected void dumpQueriesViaUsesPermission(PrintWriter pw, @Nullable Integer filteringAppId,
+ ToString<Integer> expandPackages) {
+ pw.println(" queryable via uses-permission:");
+ dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesPermission, " ",
+ expandPackages);
+ }
+
private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
WatchedSparseSetArray<Integer> queriesMap, String spacing,
@Nullable ToString<Integer> toString) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index dae7a6ffae0e..5e0b47a98756 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -55,6 +55,8 @@ import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
+import com.android.server.pm.pkg.component.ParsedPermission;
+import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
import com.android.server.utils.Watchable;
@@ -68,8 +70,11 @@ import com.android.server.utils.Watcher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Implementation of the methods that update the internal structures of AppsFilter. Because of the
@@ -90,6 +95,26 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
private final WatchableImpl mWatchable = new WatchableImpl();
/**
+ * A cache that maps parsed {@link android.R.styleable#AndroidManifestPermission
+ * &lt;permission&gt;} to the packages that define them. While computing visibility based on
+ * permissions, this cache is used to save the cost of reading through every existing package
+ * to determine the App Ids that define a particular permission.
+ */
+ @GuardedBy("mQueryableViaUsesPermissionLock")
+ @NonNull
+ private HashMap<String, Set<Integer>> mPermissionToUids;
+
+ /**
+ * A cache that maps parsed {@link android.R.styleable#AndroidManifestUsesPermission
+ * &lt;uses-permission&gt;} to the packages that request them. While computing visibility based
+ * on permissions, this cache is used to save the cost of reading through every existing
+ * package to determine the App Ids that request a particular permission.
+ */
+ @GuardedBy("mQueryableViaUsesPermissionLock")
+ @NonNull
+ private HashMap<String, Set<Integer>> mUsesPermissionToUids;
+
+ /**
* Ensures an observer is in the list, exactly once. The observer cannot be null. The
* function quietly returns if the observer is already in the list.
*
@@ -179,12 +204,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>(
mQueryableViaUsesLibrary, mQueryableViaUsesLibrary,
"AppsFilter.mQueryableViaUsesLibrary");
+ mQueryableViaUsesPermission = new WatchedSparseSetArray<>();
+ mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Auto<>(
+ mQueryableViaUsesPermission, mQueryableViaUsesPermission,
+ "AppsFilter.mQueryableViaUsesPermission");
mForceQueryable = new WatchedArraySet<>();
mForceQueryableSnapshot = new SnapshotCache.Auto<>(
mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable");
mProtectedBroadcasts = new WatchedArrayList<>();
mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
+ mPermissionToUids = new HashMap<>();
+ mUsesPermissionToUids = new HashMap<>();
mSnapshot = new SnapshotCache<AppsFilterSnapshot>(this, this) {
@Override
@@ -532,6 +563,54 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
}
}
+ if (!newPkg.getUsesPermissions().isEmpty()) {
+ // newPkg requests some permissions
+ synchronized (mQueryableViaUsesPermissionLock) {
+ for (ParsedUsesPermission usesPermission : newPkg.getUsesPermissions()) {
+ String usesPermissionName = usesPermission.getName();
+ // Lookup in the mPermissionToUids cache if installed packages have
+ // defined this permission.
+ if (mPermissionToUids.containsKey(usesPermissionName)) {
+ for (int targetAppId : mPermissionToUids.get(usesPermissionName)) {
+ if (targetAppId != newPkgSetting.getAppId()) {
+ mQueryableViaUsesPermission.add(newPkgSetting.getAppId(),
+ targetAppId);
+ }
+ }
+ }
+ // Record in mUsesPermissionToUids that a permission was requested
+ // by a new package
+ if (!mUsesPermissionToUids.containsKey(usesPermissionName)) {
+ mUsesPermissionToUids.put(usesPermissionName, new HashSet<>());
+ }
+ mUsesPermissionToUids.get(usesPermissionName).add(newPkgSetting.getAppId());
+ }
+ }
+ }
+ if (!newPkg.getPermissions().isEmpty()) {
+ synchronized (mQueryableViaUsesPermissionLock) {
+ // newPkg defines some permissions
+ for (ParsedPermission permission : newPkg.getPermissions()) {
+ String permissionName = permission.getName();
+ // Lookup in the mUsesPermissionToUids cache if installed packages have
+ // requested this permission.
+ if (mUsesPermissionToUids.containsKey(permissionName)) {
+ for (int queryingAppId : mUsesPermissionToUids.get(permissionName)) {
+ if (queryingAppId != newPkgSetting.getAppId()) {
+ mQueryableViaUsesPermission.add(queryingAppId,
+ newPkgSetting.getAppId());
+ }
+ }
+ }
+ // Record in mPermissionToUids that a permission was defined by a new package
+ if (!mPermissionToUids.containsKey(permissionName)) {
+ mPermissionToUids.put(permissionName, new HashSet<>());
+ }
+ mPermissionToUids.get(permissionName).add(newPkgSetting.getAppId());
+ }
+ }
+ }
+
for (int i = existingSettings.size() - 1; i >= 0; i--) {
final PackageStateInternal existingSetting = existingSettings.valueAt(i);
if (existingSetting.getAppId() == newPkgSetting.getAppId()
@@ -960,6 +1039,32 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
}
}
+ synchronized (mQueryableViaUsesPermissionLock) {
+ if (setting.getPkg() != null && !setting.getPkg().getPermissions().isEmpty()) {
+ for (ParsedPermission permission : setting.getPkg().getPermissions()) {
+ String permissionName = permission.getName();
+ if (mPermissionToUids.containsKey(permissionName)) {
+ mPermissionToUids.get(permissionName).remove(setting.getAppId());
+ if (mPermissionToUids.get(permissionName).isEmpty()) {
+ mPermissionToUids.remove(permissionName);
+ }
+ }
+ }
+ }
+ if (setting.getPkg() != null && !setting.getPkg().getUsesPermissions().isEmpty()) {
+ for (ParsedUsesPermission usesPermission : setting.getPkg().getUsesPermissions()) {
+ String usesPermissionName = usesPermission.getName();
+ if (mUsesPermissionToUids.containsKey(usesPermissionName)) {
+ mUsesPermissionToUids.get(usesPermissionName).remove(setting.getAppId());
+ if (mUsesPermissionToUids.get(usesPermissionName).isEmpty()) {
+ mUsesPermissionToUids.remove(usesPermissionName);
+ }
+ }
+ }
+ }
+ mQueryableViaUsesPermission.remove(setting.getAppId());
+ }
+
synchronized (mForceQueryableLock) {
mForceQueryable.remove(setting.getAppId());
}
diff --git a/services/core/java/com/android/server/pm/AppsFilterLocked.java b/services/core/java/com/android/server/pm/AppsFilterLocked.java
index 30eb09e61d3f..870f9da26210 100644
--- a/services/core/java/com/android/server/pm/AppsFilterLocked.java
+++ b/services/core/java/com/android/server/pm/AppsFilterLocked.java
@@ -33,10 +33,11 @@ abstract class AppsFilterLocked extends AppsFilterBase {
protected final Object mQueriesViaComponentLock = new Object();
/**
* This lock covers both {@link #mImplicitlyQueryable} and {@link #mRetainedImplicitlyQueryable}
- */
+ */
protected final Object mImplicitlyQueryableLock = new Object();
protected final Object mQueryableViaUsesLibraryLock = new Object();
protected final Object mProtectedBroadcastsLock = new Object();
+ protected final Object mQueryableViaUsesPermissionLock = new Object();
/**
* Guards the access for {@link AppsFilterBase#mShouldFilterCache};
@@ -86,6 +87,13 @@ abstract class AppsFilterLocked extends AppsFilterBase {
}
@Override
+ protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
+ synchronized (mQueryableViaUsesPermissionLock) {
+ return super.isQueryableViaUsesPermission(callingAppId, targetAppId);
+ }
+ }
+
+ @Override
protected boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
synchronized (mCacheLock) {
return super.shouldFilterApplicationUsingCache(callingUid, appId, userId);
diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
index 6ae6efae1230..019c853471fe 100644
--- a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
@@ -44,6 +44,10 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase {
mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
}
mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
+ synchronized (orig.mQueryableViaUsesPermissionLock) {
+ mQueryableViaUsesPermission = orig.mQueryableViaUsesPermissionSnapshot.snapshot();
+ }
+ mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Sealed<>();
synchronized (orig.mForceQueryableLock) {
mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
}
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 7e16925195f5..63c25ea520f7 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -5008,6 +5008,8 @@ public class ComputerEngine implements Computer {
final int callingUid = Binder.getCallingUid();
final int userId = processName != null ? UserHandle.getUserId(uid)
: UserHandle.getCallingUserId();
+ enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+ false /* checkShell */, "queryContentProviders");
if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForComponent(flags, userId);
ArrayList<ProviderInfo> finalList = null;
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 075fb47cceac..48ec436761e9 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -271,7 +271,7 @@ final class DeletePackageHelper {
// other processes clean up before deleting resources.
synchronized (mPm.mInstallLock) {
if (info.mArgs != null) {
- info.mArgs.doPostDeleteLI(true);
+ mRemovePackageHelper.cleanUpResources(info.mArgs);
}
boolean reEnableStub = false;
@@ -341,6 +341,7 @@ final class DeletePackageHelper {
/*
* This method handles package deletion in general
*/
+ @GuardedBy("mPm.mInstallLock")
public boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
boolean deleteCodeAndResources, @NonNull int[] allUserHandles, int flags,
PackageRemovedInfo outInfo, boolean writeSettings) {
@@ -393,8 +394,18 @@ final class DeletePackageHelper {
return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
}
+ public void executeDeletePackage(DeletePackageAction action, String packageName,
+ boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings)
+ throws SystemDeleteException {
+ synchronized (mPm.mInstallLock) {
+ executeDeletePackageLIF(action, packageName, deleteCodeAndResources, allUserHandles,
+ writeSettings);
+ }
+ }
+
/** Deletes a package. Only throws when install of a disabled package fails. */
- public void executeDeletePackageLIF(DeletePackageAction action,
+ @GuardedBy("mPm.mInstallLock")
+ private void executeDeletePackageLIF(DeletePackageAction action,
String packageName, boolean deleteCodeAndResources,
@NonNull int[] allUserHandles, boolean writeSettings) throws SystemDeleteException {
final PackageSetting ps = action.mDeletingPs;
@@ -487,7 +498,9 @@ final class DeletePackageHelper {
// Take a note whether we deleted the package for all users
if (outInfo != null) {
- outInfo.mRemovedForAllUsers = mPm.mPackages.get(ps.getPackageName()) == null;
+ synchronized (mPm.mLock) {
+ outInfo.mRemovedForAllUsers = mPm.mPackages.get(ps.getPackageName()) == null;
+ }
}
}
@@ -538,6 +551,7 @@ final class DeletePackageHelper {
}
}
+ @GuardedBy("mPm.mInstallLock")
private void deleteInstalledPackageLIF(PackageSetting ps,
boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
PackageRemovedInfo outInfo, boolean writeSettings) {
@@ -556,7 +570,7 @@ final class DeletePackageHelper {
// Delete application code and resources only for parent packages
if (deleteCodeAndResources && (outInfo != null)) {
- outInfo.mArgs = new FileInstallArgs(
+ outInfo.mArgs = new InstallArgs(
ps.getPathString(), getAppDexInstructionSets(
ps.getPrimaryCpuAbi(), ps.getSecondaryCpuAbi()), mPm);
if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.mArgs);
@@ -636,7 +650,10 @@ final class DeletePackageHelper {
flags |= PackageManager.DELETE_KEEP_DATA;
}
- deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, outInfo, writeSettings);
+ synchronized (mPm.mInstallLock) {
+ deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, outInfo,
+ writeSettings);
+ }
}
public void deletePackageVersionedInternal(VersionedPackage versionedPackage,
diff --git a/services/core/java/com/android/server/pm/FileInstallArgs.java b/services/core/java/com/android/server/pm/FileInstallArgs.java
deleted file mode 100644
index 4d9e2a311ce2..000000000000
--- a/services/core/java/com/android/server/pm/FileInstallArgs.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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.pm;
-
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.content.pm.PackageManager.INSTALL_STAGED;
-import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.os.incremental.IncrementalManager.isIncrementalPath;
-
-import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
-import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
-import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.TAG;
-import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
-
-import android.content.pm.DataLoaderType;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.SigningDetails;
-import android.content.pm.parsing.ApkLiteParseUtils;
-import android.content.pm.parsing.PackageLite;
-import android.content.pm.parsing.result.ParseResult;
-import android.content.pm.parsing.result.ParseTypeImpl;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.SELinux;
-import android.os.Trace;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Slog;
-
-import com.android.internal.content.NativeLibraryHelper;
-import com.android.server.pm.parsing.pkg.ParsedPackage;
-
-import libcore.io.IoUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Logic to handle installation of new applications, including copying
- * and renaming logic.
- */
-class FileInstallArgs extends InstallArgs {
- private File mCodeFile;
-
- // Example topology:
- // /data/app/com.example/base.apk
- // /data/app/com.example/split_foo.apk
- // /data/app/com.example/lib/arm/libfoo.so
- // /data/app/com.example/lib/arm64/libfoo.so
- // /data/app/com.example/dalvik/arm/base.apk@classes.dex
-
- /** New install */
- FileInstallArgs(InstallingSession params) {
- super(params);
- }
-
- /**
- * Create args that describe an existing installed package. Typically used
- * when cleaning up old installs, or used as a move source.
- */
- FileInstallArgs(String codePath, String[] instructionSets, PackageManagerService pm) {
- super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
- null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
- SigningDetails.UNKNOWN,
- PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT,
- false, DataLoaderType.NONE,
- PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, pm);
- mCodeFile = (codePath != null) ? new File(codePath) : null;
- }
-
- int copyApk() {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
- try {
- return doCopyApk();
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- private int doCopyApk() {
- if (mOriginInfo.mStaged) {
- if (DEBUG_INSTALL) Slog.d(TAG, mOriginInfo.mFile + " already staged; skipping copy");
- mCodeFile = mOriginInfo.mFile;
- return PackageManager.INSTALL_SUCCEEDED;
- }
-
- try {
- final boolean isEphemeral = (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
- final File tempDir =
- mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
- mCodeFile = tempDir;
- } catch (IOException e) {
- Slog.w(TAG, "Failed to create copy file: " + e);
- return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- }
-
- int ret = PackageManagerServiceUtils.copyPackage(
- mOriginInfo.mFile.getAbsolutePath(), mCodeFile);
- if (ret != PackageManager.INSTALL_SUCCEEDED) {
- Slog.e(TAG, "Failed to copy package");
- return ret;
- }
-
- final boolean isIncremental = isIncrementalPath(mCodeFile.getAbsolutePath());
- final File libraryRoot = new File(mCodeFile, LIB_DIR_NAME);
- NativeLibraryHelper.Handle handle = null;
- try {
- handle = NativeLibraryHelper.Handle.create(mCodeFile);
- ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
- mAbiOverride, isIncremental);
- } catch (IOException e) {
- Slog.e(TAG, "Copying native libraries failed", e);
- ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
- } finally {
- IoUtils.closeQuietly(handle);
- }
-
- return ret;
- }
-
- int doPreInstall(int status) {
- if (status != PackageManager.INSTALL_SUCCEEDED) {
- cleanUp();
- }
- return status;
- }
-
- @Override
- boolean doRename(int status, ParsedPackage parsedPackage) {
- if (status != PackageManager.INSTALL_SUCCEEDED) {
- cleanUp();
- return false;
- }
-
- final File targetDir = resolveTargetDir();
- final File beforeCodeFile = mCodeFile;
- final File afterCodeFile = PackageManagerServiceUtils.getNextCodePath(targetDir,
- parsedPackage.getPackageName());
-
- if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
- final boolean onIncremental = mPm.mIncrementalManager != null
- && isIncrementalPath(beforeCodeFile.getAbsolutePath());
- try {
- makeDirRecursive(afterCodeFile.getParentFile(), 0775);
- if (onIncremental) {
- // Just link files here. The stage dir will be removed when the installation
- // session is completed.
- mPm.mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile);
- } else {
- Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
- }
- } catch (IOException | ErrnoException e) {
- Slog.w(TAG, "Failed to rename", e);
- return false;
- }
-
- if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
- Slog.w(TAG, "Failed to restorecon");
- return false;
- }
-
- // Reflect the rename internally
- mCodeFile = afterCodeFile;
-
- // Reflect the rename in scanned details
- try {
- parsedPackage.setPath(afterCodeFile.getCanonicalPath());
- } catch (IOException e) {
- Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
- return false;
- }
- parsedPackage.setBaseApkPath(FileUtils.rewriteAfterRename(beforeCodeFile,
- afterCodeFile, parsedPackage.getBaseApkPath()));
- parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
- afterCodeFile, parsedPackage.getSplitCodePaths()));
-
- return true;
- }
-
- // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
- // flow, we won't need this method anymore.
- private File resolveTargetDir() {
- boolean isStagedInstall = (mInstallFlags & INSTALL_STAGED) != 0;
- if (isStagedInstall) {
- return Environment.getDataAppDirectory(null);
- } else {
- return mCodeFile.getParentFile();
- }
- }
-
- int doPostInstall(int status, int uid) {
- if (status != PackageManager.INSTALL_SUCCEEDED) {
- cleanUp();
- }
- return status;
- }
-
- @Override
- String getCodePath() {
- return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
- }
-
- private boolean cleanUp() {
- if (mCodeFile == null || !mCodeFile.exists()) {
- return false;
- }
- mRemovePackageHelper.removeCodePathLI(mCodeFile);
- return true;
- }
-
- void cleanUpResourcesLI() {
- // Try enumerating all code paths before deleting
- List<String> allCodePaths = Collections.EMPTY_LIST;
- if (mCodeFile != null && mCodeFile.exists()) {
- final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
- final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
- input.reset(), mCodeFile, /* flags */ 0);
- if (result.isSuccess()) {
- // Ignore error; we tried our best
- allCodePaths = result.getResult().getAllApkPaths();
- }
- }
-
- cleanUp();
- removeDexFiles(allCodePaths, mInstructionSets);
- }
-
- void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
- if (!allCodePaths.isEmpty()) {
- if (instructionSets == null) {
- throw new IllegalStateException("instructionSet == null");
- }
- String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
- for (String codePath : allCodePaths) {
- for (String dexCodeInstructionSet : dexCodeInstructionSets) {
- try {
- mPm.mInstaller.rmdex(codePath, dexCodeInstructionSet);
- } catch (Installer.InstallerException ignored) {
- }
- }
- }
- }
- }
-
- boolean doPostDeleteLI(boolean delete) {
- // XXX err, shouldn't we respect the delete flag?
- cleanUpResourcesLI();
- return true;
- }
-}
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index f4285eb0d9d9..c70e6ad6e09d 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -387,14 +387,6 @@ public abstract class IPackageManagerBase extends IPackageManager.Stub {
return snapshot().getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
}
- @Override
- @Deprecated
- public final String getContentCaptureServicePackageName() {
- return mService.ensureSystemPackageName(snapshot(),
- mService.getPackageFromComponentString(
- R.string.config_defaultContentCaptureService));
- }
-
@Nullable
@Override
@Deprecated
diff --git a/services/core/java/com/android/server/pm/InstallArgs.java b/services/core/java/com/android/server/pm/InstallArgs.java
index fa8a9756c179..616bb8f419dd 100644
--- a/services/core/java/com/android/server/pm/InstallArgs.java
+++ b/services/core/java/com/android/server/pm/InstallArgs.java
@@ -16,19 +16,24 @@
package com.android.server.pm;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.DataLoaderType;
import android.content.pm.IPackageInstallObserver2;
+import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.SigningDetails;
import android.os.UserHandle;
import com.android.internal.util.Preconditions;
-import com.android.server.pm.parsing.pkg.ParsedPackage;
+import java.io.File;
import java.util.List;
-abstract class InstallArgs {
+final class InstallArgs {
+ File mCodeFile;
/** @see InstallingSession#mOriginInfo */
final OriginInfo mOriginInfo;
/** @see InstallingSession#mMoveInfo */
@@ -108,28 +113,21 @@ abstract class InstallArgs {
params.mDataLoaderType, params.mPackageSource, params.mPm);
}
- abstract int copyApk();
- abstract int doPreInstall(int status);
-
/**
- * Rename package into final resting place. All paths on the given
- * scanned package should be updated to reflect the rename.
+ * Create args that describe an existing installed package. Typically used
+ * when cleaning up old installs, or used as a move source.
*/
- abstract boolean doRename(int status, ParsedPackage parsedPackage);
- abstract int doPostInstall(int status, int uid);
-
- /** @see PackageSettingBase#getPath() */
- abstract String getCodePath();
-
- // Need installer lock especially for dex file removal.
- abstract void cleanUpResourcesLI();
- abstract boolean doPostDeleteLI(boolean delete);
-
- protected boolean isEphemeral() {
- return (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+ InstallArgs(String codePath, String[] instructionSets, PackageManagerService pm) {
+ this(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
+ null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
+ SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN,
+ PackageManager.INSTALL_SCENARIO_DEFAULT, false, DataLoaderType.NONE,
+ PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, pm);
+ mCodeFile = (codePath != null) ? new File(codePath) : null;
}
- UserHandle getUser() {
- return mUser;
+ /** @see PackageSettingBase#getPath() */
+ String getCodePath() {
+ return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
}
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 89bb17f37382..8bb9b841e1a2 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -34,6 +34,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
+import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
@@ -89,6 +90,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
+import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
import android.annotation.NonNull;
@@ -123,9 +125,11 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.SELinux;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
@@ -135,6 +139,8 @@ import android.os.incremental.IncrementalStorage;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.stats.storage.StorageEnums;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
@@ -236,7 +242,7 @@ final class InstallPackageHelper {
* This needs to be fixed so, once we get to this point, no errors are
* possible and the system is not left in an inconsistent state.
*/
- @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+ @GuardedBy("mPm.mLock")
public AndroidPackage commitReconciledScanResultLocked(
@NonNull ReconciledPackage reconciledPkg, int[] allUsers) {
final ScanResult result = reconciledPkg.mScanResult;
@@ -347,7 +353,7 @@ final class InstallPackageHelper {
|| (oldPkgSetting != null && oldPkgSetting.getUsesLibraryInfos() != null)) {
// Reconcile if the new package or the old package uses shared libraries.
// It is possible that the old package uses shared libraries but the new one doesn't.
- mSharedLibraries.executeSharedLibrariesUpdateLPw(pkg, pkgSetting, null, null,
+ mSharedLibraries.executeSharedLibrariesUpdate(pkg, pkgSetting, null, null,
reconciledPkg.mCollectedSharedLibraryInfos, allUsers);
}
@@ -365,8 +371,10 @@ final class InstallPackageHelper {
for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
final String codePathString = changedAbiCodePath.get(i);
try {
- mPm.mInstaller.rmdex(codePathString,
- getDexCodeInstructionSet(getPreferredInstructionSet()));
+ synchronized (mPm.mInstallLock) {
+ mPm.mInstaller.rmdex(codePathString,
+ getDexCodeInstructionSet(getPreferredInstructionSet()));
+ }
} catch (Installer.InstallerException ignored) {
}
}
@@ -405,30 +413,12 @@ final class InstallPackageHelper {
mPm.setPlatformPackage(pkg, pkgSetting);
}
- ArrayList<AndroidPackage> clientLibPkgs = null;
// writer
- synchronized (mPm.mLock) {
- if (!ArrayUtils.isEmpty(reconciledPkg.mAllowedSharedLibraryInfos)) {
- for (SharedLibraryInfo info : reconciledPkg.mAllowedSharedLibraryInfos) {
- mSharedLibraries.commitSharedLibraryInfoLPw(info);
- }
- final Map<String, AndroidPackage> combinedSigningDetails =
- reconciledPkg.getCombinedAvailablePackages();
- try {
- // Shared libraries for the package need to be updated.
- mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null,
- combinedSigningDetails);
- } catch (PackageManagerException e) {
- Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
- }
- // Update all applications that use this library. Skip when booting
- // since this will be done after all packages are scaned.
- if ((scanFlags & SCAN_BOOTING) == 0) {
- clientLibPkgs = mSharedLibraries.updateAllSharedLibrariesLPw(pkg, pkgSetting,
- combinedSigningDetails);
- }
- }
- }
+ ArrayList<AndroidPackage> clientLibPkgs =
+ mSharedLibraries.commitSharedLibraryChanges(pkg, pkgSetting,
+ reconciledPkg.mAllowedSharedLibraryInfos,
+ reconciledPkg.getCombinedAvailablePackages(), scanFlags);
+
if (reconciledPkg.mInstallResult != null) {
reconciledPkg.mInstallResult.mLibraryConsumers = clientLibPkgs;
}
@@ -795,126 +785,14 @@ final class InstallPackageHelper {
return false;
}
- public void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
- List<InstallRequest> apexInstallRequests = new ArrayList<>();
- List<InstallRequest> apkInstallRequests = new ArrayList<>();
- for (InstallRequest request : installRequests) {
- if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
- apexInstallRequests.add(request);
- } else {
- apkInstallRequests.add(request);
- }
- }
- // Note: supporting multi package install of both APEXes and APKs might requir some
- // thinking to ensure atomicity of the install.
- if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
- // This should've been caught at the validation step, but for some reason wasn't.
- throw new IllegalStateException(
- "Attempted to do a multi package install of both APEXes and APKs");
- }
- if (!apexInstallRequests.isEmpty()) {
- if (success) {
- // Since installApexPackages requires talking to external service (apexd), we
- // schedule to run it async. Once it finishes, it will resume the install.
- Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
- "installApexPackages");
- t.start();
- } else {
- // Non-staged APEX installation failed somewhere before
- // processInstallRequestAsync. In that case just notify the observer about the
- // failure.
- InstallRequest request = apexInstallRequests.get(0);
- mPm.notifyInstallObserver(request.mInstallResult,
- request.mArgs.mObserver);
- }
- return;
- }
-
- processApkInstallRequests(success, installRequests);
- }
-
- private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
- if (success) {
- for (InstallRequest request : installRequests) {
- request.mArgs.doPreInstall(request.mInstallResult.mReturnCode);
- }
- synchronized (mPm.mInstallLock) {
- installPackagesTracedLI(installRequests);
- }
- for (InstallRequest request : installRequests) {
- request.mArgs.doPostInstall(
- request.mInstallResult.mReturnCode, request.mInstallResult.mUid);
- }
- }
- for (InstallRequest request : installRequests) {
- restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
- request.mInstallResult,
- new PostInstallData(request.mArgs,
- request.mInstallResult, null));
- }
- }
-
- private void installApexPackagesTraced(List<InstallRequest> requests) {
- try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
- installApexPackages(requests);
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- private void installApexPackages(List<InstallRequest> requests) {
- if (requests.isEmpty()) {
- return;
- }
- if (requests.size() != 1) {
- throw new IllegalStateException(
- "Only a non-staged install of a single APEX is supported");
- }
- InstallRequest request = requests.get(0);
- try {
- // Should directory scanning logic be moved to ApexManager for better test coverage?
- final File dir = request.mArgs.mOriginInfo.mResolvedFile;
- final File[] apexes = dir.listFiles();
- if (apexes == null) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- dir.getAbsolutePath() + " is not a directory");
- }
- if (apexes.length != 1) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Expected exactly one .apex file under " + dir.getAbsolutePath()
- + " got: " + apexes.length);
- }
- try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
- ApexInfo apexInfo = mApexManager.installPackage(apexes[0]);
- if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
- // APEX has been handled successfully by apexd. Let's continue the install flow
- // so it will be scanned and registered with the system.
- // TODO(b/225756739): Improve atomicity of rebootless APEX install.
- // The newly installed APEX will not be reverted even if
- // processApkInstallRequests() fails. Need a way to keep info stored in apexd
- // and PMS in sync in the face of install failures.
- request.mInstallResult.mApexInfo = apexInfo;
- mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
- return;
- } else {
- mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser);
- }
+ void installPackagesTraced(List<InstallRequest> requests) {
+ synchronized (mPm.mInstallLock) {
+ try {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
+ installPackagesLI(requests);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- } catch (PackageManagerException e) {
- request.mInstallResult.setError("APEX installation failed", e);
- }
- PackageManagerService.invalidatePackageInfoCache();
- mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
- }
-
- @GuardedBy("mPm.mInstallLock")
- private void installPackagesTracedLI(List<InstallRequest> requests) {
- try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
- installPackagesLI(requests);
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
@@ -1010,11 +888,12 @@ final class InstallPackageHelper {
return;
}
}
- ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
- installResults, prepareResults,
- Collections.unmodifiableMap(mPm.mPackages), versionInfos);
- CommitRequest commitRequest = null;
+
+ CommitRequest commitRequest;
synchronized (mPm.mLock) {
+ ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
+ installResults, prepareResults,
+ Collections.unmodifiableMap(mPm.mPackages), versionInfos);
Map<String, ReconciledPackage> reconciledPackages;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
@@ -1039,7 +918,7 @@ final class InstallPackageHelper {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
- executePostCommitSteps(commitRequest);
+ executePostCommitStepsLIF(commitRequest);
} finally {
if (success) {
for (InstallRequest request : requests) {
@@ -1061,7 +940,7 @@ final class InstallPackageHelper {
.buildVerificationRootHashString(baseCodePath, splitCodePaths);
VerificationUtils.broadcastPackageVerified(verificationId, originUri,
PackageManager.VERIFICATION_ALLOW, rootHashString,
- args.mDataLoaderType, args.getUser(), mContext);
+ args.mDataLoaderType, args.mUser, mContext);
}
} else {
for (ScanResult result : preparedScans.values()) {
@@ -1288,7 +1167,7 @@ final class InstallPackageHelper {
// the package setting for the latest library version.
if (parsedPackage.isStaticSharedLibrary()) {
SharedLibraryInfo libraryInfo =
- mSharedLibraries.getLatestStaticSharedLibraVersionLPr(parsedPackage);
+ mSharedLibraries.getLatestStaticSharedLibraVersion(parsedPackage);
if (libraryInfo != null) {
signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName());
}
@@ -1541,7 +1420,7 @@ final class InstallPackageHelper {
}
if (!isApex) {
- if (!args.doRename(res.mReturnCode, parsedPackage)) {
+ if (!doRenameLI(args, res.mReturnCode, parsedPackage)) {
throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
}
@@ -1805,6 +1684,82 @@ final class InstallPackageHelper {
}
}
+ /**
+ * Rename package into final resting place. All paths on the given
+ * scanned package should be updated to reflect the rename.
+ */
+ @GuardedBy("mPm.mInstallLock")
+ private boolean doRenameLI(InstallArgs args, int status, ParsedPackage parsedPackage) {
+ if (args.mMoveInfo != null) {
+ if (status != PackageManager.INSTALL_SUCCEEDED) {
+ mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
+ args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
+ return false;
+ }
+ return true;
+ }
+ // For file installations
+ if (status != PackageManager.INSTALL_SUCCEEDED) {
+ mRemovePackageHelper.removeCodePath(args.mCodeFile);
+ return false;
+ }
+
+ final File targetDir = resolveTargetDir(args);
+ final File beforeCodeFile = args.mCodeFile;
+ final File afterCodeFile = PackageManagerServiceUtils.getNextCodePath(targetDir,
+ parsedPackage.getPackageName());
+
+ if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
+ final boolean onIncremental = mPm.mIncrementalManager != null
+ && isIncrementalPath(beforeCodeFile.getAbsolutePath());
+ try {
+ makeDirRecursive(afterCodeFile.getParentFile(), 0775);
+ if (onIncremental) {
+ // Just link files here. The stage dir will be removed when the installation
+ // session is completed.
+ mPm.mIncrementalManager.linkCodePath(beforeCodeFile, afterCodeFile);
+ } else {
+ Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
+ }
+ } catch (IOException | ErrnoException e) {
+ Slog.w(TAG, "Failed to rename", e);
+ return false;
+ }
+
+ if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
+ Slog.w(TAG, "Failed to restorecon");
+ return false;
+ }
+
+ // Reflect the rename internally
+ args.mCodeFile = afterCodeFile;
+
+ // Reflect the rename in scanned details
+ try {
+ parsedPackage.setPath(afterCodeFile.getCanonicalPath());
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
+ return false;
+ }
+ parsedPackage.setBaseApkPath(FileUtils.rewriteAfterRename(beforeCodeFile,
+ afterCodeFile, parsedPackage.getBaseApkPath()));
+ parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
+ afterCodeFile, parsedPackage.getSplitCodePaths()));
+
+ return true;
+ }
+
+ // TODO(b/168126411): Once staged install flow starts using the same folder as non-staged
+ // flow, we won't need this method anymore.
+ private File resolveTargetDir(InstallArgs args) {
+ boolean isStagedInstall = (args.mInstallFlags & INSTALL_STAGED) != 0;
+ if (isStagedInstall) {
+ return Environment.getDataAppDirectory(null);
+ } else {
+ return args.mCodeFile.getParentFile();
+ }
+ }
+
/*
* Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges
* as this only works for packages that are installed
@@ -1902,7 +1857,6 @@ final class InstallPackageHelper {
}
}
- final String packageName = pkg.getPackageName();
for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
final String filePath = entry.getKey();
final String signaturePath = entry.getValue();
@@ -1973,12 +1927,12 @@ final class InstallPackageHelper {
mPm.mSettings.getPackagesLocked());
if (reconciledPkg.mPrepareResult.mSystem) {
// Remove existing system package
- removePackageHelper.removePackageLI(oldPackage, true);
+ removePackageHelper.removePackage(oldPackage, true);
if (!disableSystemPackageLPw(oldPackage)) {
// We didn't need to disable the .apk as a current system package,
// which means we are replacing another update that is already
// installed. We need to make sure to delete the older one's .apk.
- res.mRemovedInfo.mArgs = new FileInstallArgs(
+ res.mRemovedInfo.mArgs = new InstallArgs(
oldPackage.getPath(),
getAppDexInstructionSets(
AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
@@ -1991,7 +1945,7 @@ final class InstallPackageHelper {
} else {
try {
// Settings will be written during the call to updateSettingsLI().
- deletePackageHelper.executeDeletePackageLIF(
+ deletePackageHelper.executeDeletePackage(
reconciledPkg.mDeletePackageAction, packageName,
true, request.mAllUsers, false);
} catch (SystemDeleteException e) {
@@ -2261,7 +2215,8 @@ final class InstallPackageHelper {
* is released. These are typically more expensive or require calls to installd, which often
* locks on {@link com.android.server.pm.PackageManagerService.mLock}.
*/
- private void executePostCommitSteps(CommitRequest commitRequest) {
+ @GuardedBy("mPm.mInstallLock")
+ private void executePostCommitStepsLIF(CommitRequest commitRequest) {
final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) {
final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags
@@ -2652,9 +2607,7 @@ final class InstallPackageHelper {
// Remove the update failed package's older resources safely now
InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null;
if (args != null) {
- synchronized (mPm.mInstallLock) {
- args.doPostDeleteLI(true);
- }
+ mRemovePackageHelper.cleanUpResources(args);
}
mPm.notifyInstallObserver(res, installObserver);
return;
@@ -2892,9 +2845,7 @@ final class InstallPackageHelper {
// ApplicationInfo changes have propagated to all application threads.
mPm.scheduleDeferredNoKillPostDelete(args);
} else {
- synchronized (mPm.mInstallLock) {
- args.doPostDeleteLI(true);
- }
+ mRemovePackageHelper.cleanUpResources(args);
}
} else {
// Force a gc to clear up things. Ask for a background one, it's fine to go on
@@ -3028,7 +2979,7 @@ final class InstallPackageHelper {
mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
synchronized (mPm.mLock) {
try {
- mSharedLibraries.updateSharedLibrariesLPw(
+ mSharedLibraries.updateSharedLibraries(
pkg, stubPkgSetting, null, null,
Collections.unmodifiableMap(mPm.mPackages));
} catch (PackageManagerException e) {
@@ -3100,14 +3051,14 @@ final class InstallPackageHelper {
mPm.mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
}
final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
- removePackageHelper.removePackageLI(stubPkg, true /*chatty*/);
+ removePackageHelper.removePackage(stubPkg, true /*chatty*/);
try {
return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
e);
// Remove the failed install
- removePackageHelper.removeCodePathLI(scanFile);
+ removePackageHelper.removeCodePath(scanFile);
throw e;
}
}
@@ -3150,7 +3101,7 @@ final class InstallPackageHelper {
if (!dstCodePath.exists()) {
return null;
}
- new RemovePackageHelper(mPm).removeCodePathLI(dstCodePath);
+ new RemovePackageHelper(mPm).removeCodePath(dstCodePath);
return null;
}
@@ -3236,16 +3187,16 @@ final class InstallPackageHelper {
final AndroidPackage pkg = scanSystemPackageTracedLI(
codePath, parseFlags, scanFlags, null);
- PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
-
- try {
- // update shared libraries for the newly re-installed system package
- mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null,
- Collections.unmodifiableMap(mPm.mPackages));
- } catch (PackageManagerException e) {
- Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+ synchronized (mPm.mLock) {
+ PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
+ try {
+ // update shared libraries for the newly re-installed system package
+ mSharedLibraries.updateSharedLibraries(pkg, pkgSetting, null, null,
+ Collections.unmodifiableMap(mPm.mPackages));
+ } catch (PackageManagerException e) {
+ Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+ }
}
-
mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings);
@@ -3348,7 +3299,7 @@ final class InstallPackageHelper {
+ ", versionCode=" + ps.getVersionCode()
+ "; scanned versionCode="
+ scannedPkg.getLongVersionCode());
- mRemovePackageHelper.removePackageLI(scannedPkg, true);
+ mRemovePackageHelper.removePackage(scannedPkg, true);
expectingBetter.put(ps.getPackageName(), ps.getPath());
}
@@ -3358,7 +3309,7 @@ final class InstallPackageHelper {
if (disabledPs == null) {
logCriticalInfo(Log.WARN, "System package " + packageName
+ " no longer exists; its data will be wiped");
- mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
+ mRemovePackageHelper.removePackageData(ps, userIds, null, 0, false);
} else {
// we still have a disabled system package, but, it still might have
// been removed. check the code path still exists and check there's
@@ -3409,10 +3360,12 @@ final class InstallPackageHelper {
// remove the package from the system and re-scan it without any
// special privileges
- mRemovePackageHelper.removePackageLI(pkg, true);
+ mRemovePackageHelper.removePackage(pkg, true);
try {
final File codePath = new File(pkg.getPath());
- scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
+ synchronized (mPm.mInstallLock) {
+ scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
+ }
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
+ e.getMessage());
@@ -3425,7 +3378,7 @@ final class InstallPackageHelper {
// partition], completely remove the package data.
final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
if (ps != null && mPm.mPackages.get(packageName) == null) {
- mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
+ mRemovePackageHelper.removePackageData(ps, userIds, null, 0, false);
}
logCriticalInfo(Log.WARN, msg);
}
@@ -3586,7 +3539,7 @@ final class InstallPackageHelper {
&& errorCode != PackageManager.INSTALL_SUCCEEDED) {
logCriticalInfo(Log.WARN,
"Deleting invalid package at " + parseResult.scanFile);
- mRemovePackageHelper.removeCodePathLI(parseResult.scanFile);
+ mRemovePackageHelper.removeCodePath(parseResult.scanFile);
}
}
}
@@ -3622,11 +3575,13 @@ final class InstallPackageHelper {
mPm.mSettings.enableSystemPackageLPw(packageName);
try {
- final AndroidPackage newPkg = scanSystemPackageTracedLI(
- scanFile, reparseFlags, rescanFlags, null);
- // We rescanned a stub, add it to the list of stubbed system packages
- if (newPkg.isStub()) {
- stubSystemApps.add(packageName);
+ synchronized (mPm.mInstallLock) {
+ final AndroidPackage newPkg = scanSystemPackageTracedLI(
+ scanFile, reparseFlags, rescanFlags, null);
+ // We rescanned a stub, add it to the list of stubbed system packages
+ if (newPkg.isStub()) {
+ stubSystemApps.add(packageName);
+ }
}
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
@@ -3639,7 +3594,7 @@ final class InstallPackageHelper {
* Traces a package scan.
* @see #scanSystemPackageLI(File, int, int, UserHandle)
*/
- @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+ @GuardedBy("mPm.mInstallLock")
public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags,
int scanFlags, UserHandle user) throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
@@ -3654,7 +3609,7 @@ final class InstallPackageHelper {
* Scans a package and returns the newly parsed package.
* Returns {@code null} in case of errors and the error code is stored in mLastScanError
*/
- @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+ @GuardedBy("mPm.mInstallLock")
private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags,
UserHandle user) throws PackageManagerException {
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
@@ -3688,7 +3643,7 @@ final class InstallPackageHelper {
* structures and the package is made available to the rest of the system.
* <p>NOTE: The return value should be removed. It's the passed in package object.
*/
- @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+ @GuardedBy("mPm.mInstallLock")
private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
@ParsingPackageUtils.ParseFlags int parseFlags,
@PackageManagerService.ScanFlags int scanFlags,
@@ -3770,11 +3725,13 @@ final class InstallPackageHelper {
// iff we've acquired an app ID for a new package setting, remove it so that it can be
// acquired by another request.
if (result.mPkgSetting.getAppId() > 0) {
- mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId());
+ synchronized (mPm.mLock) {
+ mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId());
+ }
}
}
- @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+ @GuardedBy("mPm.mInstallLock")
private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
final @ParsingPackageUtils.ParseFlags int parseFlags,
@PackageManagerService.ScanFlags int scanFlags, long currentTime,
@@ -3819,8 +3776,9 @@ final class InstallPackageHelper {
parsedPackage.getPackageName());
boolean ignoreSharedUserId = false;
- if (installedPkgSetting == null) {
- // We can directly ignore sharedUserSetting for new installs
+ if (installedPkgSetting == null || !installedPkgSetting.hasSharedUser()) {
+ // Directly ignore sharedUserSetting for new installs, or if the app has
+ // already left shared UID
ignoreSharedUserId = parsedPackage.isLeavingSharedUid();
}
@@ -3855,7 +3813,7 @@ final class InstallPackageHelper {
realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride);
}
- @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
+ @GuardedBy("mPm.mInstallLock")
private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
final @ParsingPackageUtils.ParseFlags int parseFlags,
@PackageManagerService.ScanFlags int scanFlags, long currentTime,
@@ -3892,6 +3850,7 @@ final class InstallPackageHelper {
}
}
+ @GuardedBy("mPm.mInstallLock")
private Pair<ScanResult, Boolean> scanSystemPackageLI(ParsedPackage parsedPackage,
@ParsingPackageUtils.ParseFlags int parseFlags,
@PackageManagerService.ScanFlags int scanFlags,
@@ -3974,10 +3933,10 @@ final class InstallPackageHelper {
+ "; " + pkgSetting.getPathString()
+ " --> " + parsedPackage.getPath());
- final InstallArgs args = new FileInstallArgs(
+ final InstallArgs args = new InstallArgs(
pkgSetting.getPathString(), getAppDexInstructionSets(
pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()), mPm);
- args.cleanUpResourcesLI();
+ mRemovePackageHelper.cleanUpResources(args);
synchronized (mPm.mLock) {
mPm.mSettings.enableSystemPackageLPw(pkgSetting.getPackageName());
}
@@ -4059,13 +4018,11 @@ final class InstallPackageHelper {
+ parsedPackage.getLongVersionCode()
+ "; " + pkgSetting.getPathString() + " --> "
+ parsedPackage.getPath());
- InstallArgs args = new FileInstallArgs(
+ InstallArgs args = new InstallArgs(
pkgSetting.getPathString(), getAppDexInstructionSets(
pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()),
mPm);
- synchronized (mPm.mInstallLock) {
- args.cleanUpResourcesLI();
- }
+ mRemovePackageHelper.cleanUpResources(args);
} else {
// The application on /system is older than the application on /data. Hide
// the application on /system and the version on /data will be scanned later
@@ -4090,7 +4047,6 @@ final class InstallPackageHelper {
* Returns if forced apk verification can be skipped for the whole package, including splits.
*/
private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
- final String packageName = pkg.getPackageName();
if (!VerityUtils.hasFsverity(pkg.getBaseApkPath())) {
return false;
}
@@ -4397,8 +4353,10 @@ final class InstallPackageHelper {
// signed with the platform certificate. Check this in increasing order of
// computational cost.
if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
- final PackageSetting platformPkgSetting =
- mPm.mSettings.getPackageLPr("android");
+ final PackageSetting platformPkgSetting;
+ synchronized (mPm.mLock) {
+ platformPkgSetting = mPm.mSettings.getPackageLPr("android");
+ }
if (!comparePackageSignatures(platformPkgSetting,
pkg.getSigningDetails().getSignatures())) {
throw new PackageManagerException("Overlay "
@@ -4416,8 +4374,10 @@ final class InstallPackageHelper {
// SystemConfig is set, check this here to augment the last line of defense
// which is OMS.
if (pkg.getOverlayTargetOverlayableName() == null) {
- final PackageSetting targetPkgSetting =
- mPm.mSettings.getPackageLPr(pkg.getOverlayTarget());
+ final PackageSetting targetPkgSetting;
+ synchronized (mPm.mLock) {
+ targetPkgSetting = mPm.mSettings.getPackageLPr(pkg.getOverlayTarget());
+ }
if (targetPkgSetting != null) {
if (!comparePackageSignatures(targetPkgSetting,
pkg.getSigningDetails().getSignatures())) {
@@ -4429,9 +4389,11 @@ final class InstallPackageHelper {
+ " different certificates, and the overlay lacks"
+ " <overlay android:targetName>");
}
- final PackageSetting refPkgSetting =
- mPm.mSettings.getPackageLPr(
- mPm.mOverlayConfigSignaturePackage);
+ final PackageSetting refPkgSetting;
+ synchronized (mPm.mLock) {
+ refPkgSetting = mPm.mSettings.getPackageLPr(
+ mPm.mOverlayConfigSignaturePackage);
+ }
if (!comparePackageSignatures(refPkgSetting,
pkg.getSigningDetails().getSignatures())) {
throw new PackageManagerException("Overlay "
@@ -4451,13 +4413,18 @@ final class InstallPackageHelper {
if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
SharedUserSetting sharedUserSetting = null;
try {
- sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(),
- 0, 0, false);
+ synchronized (mPm.mLock) {
+ sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(),
+ 0, 0, false);
+ }
} catch (PackageManagerException ignore) {
}
if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
// Exempt SharedUsers signed with the platform key.
- PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android");
+ final PackageSetting platformPkgSetting;
+ synchronized (mPm.mLock) {
+ platformPkgSetting = mPm.mSettings.getPackageLPr("android");
+ }
if (!comparePackageSignatures(platformPkgSetting,
pkg.getSigningDetails().getSignatures())) {
throw new PackageManagerException("Apps that share a user with a "
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index b3e039e5374b..0630ccdbf6e3 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -17,17 +17,21 @@
package com.android.server.pm;
import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.os.incremental.IncrementalManager.isIncrementalPath;
+import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTANT;
import static com.android.server.pm.PackageManagerService.TAG;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.apex.ApexInfo;
import android.content.pm.DataLoaderType;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInfoLite;
@@ -35,19 +39,28 @@ import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.SigningDetails;
import android.content.pm.parsing.PackageLite;
+import android.os.Environment;
import android.os.Trace;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.Pair;
import android.util.Slog;
import com.android.internal.content.F2fsUtils;
import com.android.internal.content.InstallLocationUtils;
+import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.util.Preconditions;
+import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackage;
+import libcore.io.IoUtils;
+
import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
class InstallingSession {
final OriginInfo mOriginInfo;
@@ -79,6 +92,7 @@ class InstallingSession {
@NonNull
final PackageManagerService mPm;
final InstallPackageHelper mInstallPackageHelper;
+ final RemovePackageHelper mRemovePackageHelper;
InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer,
int installFlags, InstallSource installSource, String volumeUuid,
@@ -87,6 +101,7 @@ class InstallingSession {
mPm = pm;
mUser = user;
mInstallPackageHelper = new InstallPackageHelper(mPm);
+ mRemovePackageHelper = new RemovePackageHelper(mPm);
mOriginInfo = originInfo;
mMoveInfo = moveInfo;
mObserver = observer;
@@ -115,6 +130,7 @@ class InstallingSession {
mPm = pm;
mUser = user;
mInstallPackageHelper = new InstallPackageHelper(mPm);
+ mRemovePackageHelper = new RemovePackageHelper(mPm);
mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
mMoveInfo = null;
mInstallReason = fixUpInstallReason(
@@ -195,7 +211,7 @@ class InstallingSession {
* policy if needed and then create install arguments based
* on the install location.
*/
- public void handleStartCopy() {
+ private void handleStartCopy() {
if ((mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
mRet = INSTALL_SUCCEEDED;
return;
@@ -232,14 +248,14 @@ class InstallingSession {
pkgLite.installLocation);
}
- void handleReturnCode() {
+ private void handleReturnCode() {
processPendingInstall();
}
private void processPendingInstall() {
- InstallArgs args = createInstallArgs(this);
+ InstallArgs args = new InstallArgs(this);
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
- mRet = args.copyApk();
+ mRet = copyApk(args);
}
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
F2fsUtils.releaseCompressedBlocks(
@@ -250,18 +266,89 @@ class InstallingSession {
} else {
PackageInstalledInfo res = new PackageInstalledInfo(mRet);
// Queue up an async operation since the package installation may take a little while.
- mPm.mHandler.post(() -> mInstallPackageHelper.processInstallRequests(
+ mPm.mHandler.post(() -> processInstallRequests(
res.mReturnCode == PackageManager.INSTALL_SUCCEEDED /* success */,
Collections.singletonList(new InstallRequest(args, res))));
}
}
- private InstallArgs createInstallArgs(InstallingSession installingSession) {
- if (installingSession.mMoveInfo != null) {
- return new MoveInstallArgs(installingSession);
+ private int copyApk(InstallArgs args) {
+ if (mMoveInfo == null) {
+ return copyApkForFileInstall(args);
} else {
- return new FileInstallArgs(installingSession);
+ return copyApkForMoveInstall(args);
+ }
+ }
+
+ private int copyApkForFileInstall(InstallArgs args) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
+ try {
+ if (mOriginInfo.mStaged) {
+ if (DEBUG_INSTALL) {
+ Slog.d(TAG, mOriginInfo.mFile + " already staged; skipping copy");
+ }
+ args.mCodeFile = mOriginInfo.mFile;
+ return PackageManager.INSTALL_SUCCEEDED;
+ }
+
+ try {
+ final boolean isEphemeral =
+ (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+ args.mCodeFile =
+ mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral);
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to create copy file: " + e);
+ return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ }
+
+ int ret = PackageManagerServiceUtils.copyPackage(
+ mOriginInfo.mFile.getAbsolutePath(), args.mCodeFile);
+ if (ret != PackageManager.INSTALL_SUCCEEDED) {
+ Slog.e(TAG, "Failed to copy package");
+ return ret;
+ }
+
+ final boolean isIncremental = isIncrementalPath(args.mCodeFile.getAbsolutePath());
+ final File libraryRoot = new File(args.mCodeFile, LIB_DIR_NAME);
+ NativeLibraryHelper.Handle handle = null;
+ try {
+ handle = NativeLibraryHelper.Handle.create(args.mCodeFile);
+ ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
+ args.mAbiOverride, isIncremental);
+ } catch (IOException e) {
+ Slog.e(TAG, "Copying native libraries failed", e);
+ ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ } finally {
+ IoUtils.closeQuietly(handle);
+ }
+
+ return ret;
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ private int copyApkForMoveInstall(InstallArgs args) {
+ if (DEBUG_INSTALL) {
+ Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
+ + mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
}
+ synchronized (mPm.mInstallLock) {
+ try {
+ mPm.mInstaller.moveCompleteApp(mMoveInfo.mFromUuid, mMoveInfo.mToUuid,
+ mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
+ mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
+ } catch (Installer.InstallerException e) {
+ Slog.w(TAG, "Failed to move app", e);
+ return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ }
+ }
+
+ final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
+ args.mCodeFile = new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName);
+ if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + args.mCodeFile);
+
+ return PackageManager.INSTALL_SUCCEEDED;
}
/**
@@ -368,4 +455,217 @@ class InstallingSession {
private void setTraceCookie(int traceCookie) {
mTraceCookie = traceCookie;
}
+
+ private void processInstallRequests(boolean success, List<InstallRequest> installRequests) {
+ List<InstallRequest> apexInstallRequests = new ArrayList<>();
+ List<InstallRequest> apkInstallRequests = new ArrayList<>();
+ for (InstallRequest request : installRequests) {
+ if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
+ apexInstallRequests.add(request);
+ } else {
+ apkInstallRequests.add(request);
+ }
+ }
+ // Note: supporting multi package install of both APEXes and APKs might requir some
+ // thinking to ensure atomicity of the install.
+ if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) {
+ // This should've been caught at the validation step, but for some reason wasn't.
+ throw new IllegalStateException(
+ "Attempted to do a multi package install of both APEXes and APKs");
+ }
+ if (!apexInstallRequests.isEmpty()) {
+ if (success) {
+ // Since installApexPackages requires talking to external service (apexd), we
+ // schedule to run it async. Once it finishes, it will resume the install.
+ Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests),
+ "installApexPackages");
+ t.start();
+ } else {
+ // Non-staged APEX installation failed somewhere before
+ // processInstallRequestAsync. In that case just notify the observer about the
+ // failure.
+ InstallRequest request = apexInstallRequests.get(0);
+ mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
+ }
+ return;
+ }
+
+ processApkInstallRequests(success, installRequests);
+ }
+
+ private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) {
+ if (success) {
+ for (InstallRequest request : installRequests) {
+ if (request.mInstallResult.mReturnCode != PackageManager.INSTALL_SUCCEEDED) {
+ cleanUpForFailedInstall(request.mArgs);
+ }
+ }
+
+ mInstallPackageHelper.installPackagesTraced(installRequests);
+
+ for (InstallRequest request : installRequests) {
+ doPostInstall(request.mInstallResult.mReturnCode, request.mArgs);
+ }
+ }
+ for (InstallRequest request : installRequests) {
+ mInstallPackageHelper.restoreAndPostInstall(request.mArgs.mUser.getIdentifier(),
+ request.mInstallResult,
+ new PostInstallData(request.mArgs,
+ request.mInstallResult, null));
+ }
+ }
+
+ private void doPostInstall(int status, InstallArgs args) {
+ if (mMoveInfo != null) {
+ if (status == PackageManager.INSTALL_SUCCEEDED) {
+ mRemovePackageHelper.cleanUpForMoveInstall(mMoveInfo.mFromUuid,
+ mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
+ } else {
+ mRemovePackageHelper.cleanUpForMoveInstall(mMoveInfo.mToUuid,
+ mMoveInfo.mPackageName, mMoveInfo.mFromCodePath);
+ }
+ } else {
+ if (status != PackageManager.INSTALL_SUCCEEDED) {
+ mRemovePackageHelper.removeCodePath(args.mCodeFile);
+ }
+ }
+ }
+
+ private void cleanUpForFailedInstall(InstallArgs args) {
+ if (args.mMoveInfo != null) {
+ mRemovePackageHelper.cleanUpForMoveInstall(args.mMoveInfo.mToUuid,
+ args.mMoveInfo.mPackageName, args.mMoveInfo.mFromCodePath);
+ } else {
+ mRemovePackageHelper.removeCodePath(args.mCodeFile);
+ }
+ }
+
+ private void installApexPackagesTraced(List<InstallRequest> requests) {
+ try {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages");
+ installApexPackages(requests);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ private void installApexPackages(List<InstallRequest> requests) {
+ if (requests.isEmpty()) {
+ return;
+ }
+ if (requests.size() != 1) {
+ throw new IllegalStateException(
+ "Only a non-staged install of a single APEX is supported");
+ }
+ InstallRequest request = requests.get(0);
+ try {
+ // Should directory scanning logic be moved to ApexManager for better test coverage?
+ final File dir = request.mArgs.mOriginInfo.mResolvedFile;
+ final File[] apexes = dir.listFiles();
+ if (apexes == null) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ dir.getAbsolutePath() + " is not a directory");
+ }
+ if (apexes.length != 1) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Expected exactly one .apex file under " + dir.getAbsolutePath()
+ + " got: " + apexes.length);
+ }
+ try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) {
+ ApexInfo apexInfo = mPm.mApexManager.installPackage(apexes[0]);
+ if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
+ // APEX has been handled successfully by apexd. Let's continue the install flow
+ // so it will be scanned and registered with the system.
+ // TODO(b/225756739): Improve atomicity of rebootless APEX install.
+ // The newly installed APEX will not be reverted even if
+ // processApkInstallRequests() fails. Need a way to keep info stored in apexd
+ // and PMS in sync in the face of install failures.
+ request.mInstallResult.mApexInfo = apexInfo;
+ mPm.mHandler.post(() -> processApkInstallRequests(true, requests));
+ return;
+ } else {
+ mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser);
+ }
+ }
+ } catch (PackageManagerException e) {
+ request.mInstallResult.setError("APEX installation failed", e);
+ }
+ PackageManagerService.invalidatePackageInfoCache();
+ mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver);
+ }
+
+ /**
+ * Container for a multi-package install which refers to all install sessions and args being
+ * committed together.
+ */
+ private class MultiPackageInstallingSession {
+ private final List<InstallingSession> mChildInstallingSessions;
+ private final Map<InstallArgs, Integer> mCurrentState;
+ @NonNull
+ final PackageManagerService mPm;
+ final UserHandle mUser;
+
+ MultiPackageInstallingSession(UserHandle user,
+ List<InstallingSession> childInstallingSessions,
+ PackageManagerService pm)
+ throws PackageManagerException {
+ if (childInstallingSessions.size() == 0) {
+ throw new PackageManagerException("No child sessions found!");
+ }
+ mPm = pm;
+ mUser = user;
+ mChildInstallingSessions = childInstallingSessions;
+ for (int i = 0; i < childInstallingSessions.size(); i++) {
+ final InstallingSession childInstallingSession = childInstallingSessions.get(i);
+ childInstallingSession.mParentInstallingSession = this;
+ }
+ this.mCurrentState = new ArrayMap<>(mChildInstallingSessions.size());
+ }
+
+ public void start() {
+ if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this);
+ Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
+ System.identityHashCode(this));
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
+ for (InstallingSession childInstallingSession : mChildInstallingSessions) {
+ childInstallingSession.handleStartCopy();
+ }
+ for (InstallingSession childInstallingSession : mChildInstallingSessions) {
+ childInstallingSession.handleReturnCode();
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ public void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
+ mCurrentState.put(args, currentStatus);
+ if (mCurrentState.size() != mChildInstallingSessions.size()) {
+ return;
+ }
+ int completeStatus = PackageManager.INSTALL_SUCCEEDED;
+ for (Integer status : mCurrentState.values()) {
+ if (status == PackageManager.INSTALL_UNKNOWN) {
+ return;
+ } else if (status != PackageManager.INSTALL_SUCCEEDED) {
+ completeStatus = status;
+ break;
+ }
+ }
+ final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
+ for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
+ installRequests.add(new InstallRequest(entry.getKey(),
+ new PackageInstalledInfo(completeStatus)));
+ }
+ int finalCompleteStatus = completeStatus;
+ mPm.mHandler.post(() -> processInstallRequests(
+ finalCompleteStatus == PackageManager.INSTALL_SUCCEEDED /* success */,
+ installRequests));
+ }
+
+ @Override
+ public String toString() {
+ return "MultiPackageInstallingSession{" + Integer.toHexString(
+ System.identityHashCode(this))
+ + "}";
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/MoveInstallArgs.java b/services/core/java/com/android/server/pm/MoveInstallArgs.java
deleted file mode 100644
index 1f167ce2ec9a..000000000000
--- a/services/core/java/com/android/server/pm/MoveInstallArgs.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.pm;
-
-import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
-import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
-
-import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.TAG;
-
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.util.Slog;
-
-import com.android.server.pm.parsing.pkg.ParsedPackage;
-
-import java.io.File;
-
-/**
- * Logic to handle movement of existing installed applications.
- */
-final class MoveInstallArgs extends InstallArgs {
- private File mCodeFile;
-
- /** New install */
- MoveInstallArgs(InstallingSession params) {
- super(params);
- }
-
- int copyApk() {
- if (DEBUG_INSTALL) {
- Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
- + mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
- }
- synchronized (mPm.mInstaller) {
- try {
- mPm.mInstaller.moveCompleteApp(mMoveInfo.mFromUuid, mMoveInfo.mToUuid,
- mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
- mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
- } catch (Installer.InstallerException e) {
- Slog.w(TAG, "Failed to move app", e);
- return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
- }
- }
-
- final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
- mCodeFile = new File(Environment.getDataAppDirectory(mMoveInfo.mToUuid), toPathName);
- if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + mCodeFile);
-
- return PackageManager.INSTALL_SUCCEEDED;
- }
-
- int doPreInstall(int status) {
- if (status != PackageManager.INSTALL_SUCCEEDED) {
- cleanUp(mMoveInfo.mToUuid);
- }
- return status;
- }
-
- @Override
- boolean doRename(int status, ParsedPackage parsedPackage) {
- if (status != PackageManager.INSTALL_SUCCEEDED) {
- cleanUp(mMoveInfo.mToUuid);
- return false;
- }
-
- return true;
- }
-
- int doPostInstall(int status, int uid) {
- if (status == PackageManager.INSTALL_SUCCEEDED) {
- cleanUp(mMoveInfo.mFromUuid);
- } else {
- cleanUp(mMoveInfo.mToUuid);
- }
- return status;
- }
-
- @Override
- String getCodePath() {
- return (mCodeFile != null) ? mCodeFile.getAbsolutePath() : null;
- }
-
- private void cleanUp(String volumeUuid) {
- final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
- final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
- toPathName);
- Slog.d(TAG, "Cleaning up " + mMoveInfo.mPackageName + " on " + volumeUuid);
- final int[] userIds = mPm.mUserManager.getUserIds();
- synchronized (mPm.mInstallLock) {
- // Clean up both app data and code
- // All package moves are frozen until finished
-
- // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
- // this task was only focused on moving data on internal storage.
- // We don't want ART profiles cleared, because they don't move,
- // so we would be deleting the only copy (b/149200535).
- final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
- | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
- for (int userId : userIds) {
- try {
- mPm.mInstaller.destroyAppData(volumeUuid, mMoveInfo.mPackageName, userId, flags,
- 0);
- } catch (Installer.InstallerException e) {
- Slog.w(TAG, String.valueOf(e));
- }
- }
- mRemovePackageHelper.removeCodePathLI(codeFile);
- }
- }
-
- void cleanUpResourcesLI() {
- throw new UnsupportedOperationException();
- }
-
- boolean doPostDeleteLI(boolean delete) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java b/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java
deleted file mode 100644
index e5ed5d8a5f5b..000000000000
--- a/services/core/java/com/android/server/pm/MultiPackageInstallingSession.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm;
-
-import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-
-import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
-import static com.android.server.pm.PackageManagerService.TAG;
-
-import android.annotation.NonNull;
-import android.content.pm.PackageManager;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Container for a multi-package install which refers to all install sessions and args being
- * committed together.
- */
-final class MultiPackageInstallingSession {
- private final List<InstallingSession> mChildInstallingSessions;
- private final Map<InstallArgs, Integer> mCurrentState;
- @NonNull
- final PackageManagerService mPm;
- final UserHandle mUser;
-
- MultiPackageInstallingSession(UserHandle user, List<InstallingSession> childInstallingSessions,
- PackageManagerService pm)
- throws PackageManagerException {
- if (childInstallingSessions.size() == 0) {
- throw new PackageManagerException("No child sessions found!");
- }
- mPm = pm;
- mUser = user;
- mChildInstallingSessions = childInstallingSessions;
- for (int i = 0; i < childInstallingSessions.size(); i++) {
- final InstallingSession childInstallingSession = childInstallingSessions.get(i);
- childInstallingSession.mParentInstallingSession = this;
- }
- this.mCurrentState = new ArrayMap<>(mChildInstallingSessions.size());
- }
-
- public void start() {
- if (DEBUG_INSTALL) Slog.i(TAG, "start " + mUser + ": " + this);
- Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
- System.identityHashCode(this));
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
- for (InstallingSession childInstallingSession : mChildInstallingSessions) {
- childInstallingSession.handleStartCopy();
- }
- for (InstallingSession childInstallingSession : mChildInstallingSessions) {
- childInstallingSession.handleReturnCode();
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- public void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
- mCurrentState.put(args, currentStatus);
- if (mCurrentState.size() != mChildInstallingSessions.size()) {
- return;
- }
- int completeStatus = PackageManager.INSTALL_SUCCEEDED;
- for (Integer status : mCurrentState.values()) {
- if (status == PackageManager.INSTALL_UNKNOWN) {
- return;
- } else if (status != PackageManager.INSTALL_SUCCEEDED) {
- completeStatus = status;
- break;
- }
- }
- final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
- for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
- installRequests.add(new InstallRequest(entry.getKey(),
- new PackageInstalledInfo(completeStatus)));
- }
- int finalCompleteStatus = completeStatus;
- final InstallPackageHelper installPackageHelper = new InstallPackageHelper(mPm);
- mPm.mHandler.post(() -> installPackageHelper.processInstallRequests(
- finalCompleteStatus == PackageManager.INSTALL_SUCCEEDED /* success */,
- installRequests));
- }
-
- @Override
- public String toString() {
- return "MultiPackageInstallingSession{" + Integer.toHexString(System.identityHashCode(this))
- + "}";
- }
-}
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index c950dcfc30bd..d50e55ee5303 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -62,11 +62,13 @@ import java.io.IOException;
final class PackageHandler extends Handler {
private final PackageManagerService mPm;
private final InstallPackageHelper mInstallPackageHelper;
+ private final RemovePackageHelper mRemovePackageHelper;
PackageHandler(Looper looper, PackageManagerService pm) {
super(looper);
mPm = pm;
mInstallPackageHelper = new InstallPackageHelper(mPm);
+ mRemovePackageHelper = new RemovePackageHelper(mPm);
}
@Override
@@ -107,11 +109,9 @@ final class PackageHandler extends Handler {
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
} break;
case DEFERRED_NO_KILL_POST_DELETE: {
- synchronized (mPm.mInstallLock) {
- InstallArgs args = (InstallArgs) msg.obj;
- if (args != null) {
- args.doPostDeleteLI(true);
- }
+ InstallArgs args = (InstallArgs) msg.obj;
+ if (args != null) {
+ mRemovePackageHelper.cleanUpResources(args);
}
} break;
case DEFERRED_NO_KILL_INSTALL_OBSERVER:
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index bb23d89d218f..6ee43a0268b6 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -379,9 +379,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
// Clean up orphaned staging directories
for (File stage : stagingDirsToRemove) {
Slog.w(TAG, "Deleting orphan stage " + stage);
- synchronized (mPm.mInstallLock) {
- removePackageHelper.removeCodePathLI(stage);
- }
+ removePackageHelper.removeCodePath(stage);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a909977583b4..3f052c039f9c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -201,7 +201,6 @@ import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.ArtUtils;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.ViewCompiler;
-import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackage;
@@ -6175,26 +6174,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
@Override
- public void pruneCachedApksInApex(@NonNull List<String> apexPackageNames) {
- if (mCacheDir == null) {
- return;
- }
-
- final PackageCacher cacher = new PackageCacher(mCacheDir);
- synchronized (mLock) {
- final Computer snapshot = snapshot();
- for (int i = 0, size = apexPackageNames.size(); i < size; i++) {
- final List<String> apkNames =
- mApexManager.getApksInApex(apexPackageNames.get(i));
- for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) {
- final AndroidPackage pkg = snapshot.getPackage(apkNames.get(j));
- cacher.cleanCachedResult(new File(pkg.getPath()));
- }
- }
- }
- }
-
- @Override
public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
if (policy != null) {
mExternalSourcesPolicy = policy;
diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
index 731a1a53260d..28a021bf4c45 100644
--- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java
+++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
@@ -25,7 +25,6 @@ import android.content.Intent;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.SigningDetails;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
@@ -325,10 +324,7 @@ final class PackageSessionVerifier {
// APEX checks. For single-package sessions, check if they contain an APEX. For
// multi-package sessions, find all the child sessions that contain an APEX.
if (hasApex) {
- final List<String> apexPackageNames = submitSessionToApexService(session, rollbackId);
- final PackageManagerInternal packageManagerInternal =
- LocalServices.getService(PackageManagerInternal.class);
- packageManagerInternal.pruneCachedApksInApex(apexPackageNames);
+ submitSessionToApexService(session, rollbackId);
}
}
@@ -372,7 +368,7 @@ final class PackageSessionVerifier {
}
}
- private List<String> submitSessionToApexService(StagingManager.StagedSession session,
+ private void submitSessionToApexService(StagingManager.StagedSession session,
int rollbackId) throws PackageManagerException {
final IntArray childSessionIds = new IntArray();
if (session.isMultiPackage()) {
@@ -412,7 +408,6 @@ final class PackageSessionVerifier {
}
Slog.d(TAG, "Session " + session.sessionId() + " has following APEX packages: "
+ apexPackageNames);
- return apexPackageNames;
}
private int retrieveRollbackIdForCommitSession(int sessionId) throws PackageManagerException {
diff --git a/services/core/java/com/android/server/pm/ReconciledPackage.java b/services/core/java/com/android/server/pm/ReconciledPackage.java
index bd63a1a4f10f..1bfe3576225f 100644
--- a/services/core/java/com/android/server/pm/ReconciledPackage.java
+++ b/services/core/java/com/android/server/pm/ReconciledPackage.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.SigningDetails;
@@ -75,7 +76,7 @@ final class ReconciledPackage {
* with the package(s) currently being installed. The to-be installed packages take
* precedence and may shadow already installed packages.
*/
- Map<String, AndroidPackage> getCombinedAvailablePackages() {
+ @NonNull Map<String, AndroidPackage> getCombinedAvailablePackages() {
final ArrayMap<String, AndroidPackage> combined =
new ArrayMap<>(mRequest.mAllPackages.size() + mRequest.mScannedPackages.size());
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 65d3430fe474..f083b67a0402 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -23,6 +23,7 @@ import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
+import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
import static com.android.server.pm.PackageManagerService.RANDOM_DIR_PREFIX;
@@ -30,6 +31,11 @@ import static com.android.server.pm.PackageManagerService.TAG;
import android.annotation.NonNull;
import android.content.pm.PackageManager;
+import android.content.pm.parsing.ApkLiteParseUtils;
+import android.content.pm.parsing.PackageLite;
+import android.content.pm.parsing.result.ParseResult;
+import android.content.pm.parsing.result.ParseTypeImpl;
+import android.os.Environment;
import android.os.Trace;
import android.os.UserHandle;
import android.os.incremental.IncrementalManager;
@@ -78,8 +84,17 @@ final class RemovePackageHelper {
this(pm, new AppDataHelper(pm));
}
+ public void removeCodePath(File codePath) {
+ synchronized (mPm.mInstallLock) {
+ removeCodePathLI(codePath);
+ }
+ }
+
@GuardedBy("mPm.mInstallLock")
- public void removeCodePathLI(File codePath) {
+ private void removeCodePathLI(File codePath) {
+ if (codePath == null || !codePath.exists()) {
+ return;
+ }
if (codePath.isDirectory()) {
final File codePathParent = codePath.getParentFile();
final boolean needRemoveParent = codePathParent.getName().startsWith(RANDOM_DIR_PREFIX);
@@ -118,7 +133,14 @@ final class RemovePackageHelper {
cacher.cleanCachedResult(codePath);
}
- public void removePackageLI(AndroidPackage pkg, boolean chatty) {
+ public void removePackage(AndroidPackage pkg, boolean chatty) {
+ synchronized (mPm.mInstallLock) {
+ removePackageLI(pkg, chatty);
+ }
+ }
+
+ @GuardedBy("mPm.mInstallLock")
+ private void removePackageLI(AndroidPackage pkg, boolean chatty) {
// Remove the parent package setting
PackageStateInternal ps = mPm.snapshotComputer()
.getPackageStateInternal(pkg.getPackageName());
@@ -129,6 +151,7 @@ final class RemovePackageHelper {
}
}
+ @GuardedBy("mPm.mInstallLock")
private void removePackageLI(String packageName, boolean chatty) {
if (DEBUG_INSTALL) {
if (chatty) {
@@ -145,6 +168,7 @@ final class RemovePackageHelper {
}
}
+ @GuardedBy("mPm.mLock")
private void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
mPm.mComponentResolver.removeAllComponents(pkg, chatty);
mPermissionManager.onPackageRemoved(pkg);
@@ -175,7 +199,7 @@ final class RemovePackageHelper {
final int libraryNamesSize = pkg.getLibraryNames().size();
for (i = 0; i < libraryNamesSize; i++) {
String name = pkg.getLibraryNames().get(i);
- if (mSharedLibraries.removeSharedLibraryLPw(name, 0)) {
+ if (mSharedLibraries.removeSharedLibrary(name, 0)) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
@@ -192,7 +216,7 @@ final class RemovePackageHelper {
// Any package can hold SDK or static shared libraries.
if (pkg.getSdkLibName() != null) {
- if (mSharedLibraries.removeSharedLibraryLPw(
+ if (mSharedLibraries.removeSharedLibrary(
pkg.getSdkLibName(), pkg.getSdkLibVersionMajor())) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -205,7 +229,7 @@ final class RemovePackageHelper {
}
}
if (pkg.getStaticSharedLibName() != null) {
- if (mSharedLibraries.removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
+ if (mSharedLibraries.removeSharedLibrary(pkg.getStaticSharedLibName(),
pkg.getStaticSharedLibVersion())) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -223,12 +247,20 @@ final class RemovePackageHelper {
}
}
+ public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
+ PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
+ synchronized (mPm.mInstallLock) {
+ removePackageDataLIF(deletedPs, allUserHandles, outInfo, flags, writeSettings);
+ }
+ }
+
/*
* This method deletes the package from internal data structures. If the DELETE_KEEP_DATA
* flag is not set, the data directory is removed as well.
* make sure this flag is set for partially installed apps. If not its meaningless to
* delete a partially installed application.
*/
+ @GuardedBy("mPm.mInstallLock")
public void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
String packageName = deletedPs.getPackageName();
@@ -352,4 +384,74 @@ final class RemovePackageHelper {
});
}
}
+
+ void cleanUpResources(InstallArgs args) {
+ synchronized (mPm.mInstallLock) {
+ cleanUpResourcesLI(args);
+ }
+ }
+
+ // Need installer lock especially for dex file removal.
+ @GuardedBy("mPm.mInstallLock")
+ private void cleanUpResourcesLI(InstallArgs args) {
+ // Try enumerating all code paths before deleting
+ List<String> allCodePaths = Collections.EMPTY_LIST;
+ if (args.mCodeFile != null && args.mCodeFile.exists()) {
+ final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+ final ParseResult<PackageLite> result = ApkLiteParseUtils.parsePackageLite(
+ input.reset(), args.mCodeFile, /* flags */ 0);
+ if (result.isSuccess()) {
+ // Ignore error; we tried our best
+ allCodePaths = result.getResult().getAllApkPaths();
+ }
+ }
+
+ removeCodePathLI(args.mCodeFile);
+ removeDexFilesLI(allCodePaths, args.mInstructionSets);
+ }
+
+ @GuardedBy("mPm.mInstallLock")
+ private void removeDexFilesLI(List<String> allCodePaths, String[] instructionSets) {
+ if (!allCodePaths.isEmpty()) {
+ if (instructionSets == null) {
+ throw new IllegalStateException("instructionSet == null");
+ }
+ String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
+ for (String codePath : allCodePaths) {
+ for (String dexCodeInstructionSet : dexCodeInstructionSets) {
+ try {
+ mPm.mInstaller.rmdex(codePath, dexCodeInstructionSet);
+ } catch (Installer.InstallerException ignored) {
+ }
+ }
+ }
+ }
+ }
+
+ void cleanUpForMoveInstall(String volumeUuid, String packageName, String fromCodePath) {
+ final String toPathName = new File(fromCodePath).getName();
+ final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), toPathName);
+ Slog.d(TAG, "Cleaning up " + packageName + " on " + volumeUuid);
+ final int[] userIds = mPm.mUserManager.getUserIds();
+ synchronized (mPm.mInstallLock) {
+ // Clean up both app data and code
+ // All package moves are frozen until finished
+
+ // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
+ // this task was only focused on moving data on internal storage.
+ // We don't want ART profiles cleared, because they don't move,
+ // so we would be deleting the only copy (b/149200535).
+ final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
+ | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
+ for (int userId : userIds) {
+ try {
+ mPm.mInstaller.destroyAppData(volumeUuid, packageName, userId, flags,
+ 0);
+ } catch (Installer.InstallerException e) {
+ Slog.w(TAG, String.valueOf(e));
+ }
+ }
+ removeCodePathLI(codeFile);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index fe160e3fee22..0e57c917a72b 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -428,8 +428,7 @@ final class ScanPackageUtils {
pkgSetting.setLastModifiedTime(scanFileTime);
// TODO(b/135203078): Remove, move to constructor
pkgSetting.setPkg(parsedPackage)
- .setFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting))
- .setPrivateFlags(
+ .setPkgFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting));
if (parsedPackage.getLongVersionCode() != pkgSetting.getVersionCode()) {
pkgSetting.setLongVersionCode(parsedPackage.getLongVersionCode());
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index b952f80850bb..61a251e19db7 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -146,6 +146,17 @@ public abstract class SettingBase implements Watchable, Snappable {
return this;
}
+ /**
+ * Unconditionally set both mPkgFlags and mPkgPrivateFlags.
+ * Should not be used outside pkgSetting initialization or update.
+ */
+ SettingBase setPkgFlags(int flags, int privateFlags) {
+ this.mPkgFlags = flags;
+ this.mPkgPrivateFlags = privateFlags;
+ onChanged();
+ return this;
+ }
+
public int getFlags() {
return mPkgFlags;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 138915dc42c0..c064324279c1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -987,8 +987,7 @@ public final class Settings implements Watchable, Snappable {
// Update new package state.
.setLastModifiedTime(codePath.lastModified())
.setDomainSetId(domainSetId);
- pkgSetting.setFlags(pkgFlags)
- .setPrivateFlags(pkgPrivateFlags);
+ pkgSetting.setPkgFlags(pkgFlags, pkgPrivateFlags);
} else {
pkgSetting = new PackageSetting(pkgName, realPkgName, codePath,
legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi,
@@ -1175,15 +1174,15 @@ public final class Settings implements Watchable, Snappable {
.setUsesStaticLibrariesVersions(null);
}
- // These two flags are preserved from the existing PackageSetting. Copied from prior code,
- // unclear if this is actually necessary.
- boolean wasExternalStorage = (pkgSetting.getFlags()
- & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
- if (wasExternalStorage) {
- pkgFlags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
- } else {
- pkgFlags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
- }
+ // If what we are scanning is a system (and possibly privileged) package,
+ // then make it so, regardless of whether it was previously installed only
+ // in the data partition. Reset first.
+ int newPkgFlags = pkgSetting.getFlags();
+ newPkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
+ newPkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
+ // Only set pkgFlags.
+ pkgSetting.setPkgFlags(newPkgFlags, pkgSetting.getPrivateFlags());
+
boolean wasRequiredForSystemUser = (pkgSetting.getPrivateFlags()
& ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER) != 0;
if (wasRequiredForSystemUser) {
@@ -1191,9 +1190,7 @@ public final class Settings implements Watchable, Snappable {
} else {
pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
}
-
- pkgSetting.setFlags(pkgFlags)
- .setPrivateFlags(pkgPrivateFlags);
+ pkgSetting.setPrivateFlags(pkgPrivateFlags);
}
/**
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index 479a404c88bf..7432b8446f35 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -19,6 +19,7 @@ package com.android.server.pm;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
import static com.android.server.pm.PackageManagerService.TAG;
import android.annotation.NonNull;
@@ -258,11 +259,13 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* Given the library name, returns a list of shared libraries on all versions.
* TODO: Remove, this is used for live mutation outside of the defined commit path
*/
- @GuardedBy("mPm.mLock")
+
@Override
public @NonNull WatchedLongSparseArray<SharedLibraryInfo> getSharedLibraryInfos(
@NonNull String libName) {
- return mSharedLibraries.get(libName);
+ synchronized (mPm.mLock) {
+ return mSharedLibraries.get(libName);
+ }
}
@VisibleForTesting
@@ -381,6 +384,11 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
return false;
}
+ @Nullable SharedLibraryInfo getLatestStaticSharedLibraVersion(@NonNull AndroidPackage pkg) {
+ synchronized (mPm.mLock) {
+ return getLatestStaticSharedLibraVersionLPr(pkg);
+ }
+ }
/**
* Given a package of static shared library, returns its shared library info of
* the latest version.
@@ -389,7 +397,8 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* @return The latest version of shared library info.
*/
@GuardedBy("mPm.mLock")
- @Nullable SharedLibraryInfo getLatestStaticSharedLibraVersionLPr(@NonNull AndroidPackage pkg) {
+ @Nullable
+ private SharedLibraryInfo getLatestStaticSharedLibraVersionLPr(@NonNull AndroidPackage pkg) {
WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
pkg.getStaticSharedLibName());
if (versionedLib == null) {
@@ -524,15 +533,26 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* @param changingLibSetting The updating library package setting.
* @param availablePackages All installed packages and current being installed packages.
*/
- @GuardedBy("mPm.mLock")
- void updateSharedLibrariesLPw(@NonNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
+ void updateSharedLibraries(@NonNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting,
@Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
@NonNull Map<String, AndroidPackage> availablePackages)
throws PackageManagerException {
final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
pkg, availablePackages, null /* newLibraries */);
- executeSharedLibrariesUpdateLPw(pkg, pkgSetting, changingLib, changingLibSetting,
- sharedLibraryInfos, mPm.mUserManager.getUserIds());
+ synchronized (mPm.mLock) {
+ executeSharedLibrariesUpdateLPw(pkg, pkgSetting, changingLib, changingLibSetting,
+ sharedLibraryInfos, mPm.mUserManager.getUserIds());
+ }
+ }
+
+ void executeSharedLibrariesUpdate(AndroidPackage pkg,
+ @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
+ @Nullable PackageSetting changingLibSetting,
+ ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) {
+ synchronized (mPm.mLock) {
+ executeSharedLibrariesUpdateLPw(pkg, pkgSetting, changingLib, changingLibSetting,
+ usesLibraryInfos, allUsers);
+ }
}
/**
@@ -547,7 +567,7 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* @param allUsers All user ids on the device.
*/
@GuardedBy("mPm.mLock")
- void executeSharedLibrariesUpdateLPw(AndroidPackage pkg,
+ private void executeSharedLibrariesUpdateLPw(AndroidPackage pkg,
@NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
@Nullable PackageSetting changingLibSetting,
ArrayList<SharedLibraryInfo> usesLibraryInfos, int[] allUsers) {
@@ -610,6 +630,31 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
return false;
}
+ ArrayList<AndroidPackage> commitSharedLibraryChanges(@NonNull AndroidPackage pkg,
+ @NonNull PackageSetting pkgSetting, List<SharedLibraryInfo> allowedSharedLibraryInfos,
+ @NonNull Map<String, AndroidPackage> combinedSigningDetails, int scanFlags) {
+ if (ArrayUtils.isEmpty(allowedSharedLibraryInfos)) {
+ return null;
+ }
+ synchronized (mPm.mLock) {
+ for (SharedLibraryInfo info : allowedSharedLibraryInfos) {
+ commitSharedLibraryInfoLPw(info);
+ }
+ try {
+ // Shared libraries for the package need to be updated.
+ updateSharedLibraries(pkg, pkgSetting, null, null, combinedSigningDetails);
+ } catch (PackageManagerException e) {
+ Slog.e(TAG, "updateSharedLibraries failed: ", e);
+ }
+ // Update all applications that use this library. Skip when booting
+ // since this will be done after all packages are scaned.
+ if ((scanFlags & SCAN_BOOTING) == 0) {
+ return updateAllSharedLibrariesLPw(pkg, pkgSetting, combinedSigningDetails);
+ }
+ }
+ return null;
+ }
+
/**
* Update shared library dependencies and code paths for applications that are using the
* library {@code updatedPkg}. Update all applications if the {@code updatedPkg} is null.
@@ -666,7 +711,7 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
}
}
try {
- updateSharedLibrariesLPw(pkg, pkgSetting, changingPkg,
+ updateSharedLibraries(pkg, pkgSetting, changingPkg,
changingPkgSetting, availablePackages);
} catch (PackageManagerException e) {
// If a system app update or an app and a required lib missing we
@@ -677,9 +722,11 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
if (!pkg.isSystem() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
final int flags = pkgSetting.getPkgState().isUpdatedSystemApp()
? PackageManager.DELETE_KEEP_DATA : 0;
- mDeletePackageHelper.deletePackageLIF(pkg.getPackageName(), null, true,
- mPm.mUserManager.getUserIds(), flags, null,
- true);
+ synchronized (mPm.mInstallLock) {
+ mDeletePackageHelper.deletePackageLIF(pkg.getPackageName(), null, true,
+ mPm.mUserManager.getUserIds(), flags, null,
+ true);
+ }
}
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
}
@@ -711,6 +758,7 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
* Add a shared library info to the system. This is invoked when the package is being added or
* scanned.
*/
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@GuardedBy("mPm.mLock")
void commitSharedLibraryInfoLPw(@NonNull SharedLibraryInfo libraryInfo) {
final String name = libraryInfo.getName();
@@ -729,45 +777,46 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
/**
* Remove a shared library from the system.
*/
- @GuardedBy("mPm.mLock")
- boolean removeSharedLibraryLPw(@NonNull String libName, long version) {
- WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
- if (versionedLib == null) {
- return false;
- }
- final int libIdx = versionedLib.indexOfKey(version);
- if (libIdx < 0) {
- return false;
- }
- SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
+ boolean removeSharedLibrary(@NonNull String libName, long version) {
+ synchronized (mPm.mLock) {
+ WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
+ if (versionedLib == null) {
+ return false;
+ }
+ final int libIdx = versionedLib.indexOfKey(version);
+ if (libIdx < 0) {
+ return false;
+ }
+ SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
- final Computer snapshot = mPm.snapshotComputer();
+ final Computer snapshot = mPm.snapshotComputer();
- // Remove the shared library overlays from its dependent packages.
- for (int currentUserId : mPm.mUserManager.getUserIds()) {
- final List<VersionedPackage> dependents = snapshot.getPackagesUsingSharedLibrary(
- libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
- if (dependents == null) {
- continue;
- }
- for (VersionedPackage dependentPackage : dependents) {
- final PackageSetting ps = mPm.mSettings.getPackageLPr(
- dependentPackage.getPackageName());
- if (ps != null) {
- ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
+ // Remove the shared library overlays from its dependent packages.
+ for (int currentUserId : mPm.mUserManager.getUserIds()) {
+ final List<VersionedPackage> dependents = snapshot.getPackagesUsingSharedLibrary(
+ libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
+ if (dependents == null) {
+ continue;
+ }
+ for (VersionedPackage dependentPackage : dependents) {
+ final PackageSetting ps = mPm.mSettings.getPackageLPr(
+ dependentPackage.getPackageName());
+ if (ps != null) {
+ ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
+ }
}
}
- }
- versionedLib.remove(version);
- if (versionedLib.size() <= 0) {
- mSharedLibraries.remove(libName);
- if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
- mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
- .getPackageName());
+ versionedLib.remove(version);
+ if (versionedLib.size() <= 0) {
+ mSharedLibraries.remove(libName);
+ if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
+ mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
+ .getPackageName());
+ }
}
+ return true;
}
- return true;
}
/**
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index fe1c83bab30c..f621d8b2533a 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -346,9 +346,7 @@ public final class StorageEventHelper extends StorageEventListener {
for (int i = 0; i < fileToDeleteCount; i++) {
File fileToDelete = filesToDelete.get(i);
logCriticalInfo(Log.WARN, "Destroying orphaned at " + fileToDelete);
- synchronized (mPm.mInstallLock) {
- mRemovePackageHelper.removeCodePathLI(fileToDelete);
- }
+ mRemovePackageHelper.removeCodePath(fileToDelete);
}
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index df4263909257..3df412da4ac6 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -403,11 +403,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
@Override
public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
- mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
- "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
- + " to remove permissions as one time.");
Objects.requireNonNull(packageName);
final long token = Binder.clearCallingIdentity();
@@ -1114,16 +1112,21 @@ public class PermissionManagerService extends IPermissionManager.Stub {
appOpsManager.finishProxyOp(AppOpsManager.opToPublicName(op),
resolvedAttributionSource, skipCurrentFinish);
}
-
- if (next == null || next.getNext() == null) {
- return;
- }
-
RegisteredAttribution registered =
sRunningAttributionSources.remove(current.getToken());
if (registered != null) {
registered.unregister();
}
+
+ if (next == null || next.getNext() == null) {
+ if (next != null) {
+ registered = sRunningAttributionSources.remove(next.getToken());
+ if (registered != null) {
+ registered.unregister();
+ }
+ }
+ return;
+ }
current = next;
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dd952f4e903b..cbab2c594b4e 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4585,12 +4585,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return false;
}
- final long sleepDuration = mPowerManagerInternal.getLastWakeup().sleepDuration;
+ final long sleepDurationRealtime =
+ mPowerManagerInternal.getLastWakeup().sleepDurationRealtime;
if (DEBUG_WAKEUP) {
- Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDuration= " + sleepDuration
+ Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDurationRealtime= " + sleepDurationRealtime
+ " mWakeUpToLastStateTimeout= " + mWakeUpToLastStateTimeout);
}
- return sleepDuration > mWakeUpToLastStateTimeout;
+ return sleepDurationRealtime > mWakeUpToLastStateTimeout;
}
private void wakeUpFromPowerKey(long eventTime) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 9bc0553a7612..e8a3dcd5635f 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -155,10 +155,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
int FINISH_LAYOUT_REDO_ANIM = 0x0008;
/** Layer for the screen off animation */
int COLOR_FADE_LAYER = 0x40000001;
- /** Layer for Input overlays for capturing inputs for gesture detection, etc. */
- int INPUT_DISPLAY_OVERLAY_LAYER = 0x7f000000;
- /** Layer for Screen Decoration: The top most visible layer just below input overlay layers */
- int SCREEN_DECOR_DISPLAY_OVERLAY_LAYER = INPUT_DISPLAY_OVERLAY_LAYER - 1;
/**
* Register shortcuts for window manager to dispatch.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 70be8b82ba78..988b4eba852e 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -376,6 +376,10 @@ public final class PowerManagerService extends SystemService
private long mLastGlobalWakeTime;
private long mLastGlobalSleepTime;
+ // Timestamp (in the elapsed realtime timebase) of the last time was awoken or put to sleep.
+ private long mLastGlobalWakeTimeRealtime;
+ private long mLastGlobalSleepTimeRealtime;
+
// Last reason the device went to sleep.
private @WakeReason int mLastGlobalWakeReason;
private @GoToSleepReason int mLastGlobalSleepReason;
@@ -927,6 +931,11 @@ public final class PowerManagerService extends SystemService
* Returns current time in milliseconds since boot, not counting time spent in deep sleep.
*/
long uptimeMillis();
+
+ /**
+ * Returns milliseconds since boot, including time spent in sleep.
+ */
+ long elapsedRealtime();
}
@VisibleForTesting
@@ -1005,7 +1014,18 @@ public final class PowerManagerService extends SystemService
}
Clock createClock() {
- return SystemClock::uptimeMillis;
+ return new Clock() {
+ @Override
+ public long uptimeMillis() {
+ return SystemClock.uptimeMillis();
+ }
+
+ @Override
+ public long elapsedRealtime() {
+ return SystemClock.elapsedRealtime();
+ }
+ };
+
}
/**
@@ -1206,8 +1226,8 @@ public final class PowerManagerService extends SystemService
millisUntilNormalTimeout =
powerGroup.getLastUserActivityTimeLocked() + screenOffTimeout - currentTime;
userActivityInternal(Display.DEFAULT_DISPLAY, currentTime,
- PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN, /* flags= */0,
- Process.SYSTEM_UID);
+ PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN,
+ PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS, Process.SYSTEM_UID);
}
}
if (isFaceDown) {
@@ -2141,6 +2161,7 @@ public final class PowerManagerService extends SystemService
+ ")...");
mLastGlobalWakeTime = eventTime;
mLastGlobalWakeReason = reason;
+ mLastGlobalWakeTimeRealtime = mClock.elapsedRealtime();
break;
case WAKEFULNESS_DREAMING:
@@ -2152,9 +2173,9 @@ public final class PowerManagerService extends SystemService
traceMethodName = "goToSleep";
Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
+ " (uid " + uid + ")...");
-
mLastGlobalSleepTime = eventTime;
mLastGlobalSleepReason = reason;
+ mLastGlobalSleepTimeRealtime = mClock.elapsedRealtime();
mDozeStartInProgress = true;
break;
@@ -4404,6 +4425,10 @@ public final class PowerManagerService extends SystemService
pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastGlobalSleepTime));
pw.println(" mLastSleepReason=" + PowerManager.sleepReasonToString(
mLastGlobalSleepReason));
+ pw.println(" mLastGlobalWakeTimeRealtime="
+ + TimeUtils.formatUptime(mLastGlobalWakeTimeRealtime));
+ pw.println(" mLastGlobalSleepTimeRealtime="
+ + TimeUtils.formatUptime(mLastGlobalSleepTimeRealtime));
pw.println(" mLastInteractivePowerHintTime="
+ TimeUtils.formatUptime(mLastInteractivePowerHintTime));
pw.println(" mLastScreenBrightnessBoostTime="
@@ -4830,6 +4855,11 @@ public final class PowerManagerService extends SystemService
.IS_STAY_ON_WHILE_PLUGGED_IN_WIRELESS,
((mStayOnWhilePluggedInSetting & BatteryManager.BATTERY_PLUGGED_WIRELESS)
!= 0));
+ proto.write(
+ PowerServiceSettingsAndConfigurationDumpProto.StayOnWhilePluggedInProto
+ .IS_STAY_ON_WHILE_PLUGGED_IN_DOCK,
+ ((mStayOnWhilePluggedInSetting & BatteryManager.BATTERY_PLUGGED_DOCK)
+ != 0));
proto.end(stayOnWhilePluggedInToken);
proto.write(
@@ -5886,7 +5916,7 @@ public final class PowerManagerService extends SystemService
boolean isPersonalized) {
// Get current time before acquiring the lock so that the calculated end time is as
// accurate as possible.
- final long nowElapsed = SystemClock.elapsedRealtime();
+ final long nowElapsed = mClock.elapsedRealtime();
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.BATTERY_PREDICTION)
!= PackageManager.PERMISSION_GRANTED) {
@@ -5950,7 +5980,7 @@ public final class PowerManagerService extends SystemService
synchronized (mEnhancedDischargeTimeLock) {
// Get current time after acquiring the lock so that the calculated duration
// is as accurate as possible.
- final long nowElapsed = SystemClock.elapsedRealtime();
+ final long nowElapsed = mClock.elapsedRealtime();
if (isEnhancedDischargePredictionValidLocked(nowElapsed)) {
return new ParcelDuration(mEnhancedDischargeTimeElapsed - nowElapsed);
}
@@ -5969,7 +5999,7 @@ public final class PowerManagerService extends SystemService
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mEnhancedDischargeTimeLock) {
- return isEnhancedDischargePredictionValidLocked(SystemClock.elapsedRealtime())
+ return isEnhancedDischargePredictionValidLocked(mClock.elapsedRealtime())
&& mEnhancedDischargePredictionIsPersonalized;
}
} finally {
@@ -6459,7 +6489,7 @@ public final class PowerManagerService extends SystemService
private PowerManager.WakeData getLastWakeupInternal() {
synchronized (mLock) {
return new PowerManager.WakeData(mLastGlobalWakeTime, mLastGlobalWakeReason,
- mLastGlobalWakeTime - mLastGlobalSleepTime);
+ mLastGlobalWakeTimeRealtime - mLastGlobalSleepTimeRealtime);
}
}
diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.java b/services/core/java/com/android/server/timedetector/GnssTimeSuggestion.java
index 3531b19d0f65..33499754fbc5 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.java
+++ b/services/core/java/com/android/server/timedetector/GnssTimeSuggestion.java
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package android.app.timedetector;
+package com.android.server.timedetector;
import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.app.timedetector.TimeSuggestionHelper;
import android.os.ShellCommand;
import android.os.TimestampedValue;
@@ -30,23 +29,8 @@ import java.util.Objects;
* A time signal from a GNSS source.
*
* <p>See {@link TimeSuggestionHelper} for property information.
- *
- * @hide
*/
-public final class GnssTimeSuggestion implements Parcelable {
-
- public static final @NonNull Creator<GnssTimeSuggestion> CREATOR =
- new Creator<GnssTimeSuggestion>() {
- public GnssTimeSuggestion createFromParcel(Parcel in) {
- TimeSuggestionHelper helper = TimeSuggestionHelper.handleCreateFromParcel(
- GnssTimeSuggestion.class, in);
- return new GnssTimeSuggestion(helper);
- }
-
- public GnssTimeSuggestion[] newArray(int size) {
- return new GnssTimeSuggestion[size];
- }
- };
+public final class GnssTimeSuggestion {
@NonNull private final TimeSuggestionHelper mTimeSuggestionHelper;
@@ -58,16 +42,6 @@ public final class GnssTimeSuggestion implements Parcelable {
mTimeSuggestionHelper = Objects.requireNonNull(helper);
}
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- mTimeSuggestionHelper.handleWriteToParcel(dest, flags);
- }
-
@NonNull
public TimestampedValue<Long> getUnixEpochTime() {
return mTimeSuggestionHelper.getUnixEpochTime();
diff --git a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
index 129810c3265c..88e9fa52fb1b 100644
--- a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
@@ -19,8 +19,6 @@ package com.android.server.timedetector;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
-import android.app.timedetector.GnssTimeSuggestion;
-import android.app.timedetector.TimeDetector;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
@@ -42,12 +40,13 @@ import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.time.Duration;
+import java.util.Objects;
/**
* Monitors the GNSS time.
*
* <p>When available, the time is always suggested to the {@link
- * com.android.server.timedetector.TimeDetectorService} where it may be used to set the device
+ * com.android.server.timedetector.TimeDetectorInternal} where it may be used to set the device
* system clock, depending on user settings and what other signals are available.
*/
public final class GnssTimeUpdateService extends Binder {
@@ -66,7 +65,16 @@ public final class GnssTimeUpdateService extends Binder {
@Override
public void onStart() {
- mService = new GnssTimeUpdateService(getContext());
+ Context context = getContext().createAttributionContext(ATTRIBUTION_TAG);
+ AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
+ LocationManager locationManager = context.getSystemService(LocationManager.class);
+ LocationManagerInternal locationManagerInternal =
+ LocalServices.getService(LocationManagerInternal.class);
+ TimeDetectorInternal timeDetectorInternal =
+ LocalServices.getService(TimeDetectorInternal.class);
+
+ mService = new GnssTimeUpdateService(context, alarmManager, locationManager,
+ locationManagerInternal, timeDetectorInternal);
publishBinderService("gnss_time_update_service", mService);
}
@@ -88,7 +96,7 @@ public final class GnssTimeUpdateService extends Binder {
private static final String ATTRIBUTION_TAG = "GnssTimeUpdateService";
private final Context mContext;
- private final TimeDetector mTimeDetector;
+ private final TimeDetectorInternal mTimeDetectorInternal;
private final AlarmManager mAlarmManager;
private final LocationManager mLocationManager;
private final LocationManagerInternal mLocationManagerInternal;
@@ -98,12 +106,15 @@ public final class GnssTimeUpdateService extends Binder {
@Nullable private TimestampedValue<Long> mLastSuggestedGnssTime;
@VisibleForTesting
- GnssTimeUpdateService(@NonNull Context context) {
- mContext = context.createAttributionContext(ATTRIBUTION_TAG);
- mTimeDetector = mContext.getSystemService(TimeDetector.class);
- mLocationManager = mContext.getSystemService(LocationManager.class);
- mAlarmManager = mContext.getSystemService(AlarmManager.class);
- mLocationManagerInternal = LocalServices.getService(LocationManagerInternal.class);
+ GnssTimeUpdateService(@NonNull Context context, @NonNull AlarmManager alarmManager,
+ @NonNull LocationManager locationManager,
+ @NonNull LocationManagerInternal locationManagerInternal,
+ @NonNull TimeDetectorInternal timeDetectorInternal) {
+ mContext = Objects.requireNonNull(context);
+ mAlarmManager = Objects.requireNonNull(alarmManager);
+ mLocationManager = Objects.requireNonNull(locationManager);
+ mLocationManagerInternal = Objects.requireNonNull(locationManagerInternal);
+ mTimeDetectorInternal = Objects.requireNonNull(timeDetectorInternal);
}
/**
@@ -191,7 +202,7 @@ public final class GnssTimeUpdateService extends Binder {
mLastSuggestedGnssTime = timeSignal;
GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
- mTimeDetector.suggestGnssTime(timeSuggestion);
+ mTimeDetectorInternal.suggestGnssTime(timeSuggestion);
}
@Override
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java b/services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java
new file mode 100644
index 000000000000..f62c7edb8349
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeSuggestion.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timedetector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.ShellCommand;
+import android.os.TimestampedValue;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A time signal from a network time source like NTP.
+ *
+ * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. The {@code
+ * unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when the {@code
+ * unixEpochTime.value} was established. Note that the elapsed realtime clock is considered accurate
+ * but it is volatile, so time suggestions cannot be persisted across device resets.
+ *
+ * <p>{@code uncertaintyMillis} is an indication of error bounds associated the time. This is a
+ * positive value, and the correct Unix epoch time is <em>likely</em> to be within the bounds +/-
+ * the {@code uncertaintyMillis}. The Unix epoch time is not guaranteed to be within these bounds.
+ *
+ * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
+ * record why the suggestion exists and how it was entered. This information exists only to aid in
+ * debugging and therefore is used by {@link #toString()}, but it is not for use in detection
+ * logic and is not considered in {@link #hashCode()} or {@link #equals(Object)}.
+ */
+public final class NetworkTimeSuggestion {
+
+ @NonNull private final TimestampedValue<Long> mUnixEpochTime;
+ private final int mUncertaintyMillis;
+ @Nullable private ArrayList<String> mDebugInfo;
+
+ /**
+ * Create a {@link NetworkTimeSuggestion} with the supplied property values.
+ *
+ * <p>See {@link NetworkTimeSuggestion} for property details.
+ */
+ public NetworkTimeSuggestion(
+ @NonNull TimestampedValue<Long> unixEpochTime, int uncertaintyMillis) {
+ mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
+ if (uncertaintyMillis < 0) {
+ throw new IllegalArgumentException("uncertaintyMillis < 0");
+ }
+ mUncertaintyMillis = uncertaintyMillis;
+ }
+
+ /** See {@link NetworkTimeSuggestion} for property details. */
+ @NonNull
+ public TimestampedValue<Long> getUnixEpochTime() {
+ return mUnixEpochTime;
+ }
+
+ /** See {@link NetworkTimeSuggestion} for property details. */
+ public int getUncertaintyMillis() {
+ return mUncertaintyMillis;
+ }
+
+ /** See {@link NetworkTimeSuggestion} for information about {@code debugInfo}. */
+ @NonNull
+ public List<String> getDebugInfo() {
+ return mDebugInfo == null
+ ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+ }
+
+ /**
+ * Associates information with the instance that can be useful for debugging / logging. The
+ * information is present in {@link #toString()} but is not considered for {@link
+ * #equals(Object)} and {@link #hashCode()}.
+ */
+ public void addDebugInfo(String... debugInfos) {
+ if (mDebugInfo == null) {
+ mDebugInfo = new ArrayList<>();
+ }
+ mDebugInfo.addAll(Arrays.asList(debugInfos));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof NetworkTimeSuggestion)) {
+ return false;
+ }
+ NetworkTimeSuggestion that = (NetworkTimeSuggestion) o;
+ return mUnixEpochTime.equals(that.mUnixEpochTime)
+ && mUncertaintyMillis == that.mUncertaintyMillis;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUnixEpochTime, mUncertaintyMillis);
+ }
+
+ @Override
+ public String toString() {
+ return "NetworkTimeSuggestion{"
+ + "mUnixEpochTime=" + mUnixEpochTime
+ + ", mUncertaintyMillis=" + mUncertaintyMillis
+ + ", mDebugInfo=" + mDebugInfo
+ + '}';
+ }
+
+ /** Parses command line args to create a {@link NetworkTimeSuggestion}. */
+ public static NetworkTimeSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
+ throws IllegalArgumentException {
+ Long referenceTimeMillis = null;
+ Long unixEpochTimeMillis = null;
+ Integer uncertaintyMillis = null;
+ String opt;
+ while ((opt = cmd.getNextArg()) != null) {
+ switch (opt) {
+ case "--reference_time": {
+ referenceTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+ break;
+ }
+ case "--unix_epoch_time": {
+ unixEpochTimeMillis = Long.parseLong(cmd.getNextArgRequired());
+ break;
+ }
+ case "--uncertainty_millis": {
+ uncertaintyMillis = Integer.parseInt(cmd.getNextArgRequired());
+ break;
+ }
+ default: {
+ throw new IllegalArgumentException("Unknown option: " + opt);
+ }
+ }
+ }
+
+ if (referenceTimeMillis == null) {
+ throw new IllegalArgumentException("No referenceTimeMillis specified.");
+ }
+ if (unixEpochTimeMillis == null) {
+ throw new IllegalArgumentException("No unixEpochTimeMillis specified.");
+ }
+ if (uncertaintyMillis == null) {
+ throw new IllegalArgumentException("No uncertaintyMillis specified.");
+ }
+
+ TimestampedValue<Long> timeSignal =
+ new TimestampedValue<>(referenceTimeMillis, unixEpochTimeMillis);
+ NetworkTimeSuggestion networkTimeSuggestion =
+ new NetworkTimeSuggestion(timeSignal, uncertaintyMillis);
+ networkTimeSuggestion.addDebugInfo("Command line injection");
+ return networkTimeSuggestion;
+ }
+
+ /** Prints the command line args needed to create a {@link NetworkTimeSuggestion}. */
+ public static void printCommandLineOpts(PrintWriter pw) {
+ pw.printf("%s suggestion options:\n", "Network");
+ pw.println(" --reference_time <elapsed realtime millis> - the elapsed realtime millis when"
+ + " unix epoch time was read");
+ pw.println(" --unix_epoch_time <Unix epoch time millis>");
+ pw.println(" --uncertainty_millis <Uncertainty millis> - a positive error bound (+/-)"
+ + " estimate for unix epoch time");
+ pw.println();
+ pw.println("See " + NetworkTimeSuggestion.class.getName() + " for more information");
+ }
+}
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
index 53893252c94b..1f8b0de8d903 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
@@ -20,8 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.PendingIntent;
-import android.app.timedetector.NetworkTimeSuggestion;
-import android.app.timedetector.TimeDetector;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -48,6 +46,7 @@ import android.util.NtpTrustedTime;
import android.util.NtpTrustedTime.TimeResult;
import com.android.internal.util.DumpUtils;
+import com.android.server.LocalServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -80,7 +79,7 @@ public class NetworkTimeUpdateService extends Binder {
private final Context mContext;
private final NtpTrustedTime mTime;
private final AlarmManager mAlarmManager;
- private final TimeDetector mTimeDetector;
+ private final TimeDetectorInternal mTimeDetectorInternal;
private final ConnectivityManager mCM;
private final PendingIntent mPendingPollIntent;
private final PowerManager.WakeLock mWakeLock;
@@ -112,7 +111,7 @@ public class NetworkTimeUpdateService extends Binder {
mContext = context;
mTime = NtpTrustedTime.getInstance(context);
mAlarmManager = mContext.getSystemService(AlarmManager.class);
- mTimeDetector = mContext.getSystemService(TimeDetector.class);
+ mTimeDetectorInternal = LocalServices.getService(TimeDetectorInternal.class);
mCM = mContext.getSystemService(ConnectivityManager.class);
Intent pollIntent = new Intent(ACTION_POLL, null);
@@ -196,15 +195,12 @@ public class NetworkTimeUpdateService extends Binder {
* Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
* test value, i.e. so the normal value will be used next time.
*/
- void setServerConfigForTests(
- @Nullable String hostname, @Nullable Integer port, @Nullable Duration timeout) {
+ void setServerConfigForTests(@Nullable NtpTrustedTime.NtpConfig ntpConfig) {
mContext.enforceCallingPermission(
android.Manifest.permission.SET_TIME, "set NTP server config for tests");
- mLocalLog.log("Setting server config for tests: hostname=" + hostname
- + ", port=" + port
- + ", timeout=" + timeout);
- mTime.setServerConfigForTests(hostname, port, timeout);
+ mLocalLog.log("Setting server config for tests: ntpConnectionInfo=" + ntpConfig);
+ mTime.setServerConfigForTests(ntpConfig);
}
private void onPollNetworkTime(int event) {
@@ -272,9 +268,11 @@ public class NetworkTimeUpdateService extends Binder {
private void makeNetworkTimeSuggestion(TimeResult ntpResult, String debugInfo) {
TimestampedValue<Long> timeSignal = new TimestampedValue<>(
ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
- NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
+ NetworkTimeSuggestion timeSuggestion =
+ new NetworkTimeSuggestion(timeSignal, ntpResult.getUncertaintyMillis());
timeSuggestion.addDebugInfo(debugInfo);
- mTimeDetector.suggestNetworkTime(timeSuggestion);
+ timeSuggestion.addDebugInfo(ntpResult.toString());
+ mTimeDetectorInternal.suggestNetworkTime(timeSuggestion);
}
/**
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
index 18dda55c4270..c8636b9943af 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateServiceShellCommand.java
@@ -18,8 +18,11 @@ package com.android.server.timedetector;
import android.annotation.NonNull;
import android.os.ShellCommand;
+import android.util.NtpTrustedTime;
import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.time.Duration;
import java.util.Objects;
@@ -42,13 +45,18 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
/**
- * A shell command that sets the NTP server config for tests. Config is cleared on reboot.
+ * A shell command that sets the NTP server config for tests. Config is cleared on reboot or
+ * using {@link #SHELL_COMMAND_RESET_SERVER_CONFIG}.
*/
- private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config";
- private static final String SET_SERVER_CONFIG_HOSTNAME_ARG = "--hostname";
- private static final String SET_SERVER_CONFIG_PORT_ARG = "--port";
+ private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config_for_tests";
+ private static final String SET_SERVER_CONFIG_SERVER_ARG = "--server";
private static final String SET_SERVER_CONFIG_TIMEOUT_ARG = "--timeout_millis";
+ /**
+ * A shell command that resets the NTP server config for tests.
+ */
+ private static final String SHELL_COMMAND_RESET_SERVER_CONFIG = "reset_server_config_for_tests";
+
@NonNull
private final NetworkTimeUpdateService mNetworkTimeUpdateService;
@@ -69,6 +77,8 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
return runForceRefresh();
case SHELL_COMMAND_SET_SERVER_CONFIG:
return runSetServerConfig();
+ case SHELL_COMMAND_RESET_SERVER_CONFIG:
+ return runResetServerConfig();
default: {
return handleDefaultCommands(cmd);
}
@@ -87,18 +97,17 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
}
private int runSetServerConfig() {
- String hostname = null;
- Integer port = null;
+ URI serverUri = null;
Duration timeout = null;
String opt;
while ((opt = getNextArg()) != null) {
switch (opt) {
- case SET_SERVER_CONFIG_HOSTNAME_ARG: {
- hostname = getNextArgRequired();
- break;
- }
- case SET_SERVER_CONFIG_PORT_ARG: {
- port = Integer.parseInt(getNextArgRequired());
+ case SET_SERVER_CONFIG_SERVER_ARG: {
+ try {
+ serverUri = NtpTrustedTime.parseNtpUriStrict(getNextArgRequired());
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException("Bad NTP server value", e);
+ }
break;
}
case SET_SERVER_CONFIG_TIMEOUT_ARG: {
@@ -110,7 +119,23 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
}
}
}
- mNetworkTimeUpdateService.setServerConfigForTests(hostname, port, timeout);
+
+ if (serverUri == null) {
+ throw new IllegalArgumentException(
+ "Missing required option: --" + SET_SERVER_CONFIG_SERVER_ARG);
+ }
+ if (timeout == null) {
+ throw new IllegalArgumentException(
+ "Missing required option: --" + SET_SERVER_CONFIG_TIMEOUT_ARG);
+ }
+
+ NtpTrustedTime.NtpConfig ntpConfig = new NtpTrustedTime.NtpConfig(serverUri, timeout);
+ mNetworkTimeUpdateService.setServerConfigForTests(ntpConfig);
+ return 0;
+ }
+
+ private int runResetServerConfig() {
+ mNetworkTimeUpdateService.setServerConfigForTests(null);
return 0;
}
@@ -126,11 +151,13 @@ class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
pw.printf(" Refreshes the latest time. Prints whether it was successful.\n");
pw.printf(" %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
pw.printf(" Sets the NTP server config for tests. The config is not persisted.\n");
- pw.printf(" Options: [%s <hostname>] [%s <port>] [%s <millis>]\n",
- SET_SERVER_CONFIG_HOSTNAME_ARG, SET_SERVER_CONFIG_PORT_ARG,
- SET_SERVER_CONFIG_TIMEOUT_ARG);
- pw.printf(" Each key/value is optional and must be specified to override the\n");
- pw.printf(" normal value, not specifying a key causes it to reset to the original.\n");
+ pw.printf(" Options: %s <uri> %s <millis>\n",
+ SET_SERVER_CONFIG_SERVER_ARG, SET_SERVER_CONFIG_TIMEOUT_ARG);
+ pw.printf(" The URI must be in the form \"ntp://hostname\" or"
+ + " \"ntp://hostname:port\"");
+ pw.printf(" %s\n", SHELL_COMMAND_RESET_SERVER_CONFIG);
+ pw.printf(" Resets/clears the NTP server config set via %s.\n",
+ SHELL_COMMAND_SET_SERVER_CONFIG);
pw.println();
}
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
index 181f5adee55f..eae12c28d2b9 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternal.java
@@ -16,6 +16,8 @@
package com.android.server.timedetector;
+import android.annotation.NonNull;
+
/**
* The internal (in-process) system server API for the {@link
* com.android.server.timedetector.TimeDetectorService}.
@@ -25,4 +27,9 @@ package com.android.server.timedetector;
*/
public interface TimeDetectorInternal {
-}
+ /** Used to pass new network time suggestions to the time detector. */
+ void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal);
+
+ /** Used to pass new GNSS time suggestions to the time detector. */
+ void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal);
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
index 1b47ebb3caaa..5a3e20ebd6cd 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorInternalImpl.java
@@ -39,4 +39,18 @@ public class TimeDetectorInternalImpl implements TimeDetectorInternal {
mHandler = Objects.requireNonNull(handler);
mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
}
+
+ @Override
+ public void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
+ Objects.requireNonNull(timeSignal);
+
+ mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
+ }
+
+ @Override
+ public void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
+ Objects.requireNonNull(timeSignal);
+
+ mHandler.post(() -> mTimeDetectorStrategy.suggestGnssTime(timeSignal));
+ }
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 02d3487ac431..5c47abfff09e 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -24,10 +24,8 @@ import android.app.time.ExternalTimeSuggestion;
import android.app.time.ITimeDetectorListener;
import android.app.time.TimeCapabilitiesAndConfig;
import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ITimeDetectorService;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.app.timedetector.TimePoint;
import android.content.Context;
@@ -295,16 +293,14 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub
}
}
- @Override
- public void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
+ void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
enforceSuggestNetworkTimePermission();
Objects.requireNonNull(timeSignal);
mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
}
- @Override
- public void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
+ void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
enforceSuggestGnssTimePermission();
Objects.requireNonNull(timeSignal);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
index 211ebe4fbb09..d306d10f3c69 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
@@ -30,9 +30,7 @@ import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_ORIG
import android.app.time.ExternalTimeSuggestion;
import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.os.ShellCommand;
import android.os.UserHandle;
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index cec383ce77be..141cdcf0dbb9 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -20,9 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.os.TimestampedValue;
import android.util.IndentingPrintWriter;
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index ecbf1f88c120..017306a5039d 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -25,9 +25,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AlarmManager;
import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.content.Context;
import android.os.Handler;
diff --git a/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java b/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
index f4a6ef0bf25c..8218fa5c4643 100644
--- a/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
+++ b/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
@@ -189,6 +189,10 @@ public final class GeolocationTimeZoneSuggestion {
}
}
+ if (zoneIdsString == null) {
+ throw new IllegalArgumentException("Missing --zone_ids");
+ }
+
long elapsedRealtimeMillis = SystemClock.elapsedRealtime();
List<String> zoneIds = parseZoneIdsArg(zoneIdsString);
GeolocationTimeZoneSuggestion suggestion =
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 80ce70de2138..e00e02999b0c 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -1666,10 +1666,9 @@ public class TrustManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.TRUST_LISTENER)
@Override
public boolean isTrustUsuallyManaged(int userId) {
- mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
- "query trust state");
return isTrustUsuallyManagedInternal(userId);
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index 220e347529a4..79ae66250a63 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -16,8 +16,6 @@
package com.android.server.wm;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-
import static com.android.server.wm.utils.RegionUtils.forEachRect;
import android.annotation.NonNull;
@@ -846,17 +844,8 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
windowInfo.token = window.mWindow.asBinder();
windowInfo.hasFlagWatchOutsideTouch = (window.mInputConfig
& InputConfig.WATCH_OUTSIDE_TOUCH) != 0;
- windowInfo.inPictureInPicture = false;
-
- // There only are two windowless windows now, one is split window, and the other
- // one is PIP.
- if (windowInfo.type == TYPE_DOCK_DIVIDER) {
- windowInfo.title = "Splitscreen Divider";
- } else if (window.mIsPIPMenu) {
- windowInfo.title = "Picture-in-Picture menu";
- // Set it to true to be consistent with the legacy implementation.
- windowInfo.inPictureInPicture = true;
- }
+ // Set it to true to be consistent with the legacy implementation.
+ windowInfo.inPictureInPicture = window.mIsPIPMenu;
return windowInfo;
}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 270891fcf421..a21919cdb960 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -149,6 +149,12 @@ class ActivityMetricsLogger {
private static final long UNKNOWN_VISIBILITY_CHECK_DELAY_MS = 3000;
/**
+ * If the recents animation is finished before the delay since the window drawn, do not log the
+ * action because the duration is too small that may be just an accidentally touch.
+ */
+ private static final long LATENCY_TRACKER_RECENTS_DELAY_MS = 300;
+
+ /**
* The flag for {@link #notifyActivityLaunching} to skip associating a new launch with an active
* transition, in the case the launch is standalone (e.g. from recents).
*/
@@ -735,13 +741,10 @@ class ActivityMetricsLogger {
info.mWindowsDrawnDelayMs = info.calculateDelay(timestampNs);
info.mIsDrawn = true;
final TransitionInfoSnapshot infoSnapshot = new TransitionInfoSnapshot(info);
- if (info.mLoggedTransitionStarting) {
+ if (info.mLoggedTransitionStarting || (!r.mDisplayContent.mOpeningApps.contains(r)
+ && !r.mTransitionController.isCollecting(r))) {
done(false /* abort */, info, "notifyWindowsDrawn", timestampNs);
}
- if (r.mWmService.isRecentsAnimationTarget(r)) {
- r.mWmService.getRecentsAnimationController().logRecentsAnimationStartTime(
- info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs);
- }
return infoSnapshot;
}
@@ -786,12 +789,6 @@ class ActivityMetricsLogger {
info.mReason = activityToReason.valueAt(index);
info.mLoggedTransitionStarting = true;
if (info.mIsDrawn) {
- if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
- final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
- final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
- mLoggerHandler.post(() -> latencyTracker.logAction(
- LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
- }
done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
}
}
@@ -959,6 +956,9 @@ class ActivityMetricsLogger {
launchObserverNotifyActivityLaunchFinished(info, timestampNs);
}
logAppTransitionFinished(info, isHibernating != null ? isHibernating : false);
+ if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
+ logRecentsAnimationLatency(info);
+ }
}
mTransitionInfoList.remove(info);
}
@@ -1114,6 +1114,22 @@ class ActivityMetricsLogger {
Log.i(TAG, sb.toString());
}
+ private void logRecentsAnimationLatency(TransitionInfo info) {
+ final int duration = info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs;
+ final ActivityRecord r = info.mLastLaunchedActivity;
+ final long lastTopLossTime = r.topResumedStateLossTime;
+ final WindowManagerService wm = mSupervisor.mService.mWindowManager;
+ final Object controller = wm.getRecentsAnimationController();
+ mLoggerHandler.postDelayed(() -> {
+ if (lastTopLossTime != r.topResumedStateLossTime
+ || controller != wm.getRecentsAnimationController()) {
+ // Skip if the animation was finished in a short time.
+ return;
+ }
+ wm.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration);
+ }, LATENCY_TRACKER_RECENTS_DELAY_MS);
+ }
+
private static int getAppStartTransitionType(int tronType, boolean relaunched) {
if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index fa8ea76bf0d1..948db1f24a39 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -224,6 +224,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WIND
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.sEnableShellTransitions;
import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
@@ -1992,6 +1993,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (options.getLaunchIntoPipParams() != null) {
pictureInPictureArgs = options.getLaunchIntoPipParams();
+ if (sourceRecord != null) {
+ adjustPictureInPictureParamsIfNeeded(sourceRecord.getBounds());
+ }
}
mOverrideTaskTransition = options.getOverrideTaskTransition();
@@ -3149,15 +3153,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mWillCloseOrEnterPip = willCloseOrEnterPip;
}
- /**
- * Returns whether this {@link ActivityRecord} is considered closing. Conditions are either
- * 1. Is this app animating and was requested to be hidden
- * 2. App is delayed closing since it might enter PIP.
- */
- boolean isClosingOrEnteringPip() {
- return (isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_APP_TRANSITION)
- && !mVisibleRequested) || mWillCloseOrEnterPip;
+ boolean willCloseOrEnterPip() {
+ return mWillCloseOrEnterPip;
}
+
/**
* @return Whether AppOps allows this package to enter picture-in-picture.
*/
@@ -5272,12 +5271,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
final int windowsCount = mChildren.size();
+ // With Shell-Transition, the activity will running a transition when it is visible.
+ // It won't be included when fromTransition is true means the call from finishTransition.
+ final boolean runningAnimation = sEnableShellTransitions ? visible
+ : isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION);
for (int i = 0; i < windowsCount; i++) {
- mChildren.get(i).onAppVisibilityChanged(visible, isAnimating(PARENTS,
- ANIMATION_TYPE_APP_TRANSITION));
+ mChildren.get(i).onAppVisibilityChanged(visible, runningAnimation);
}
setVisible(visible);
setVisibleRequested(visible);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "commitVisibility: %s: visible=%b"
+ + " visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
+ this, isVisible(), mVisibleRequested, isInTransition(), runningAnimation,
+ Debug.getCallers(5));
if (!visible) {
stopFreezingScreen(true, true);
} else {
@@ -5300,9 +5306,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
task.dispatchTaskInfoChangedIfNeeded(false /* force */);
task = task.getParent().asTask();
}
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
- "commitVisibility: %s: visible=%b mVisibleRequested=%b", this,
- isVisible(), mVisibleRequested);
final DisplayContent displayContent = getDisplayContent();
displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
if (performLayout) {
@@ -9764,6 +9767,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
void setPictureInPictureParams(PictureInPictureParams p) {
pictureInPictureArgs.copyOnlySet(p);
+ adjustPictureInPictureParamsIfNeeded(getBounds());
getTask().getRootTask().onPictureInPictureParamsChanged();
}
@@ -9810,6 +9814,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return new Point(windowLayout.minWidth, windowLayout.minHeight);
}
+ /**
+ * Adjust the source rect hint in {@link #pictureInPictureArgs} by window bounds since
+ * it is relative to its root view (see also b/235599028).
+ * It is caller's responsibility to make sure this is called exactly once when we update
+ * {@link #pictureInPictureArgs} to avoid double offset.
+ */
+ private void adjustPictureInPictureParamsIfNeeded(Rect windowBounds) {
+ if (pictureInPictureArgs != null && pictureInPictureArgs.hasSourceBoundsHint()) {
+ pictureInPictureArgs.getSourceRectHint().offset(windowBounds.left, windowBounds.top);
+ }
+ }
+
static class Builder {
private final ActivityTaskManagerService mAtmService;
private WindowProcessController mCallerApp;
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 501d45f1d985..77d6097a9c69 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -19,7 +19,9 @@ package com.android.server.wm;
import static android.app.ActivityManager.START_CANCELED;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
@@ -29,6 +31,7 @@ import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.content.ComponentName;
@@ -46,6 +49,7 @@ import android.provider.Settings;
import android.util.Slog;
import android.util.SparseArray;
import android.view.RemoteAnimationAdapter;
+import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -536,6 +540,42 @@ public class ActivityStartController {
.execute();
}
+ boolean startExistingRecentsIfPossible(Intent intent, ActivityOptions options) {
+ final int activityType = mService.getRecentTasks().getRecentsComponent()
+ .equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME;
+ final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea()
+ .getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
+ if (rootTask == null) return false;
+ final ActivityRecord r = rootTask.topRunningActivity();
+ if (r == null || r.mVisibleRequested || !r.attachedToProcess()
+ || !r.mActivityComponent.equals(intent.getComponent())
+ // Recents keeps invisible while device is locked.
+ || r.mDisplayContent.isKeyguardLocked()) {
+ return false;
+ }
+ mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r);
+ final ActivityMetricsLogger.LaunchingState launchingState =
+ mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
+ final Task task = r.getTask();
+ mService.deferWindowLayout();
+ try {
+ task.mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_TO_FRONT,
+ 0 /* flags */, task, task /* readyGroupRef */,
+ options.getRemoteTransition(), null /* displayChange */);
+ r.mTransitionController.setTransientLaunch(r,
+ TaskDisplayArea.getRootTaskAbove(rootTask));
+ task.moveToFront("startExistingRecents");
+ task.mInResumeTopActivity = true;
+ task.resumeTopActivity(null /* prev */, options, true /* deferPause */);
+ mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
+ ActivityManager.START_TASK_TO_FRONT, false, r, options);
+ } finally {
+ task.mInResumeTopActivity = false;
+ mService.continueWindowLayout();
+ }
+ return true;
+ }
+
void registerRemoteAnimationForNextActivityStart(String packageName,
RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 9b1c6bbd9a3a..59dbf2223506 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -201,8 +201,6 @@ class ActivityStarter {
@VisibleForTesting
boolean mAddingToTask;
- private ActivityInfo mNewTaskInfo;
- private Intent mNewTaskIntent;
private Task mSourceRootTask;
private Task mTargetRootTask;
// The task that the last activity was started into. We currently reset the actual start
@@ -613,8 +611,6 @@ class ActivityStarter {
mInTaskFragment = starter.mInTaskFragment;
mAddingToTask = starter.mAddingToTask;
- mNewTaskInfo = starter.mNewTaskInfo;
- mNewTaskIntent = starter.mNewTaskIntent;
mSourceRootTask = starter.mSourceRootTask;
mTargetTask = starter.mTargetTask;
@@ -1819,9 +1815,6 @@ class ActivityStarter {
voiceSession, voiceInteractor, restrictedBgActivity);
computeLaunchingTaskFlags();
-
- computeSourceRootTask();
-
mIntent.setFlags(mLaunchFlags);
boolean dreamStopping = false;
@@ -2413,8 +2406,6 @@ class ActivityStarter {
mInTaskFragment = null;
mAddingToTask = false;
- mNewTaskInfo = null;
- mNewTaskIntent = null;
mSourceRootTask = null;
mTargetRootTask = null;
@@ -2448,6 +2439,7 @@ class ActivityStarter {
mOptions = options;
mCallingUid = r.launchedFromUid;
mSourceRecord = sourceRecord;
+ mSourceRootTask = mSourceRecord != null ? mSourceRecord.getRootTask() : null;
mVoiceSession = voiceSession;
mVoiceInteractor = voiceInteractor;
mRestrictedBgActivity = restrictedBgActivity;
@@ -2565,7 +2557,6 @@ class ActivityStarter {
mInTask = null;
}
mInTaskFragment = inTaskFragment;
- sendNewTaskFragmentResultRequestIfNeeded();
mStartFlags = startFlags;
// If the onlyIfNeeded flag is set, then we can do this if the activity being launched
@@ -2608,18 +2599,6 @@ class ActivityStarter {
}
}
- private void sendNewTaskFragmentResultRequestIfNeeded() {
- if (mStartActivity.resultTo != null && mInTaskFragment != null
- && mInTaskFragment != mStartActivity.resultTo.getTaskFragment()) {
- Slog.w(TAG,
- "Activity is launching as a new TaskFragment, so cancelling activity result.");
- mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
- mStartActivity.requestCode, RESULT_CANCELED,
- null /* data */, null /* dataGrants */);
- mStartActivity.resultTo = null;
- }
- }
-
private void computeLaunchingTaskFlags() {
// If the caller is not coming from another activity, but has given us an explicit task into
// which they would like us to launch the new activity, then let's see about doing that.
@@ -2708,39 +2687,6 @@ class ActivityStarter {
}
}
- private void computeSourceRootTask() {
- if (mSourceRecord == null) {
- mSourceRootTask = null;
- return;
- }
- if (!mSourceRecord.finishing) {
- mSourceRootTask = mSourceRecord.getRootTask();
- return;
- }
-
- // If the source is finishing, we can't further count it as our source. This is because the
- // task it is associated with may now be empty and on its way out, so we don't want to
- // blindly throw it in to that task. Instead we will take the NEW_TASK flow and try to find
- // a task for it. But save the task information so it can be used when creating the new task.
- if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
- Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
- + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
- mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
-
- // It is not guaranteed that the source record will have a task associated with it.
- // For example, if this method is being called for processing a pending activity
- // launch, it is possible that the activity has been removed from the task after the
- // launch was enqueued.
- final Task sourceTask = mSourceRecord.getTask();
- if (sourceTask == null || sourceTask.getTopNonFinishingActivity() == null) {
- mNewTaskInfo = mSourceRecord.info;
- mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
- }
- }
- mSourceRecord = null;
- mSourceRootTask = null;
- }
-
/**
* Decide whether the new activity should be inserted into an existing task. Returns null
* if not or an ActivityRecord with the task into which the new activity should be added.
@@ -2934,8 +2880,7 @@ class ActivityStarter {
private void setNewTask(Task taskToAffiliate) {
final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
final Task task = mTargetRootTask.reuseOrCreateTask(
- mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
- mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
+ mStartActivity.info, mIntent, mVoiceSession,
mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
task.mTransitionController.collectExistenceChange(task);
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask");
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 6de1b95999d0..a773dbeb7b08 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1231,6 +1231,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
+
+ final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
+ // A quick path (skip general intent/task resolving) to start recents animation if the
+ // recents (or home) activity is available in background.
+ if (opts != null && opts.getOriginalOptions().getTransientLaunch()
+ && isCallerRecents(Binder.getCallingUid())) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
+ if (mActivityStartController.startExistingRecentsIfPossible(
+ intent, opts.getOriginalOptions())) {
+ return ActivityManager.START_TASK_TO_FRONT;
+ }
+ // Else follow the standard launch procedure.
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
@@ -1257,7 +1279,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
- .setActivityOptions(bOptions)
+ .setActivityOptions(opts)
.setUserId(userId)
.execute();
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 2e1d3b1643ac..0af046281cc5 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -120,7 +120,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
} else {
mTransitionOp = OP_CHANGE;
}
- } else if (transitionType != WindowManager.TRANSIT_NONE) {
+ } else if (displayContent.mTransitionController.isShellTransitionsEnabled()) {
mTransitionOp = OP_APP_SWITCH;
} else {
mTransitionOp = OP_LEGACY;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6619f985df58..7ffa55f1dc81 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1363,7 +1363,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
@Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
- setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
+ setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
}
/**
@@ -1372,15 +1372,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* @param type The type of inset this window provides.
* @param win The window.
* @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
- * the window should be taken.
- * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
- * {@code null} if the normal frame should be taken.
+ * the window should be taken. Only for non-WindowState providers, nav bar
+ * and status bar.
+ * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
+ * given window types, or {@code null} if the normal frame should
+ * be taken.
*/
void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
@Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
- @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+ @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+ overrideFrameProviders) {
mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
- imeFrameProvider);
+ overrideFrameProviders);
}
InsetsStateController getInsetsStateController() {
@@ -1685,7 +1688,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return false;
}
}
- if (r.isState(RESUMED) && !r.getRootTask().mInResumeTopActivity) {
+ if (r.isState(RESUMED) && !r.getTask().mInResumeTopActivity) {
// If the activity is executing or has done the lifecycle callback, use normal
// rotation animation so the display info can be updated immediately (see
// updateDisplayAndOrientation). This prevents a compatibility issue such as
@@ -3866,7 +3869,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
}
mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
- mDisplayPolicy.getImeSourceFrameProvider(), null /* imeFrameProvider */);
+ mDisplayPolicy.getImeSourceFrameProvider(), null);
computeImeTarget(true /* updateImeTarget */);
updateImeControlTarget();
}
@@ -4811,16 +4814,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final Bitmap bitmap = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
if (bitmap == null) {
Slog.w(TAG_WM, "Failed to take screenshot");
- return null;
- }
-
- // Create a copy of the screenshot that is immutable and backed in ashmem.
- // This greatly reduces the overhead of passing the bitmap between processes.
- final Bitmap ret = bitmap.asShared();
- if (ret != bitmap) {
- bitmap.recycle();
}
- return ret;
+ return bitmap;
}
@Override
@@ -5681,7 +5676,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) {
final Matrix tmpMatrix = new Matrix();
final float[] tmpFloat9 = new float[9];
+ final RecentsAnimationController recentsAnimationController =
+ mWmService.getRecentsAnimationController();
forAllWindows(w -> {
+ // Skip the window if it is part of Recents animation
+ final boolean ignoreRecentsAnimationTarget = recentsAnimationController != null
+ && recentsAnimationController.shouldApplyInputConsumer(w.getActivityRecord());
+ if (ignoreRecentsAnimationTarget) {
+ return false; // continue traversal
+ }
+
if (w.isVisible() && !w.inPinnedWindowingMode()) {
w.getKeepClearAreas(outRestricted, outUnrestricted, tmpMatrix, tmpFloat9);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 95f76180c600..98a51a97110d 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -46,9 +46,9 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -1156,7 +1156,7 @@ public class DisplayPolicy {
break;
case TYPE_NAVIGATION_BAR:
mNavigationBar = win;
- mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+ final TriConsumer<DisplayFrames, WindowContainer, Rect> navFrameProvider =
(displayFrames, windowContainer, inOutFrame) -> {
if (!mNavButtonForcedVisible) {
final LayoutParams lp =
@@ -1166,19 +1166,22 @@ public class DisplayPolicy {
if (provider.type != ITYPE_NAVIGATION_BAR) {
continue;
}
- calculateInsetsFrame(displayFrames, win, inOutFrame,
- provider.source, provider.insetsSize,
- lp.privateFlags, lp.gravity
- );
+ InsetsFrameProvider.calculateInsetsFrame(
+ displayFrames.mUnrestricted,
+ win.getBounds(), displayFrames.mDisplayCutoutSafe,
+ inOutFrame, provider.source,
+ provider.insetsSize, lp.privateFlags);
}
}
inOutFrame.inset(win.mGivenContentInsets);
}
- },
-
- (displayFrames, windowContainer, inOutFrame) -> {
- // For IME, we don't modify the frame.
- });
+ };
+ final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverride =
+ new SparseArray<>();
+ // For IME, we don't modify the frame.
+ imeOverride.put(TYPE_INPUT_METHOD, null);
+ mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
+ navFrameProvider, imeOverride);
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_MANDATORY_GESTURES, win,
(displayFrames, windowContainer, inOutFrame) -> {
@@ -1246,25 +1249,48 @@ public class DisplayPolicy {
final LayoutParams lp =
win.mAttrs.forRotation(displayFrames.mRotation);
final InsetsFrameProvider ifp =
- lp.providedInsets[index];
- calculateInsetsFrame(displayFrames, windowContainer,
- inOutFrame, ifp.source, ifp.insetsSize,
- lp.privateFlags, lp.gravity);
- } : null;
- final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
- provider.imeInsetsSize != null
- ? (displayFrames, windowContainer, inOutFrame) -> {
- inOutFrame.inset(win.mGivenContentInsets);
- final LayoutParams lp =
- win.mAttrs.forRotation(displayFrames.mRotation);
- final InsetsFrameProvider ifp =
- lp.providedInsets[index];
- calculateInsetsFrame(displayFrames, windowContainer,
- inOutFrame, ifp.source, ifp.imeInsetsSize,
- lp.privateFlags, lp.gravity);
+ win.mAttrs.forRotation(displayFrames.mRotation)
+ .providedInsets[index];
+ InsetsFrameProvider.calculateInsetsFrame(
+ displayFrames.mUnrestricted,
+ windowContainer.getBounds(),
+ displayFrames.mDisplayCutoutSafe,
+ inOutFrame, ifp.source,
+ ifp.insetsSize, lp.privateFlags);
} : null;
+ final InsetsFrameProvider.InsetsSizeOverride[] overrides =
+ provider.insetsSizeOverrides;
+ final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+ overrideProviders;
+ if (overrides != null) {
+ overrideProviders = new SparseArray<>();
+ for (int j = overrides.length - 1; j >= 0; j--) {
+ final int overrideIndex = j;
+ final TriConsumer<DisplayFrames, WindowContainer, Rect>
+ overrideFrameProvider =
+ (displayFrames, windowContainer, inOutFrame) -> {
+ final LayoutParams lp =
+ win.mAttrs.forRotation(
+ displayFrames.mRotation);
+ final InsetsFrameProvider ifp =
+ win.mAttrs.providedInsets[index];
+ InsetsFrameProvider.calculateInsetsFrame(
+ displayFrames.mUnrestricted,
+ windowContainer.getBounds(),
+ displayFrames.mDisplayCutoutSafe,
+ inOutFrame, ifp.source,
+ ifp.insetsSizeOverrides[
+ overrideIndex].insetsSize,
+ lp.privateFlags);
+ };
+ overrideProviders.put(overrides[j].windowType,
+ overrideFrameProvider);
+ }
+ } else {
+ overrideProviders = null;
+ }
mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
- imeFrameProvider);
+ overrideProviders);
mInsetsSourceWindowsExceptIme.add(win);
}
}
@@ -1272,40 +1298,6 @@ public class DisplayPolicy {
}
}
- private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
- int source, Insets insetsSize, @LayoutParams.PrivateFlags int privateFlags,
- int windowGravity) {
- boolean extendByCutout = false;
- if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
- inOutFrame.set(df.mUnrestricted);
- } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
- inOutFrame.set(container.getBounds());
- } else {
- extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
- }
- if (insetsSize == null) {
- return;
- }
- // Only one side of the provider shall be applied. Check in the order of left - top -
- // right - bottom, only the first non-zero value will be applied.
- if (insetsSize.left != 0) {
- inOutFrame.right = inOutFrame.left + insetsSize.left;
- } else if (insetsSize.top != 0) {
- inOutFrame.bottom = inOutFrame.top + insetsSize.top;
- } else if (insetsSize.right != 0) {
- inOutFrame.left = inOutFrame.right - insetsSize.right;
- } else if (insetsSize.bottom != 0) {
- inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
- } else {
- inOutFrame.setEmpty();
- }
-
- if (extendByCutout) {
- WindowLayout.extendFrameByCutout(windowGravity, df.mDisplayCutoutSafe,
- df.mUnrestricted, inOutFrame, sTmpRect);
- }
- }
-
@WindowManagerPolicy.AltBarPosition
private int getAltBarPosition(WindowManager.LayoutParams params) {
switch (params.gravity) {
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 0d4cfa3a8128..3e6e06a27fdc 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -234,7 +234,7 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider
//
private static boolean isImeLayeringTarget(@NonNull InsetsControlTarget target,
@NonNull InsetsControlTarget dcTarget) {
- return !dcTarget.getWindow().isClosing() && target == dcTarget;
+ return !isImeTargetWindowClosing(dcTarget.getWindow()) && target == dcTarget;
}
private static boolean isAboveImeLayeringTarget(@NonNull InsetsControlTarget target,
@@ -256,7 +256,14 @@ final class ImeInsetsSourceProvider extends WindowContainerInsetsSourceProvider
final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
return target == mImeRequester
&& (mImeRequester.getWindow() == null
- || !mImeRequester.getWindow().isClosing());
+ || !isImeTargetWindowClosing(mImeRequester.getWindow()));
+ }
+
+ private static boolean isImeTargetWindowClosing(@NonNull WindowState win) {
+ return win.mAnimatingExit || win.mActivityRecord != null
+ && (win.mActivityRecord.isInTransition()
+ && !win.mActivityRecord.isVisibleRequested()
+ || win.mActivityRecord.willCloseOrEnterPip());
}
private boolean isTargetChangedWithinActivity(InsetsControlTarget target) {
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index b7ddbd070460..33cdd2e98113 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -265,7 +265,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
.setContainerLayer()
.setName(name)
.setCallsite("createSurfaceForGestureMonitor")
- .setParent(dc.getOverlayLayer())
+ .setParent(dc.getSurfaceControl())
.build();
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index ee1ff2cd61ff..620a56d18dcd 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -289,7 +289,7 @@ class InsetsPolicy {
// contains all insets types.
final InsetsState originalState = mDisplayContent.getInsetsPolicy()
.enforceInsetsPolicyForTarget(type, WINDOWING_MODE_FULLSCREEN, alwaysOnTop,
- mStateController.getRawInsetsState());
+ attrs.type, mStateController.getRawInsetsState());
InsetsState state = adjustVisibilityForTransientTypes(originalState);
return adjustInsetsForRoundedCorners(token, state, state == originalState);
}
@@ -351,12 +351,13 @@ class InsetsPolicy {
* @param type the inset type provided by the target
* @param windowingMode the windowing mode of the target
* @param isAlwaysOnTop is the target always on top
+ * @param windowType the type of the target
* @param state the input inset state containing all the sources
* @return The state stripped of the necessary information.
*/
InsetsState enforceInsetsPolicyForTarget(@InternalInsetsType int type,
@WindowConfiguration.WindowingMode int windowingMode, boolean isAlwaysOnTop,
- InsetsState state) {
+ int windowType, InsetsState state) {
boolean stateCopied = false;
if (type != ITYPE_INVALID) {
@@ -377,21 +378,20 @@ class InsetsPolicy {
if (type == ITYPE_STATUS_BAR || type == ITYPE_CLIMATE_BAR) {
state.removeSource(ITYPE_CAPTION_BAR);
}
-
- // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
- if (type == ITYPE_IME) {
- ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
- .getSourceProviders();
- for (int i = providers.size() - 1; i >= 0; i--) {
- WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
- if (otherProvider.overridesImeFrame()) {
- InsetsSource override =
- new InsetsSource(
- state.getSource(otherProvider.getSource().getType()));
- override.setFrame(otherProvider.getImeOverrideFrame());
- state.addSource(override);
- }
+ }
+ ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
+ .getSourceProviders();
+ for (int i = providers.size() - 1; i >= 0; i--) {
+ WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
+ if (otherProvider.overridesFrame(windowType)) {
+ if (!stateCopied) {
+ state = new InsetsState(state);
+ stateCopied = true;
}
+ InsetsSource override =
+ new InsetsSource(state.getSource(otherProvider.getSource().getType()));
+ override.setFrame(otherProvider.getOverriddenFrame(windowType));
+ state.addSource(override);
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 610bf0594c66..86a73c935e52 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -27,7 +27,6 @@ import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET;
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
-import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME;
import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET;
import static com.android.server.wm.InsetsSourceProviderProto.SEAMLESS_ROTATING;
@@ -41,6 +40,7 @@ import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
+import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsFrameProvider;
import android.view.InsetsSource;
@@ -78,8 +78,8 @@ abstract class InsetsSourceProvider {
private @Nullable ControlAdapter mAdapter;
private TriConsumer<DisplayFrames, WindowContainer, Rect> mFrameProvider;
- private TriConsumer<DisplayFrames, WindowContainer, Rect> mImeFrameProvider;
- private final Rect mImeOverrideFrame = new Rect();
+ private SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> mOverrideFrameProviders;
+ private final SparseArray<Rect> mOverrideFrames = new SparseArray<Rect>();
private boolean mIsLeashReadyForDispatching;
private final Rect mSourceFrame = new Rect();
private final Rect mLastSourceFrame = new Rect();
@@ -146,12 +146,15 @@ abstract class InsetsSourceProvider {
* @param windowContainer The window container that links to this source.
* @param frameProvider Based on display frame state and the window, calculates the resulting
* frame that should be reported to clients.
- * @param imeFrameProvider Based on display frame state and the window, calculates the resulting
- * frame that should be reported to IME.
+ * This will only be used when the window container providing the insets is
+ * not a WindowState.
+ * @param overrideFrameProviders Based on display frame state and the window, calculates the
+ * resulting frame that should be reported to given window type.
*/
void setWindowContainer(@Nullable WindowContainer windowContainer,
@Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
- @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider) {
+ @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
+ overrideFrameProviders) {
if (mWindowContainer != null) {
if (mControllable) {
mWindowContainer.setControllableInsetProvider(null);
@@ -167,8 +170,9 @@ abstract class InsetsSourceProvider {
ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource setWin %s for type %s",
windowContainer, InsetsState.typeToString(mSource.getType()));
mWindowContainer = windowContainer;
+ // TODO: remove the frame provider for non-WindowState container.
mFrameProvider = frameProvider;
- mImeFrameProvider = imeFrameProvider;
+ mOverrideFrameProviders = overrideFrameProviders;
if (windowContainer == null) {
setServerVisible(false);
mSource.setVisibleFrame(null);
@@ -228,10 +232,25 @@ abstract class InsetsSourceProvider {
}
updateSourceFrameForServerVisibility();
- if (mImeFrameProvider != null) {
- mImeOverrideFrame.set(frame);
- mImeFrameProvider.accept(mWindowContainer.getDisplayContent().mDisplayFrames,
- mWindowContainer, mImeOverrideFrame);
+ if (mOverrideFrameProviders != null) {
+ for (int i = mOverrideFrameProviders.size() - 1; i >= 0; i--) {
+ final int windowType = mOverrideFrameProviders.keyAt(i);
+ final Rect overrideFrame;
+ if (mOverrideFrames.contains(windowType)) {
+ overrideFrame = mOverrideFrames.get(windowType);
+ overrideFrame.set(frame);
+ } else {
+ overrideFrame = new Rect(frame);
+ }
+ final TriConsumer<DisplayFrames, WindowContainer, Rect> provider =
+ mOverrideFrameProviders.get(windowType);
+ if (provider != null) {
+ mOverrideFrameProviders.get(windowType).accept(
+ mWindowContainer.getDisplayContent().mDisplayFrames, mWindowContainer,
+ overrideFrame);
+ }
+ mOverrideFrames.put(windowType, overrideFrame);
+ }
}
if (win.mGivenVisibleInsets.left != 0 || win.mGivenVisibleInsets.top != 0
@@ -552,32 +571,30 @@ abstract class InsetsSourceProvider {
return mClientVisible;
}
- /**
- * @return Whether this provider uses a different frame to dispatch to the IME.
- */
- boolean overridesImeFrame() {
- return mImeFrameProvider != null;
+ boolean overridesFrame(int windowType) {
+ return mOverrideFrames.contains(windowType);
}
- /**
- * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()}
- * returns {@code true}.
- */
- Rect getImeOverrideFrame() {
- return mImeOverrideFrame;
+ Rect getOverriddenFrame(int windowType) {
+ return mOverrideFrames.get(windowType);
}
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + getClass().getSimpleName());
prefix = prefix + " ";
pw.print(prefix + "mSource="); mSource.dump("", pw);
+ pw.print(prefix + "mSourceFrame=");
+ pw.println(mSourceFrame);
+ if (mOverrideFrames.size() > 0) {
+ pw.print(prefix + "mOverrideFrames=");
+ pw.println(mOverrideFrames);
+ }
if (mControl != null) {
pw.print(prefix + "mControl=");
mControl.dump("", pw);
}
pw.print(prefix);
pw.print("mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
- pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toShortString());
pw.println();
if (mWindowContainer != null) {
pw.print(prefix + "mWindowContainer=");
@@ -621,7 +638,6 @@ abstract class InsetsSourceProvider {
if (mAdapter != null && mAdapter.mCapturedLeash != null) {
mAdapter.mCapturedLeash.dumpDebug(proto, CAPTURED_LEASH);
}
- mImeOverrideFrame.dumpDebug(proto, IME_OVERRIDDEN_FRAME);
proto.write(IS_LEASH_READY_FOR_DISPATCHING, mIsLeashReadyForDispatching);
proto.write(CLIENT_VISIBLE, mClientVisible);
proto.write(SERVER_VISIBLE, mServerVisible);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index d2ce048ca88f..e8a63d453004 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -71,9 +71,7 @@ import android.window.TaskSnapshot;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.LatencyTracker;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
@@ -99,11 +97,6 @@ import java.util.stream.Collectors;
public class RecentsAnimationController implements DeathRecipient {
private static final String TAG = RecentsAnimationController.class.getSimpleName();
private static final long FAILSAFE_DELAY = 1000;
- /**
- * If the recents animation is canceled before the delay since the window drawn, do not log the
- * action because the duration is too small that may be just a mistouch.
- */
- private static final long LATENCY_TRACKER_LOG_DELAY_MS = 300;
// Constant for a yet-to-be-calculated {@link RemoteAnimationTarget#Mode} state
private static final int MODE_UNKNOWN = -1;
@@ -144,7 +137,7 @@ public class RecentsAnimationController implements DeathRecipient {
private boolean mPendingStart = true;
// Set when the animation has been canceled
- private volatile boolean mCanceled;
+ private boolean mCanceled;
// Whether or not the input consumer is enabled. The input consumer must be both registered and
// enabled for it to start intercepting touch events.
@@ -785,15 +778,6 @@ public class RecentsAnimationController implements DeathRecipient {
}, false /* traverseTopToBottom */);
}
- void logRecentsAnimationStartTime(int durationMs) {
- BackgroundThread.getHandler().postDelayed(() -> {
- if (!mCanceled) {
- mService.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION,
- durationMs);
- }
- }, LATENCY_TRACKER_LOG_DELAY_MS);
- }
-
private boolean removeTaskInternal(int taskId) {
boolean result = false;
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index ac1a2b17603a..8db5289f8b45 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -71,6 +71,7 @@ class RemoteAnimationController implements DeathRecipient {
final ArrayList<NonAppWindowAnimationAdapter> mPendingNonAppAnimations = new ArrayList<>();
private final Handler mHandler;
private final Runnable mTimeoutRunnable = () -> cancelAnimation("timeoutRunnable");
+ private boolean mIsFinishing;
private FinishedCallback mFinishedCallback;
private final boolean mIsActivityEmbedding;
@@ -275,6 +276,7 @@ class RemoteAnimationController implements DeathRecipient {
mPendingAnimations.size());
mHandler.removeCallbacks(mTimeoutRunnable);
synchronized (mService.mGlobalLock) {
+ mIsFinishing = true;
unlinkToDeathOfRunner();
releaseFinishedCallback();
mService.openSurfaceTransaction();
@@ -319,6 +321,7 @@ class RemoteAnimationController implements DeathRecipient {
throw e;
} finally {
mService.closeSurfaceTransaction("RemoteAnimationController#finished");
+ mIsFinishing = false;
}
}
// Reset input for all activities when the remote animation is finished.
@@ -558,6 +561,9 @@ class RemoteAnimationController implements DeathRecipient {
@Override
public void onAnimationCancelled(SurfaceControl animationLeash) {
+ if (mIsFinishing) {
+ return;
+ }
if (mRecord.mAdapter == this) {
mRecord.mAdapter = null;
} else {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index da3e56e60148..5a9058bc5898 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2116,7 +2116,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// entering content-pip animation.
mWindowManager.mTaskSnapshotController.recordTaskSnapshot(
task, false /* allowSnapshotHome */);
- rootTask.setBounds(r.getOptions().getLaunchBounds());
+ rootTask.setBounds(r.pictureInPictureArgs.getSourceRectHint());
}
rootTask.setDeferTaskAppear(false);
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 927604eaa32f..d92a1f495917 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_KEYGUARD;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
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;
@@ -249,6 +250,14 @@ public class SafeActivityOptions {
throw new SecurityException(msg);
}
}
+ if (options.getTransientLaunch() && !supervisor.mRecentTasks.isCallerRecents(callingUid)
+ && ActivityTaskManagerService.checkPermission(
+ MANAGE_ACTIVITY_TASKS, callingPid, callingUid) == PERMISSION_DENIED) {
+ final String msg = "Permission Denial: starting transient launch from " + callerApp
+ + ", pid=" + callingPid + ", uid=" + callingUid;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
// Check if the caller is allowed to launch on the specified display area.
final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
TaskDisplayArea taskDisplayArea = daToken != null
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index f80e732c8212..8cad16509c4c 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -173,11 +173,6 @@ class ScreenRotationAnimation {
if (isSizeChanged) {
mRoundedCornerOverlay = displayContent.findRoundedCornerOverlays();
- } else {
- // Exclude rounded corner overlay from screenshot buffer. Rounded
- // corner overlay windows are un-rotated during rotation animation
- // for a seamless transition.
- builder.setExcludeLayers(displayContent.findRoundedCornerOverlays());
}
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
@@ -600,7 +595,7 @@ class ScreenRotationAnimation {
}
private SurfaceAnimator startDisplayRotation() {
- return startAnimation(initializeBuilder()
+ SurfaceAnimator animator = startAnimation(initializeBuilder()
.setAnimationLeashParent(mDisplayContent.getSurfaceControl())
.setSurfaceControl(mDisplayContent.getWindowingLayer())
.setParentSurfaceControl(mDisplayContent.getSurfaceControl())
@@ -609,6 +604,13 @@ class ScreenRotationAnimation {
.build(),
createWindowAnimationSpec(mRotateEnterAnimation),
this::onAnimationEnd);
+
+ // Crop the animation leash to avoid extended wallpaper from showing over
+ // mBackColorSurface
+ Rect displayBounds = mDisplayContent.getBounds();
+ mDisplayContent.getPendingTransaction()
+ .setWindowCrop(animator.mLeash, displayBounds.width(), displayBounds.height());
+ return animator;
}
private SurfaceAnimator startScreenshotAlphaAnimation() {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 09f6110b517f..c455ac1dd370 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -533,9 +533,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
}
// Need to update layers on involved displays since they were all paused while
// the animation played. This puts the layers back into the correct order.
- for (int i = displays.size() - 1; i >= 0; --i) {
- if (displays.valueAt(i) == null) continue;
- displays.valueAt(i).assignChildLayers(t);
+ mController.mBuildingFinishLayers = true;
+ try {
+ for (int i = displays.size() - 1; i >= 0; --i) {
+ if (displays.valueAt(i) == null) continue;
+ displays.valueAt(i).assignChildLayers(t);
+ }
+ } finally {
+ mController.mBuildingFinishLayers = false;
}
if (rootLeash.isValid()) {
t.reparent(rootLeash, null);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index dbc2c5fb0ce3..88572a937156 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -100,6 +100,14 @@ class TransitionController {
// TODO(b/188595497): remove when not needed.
final StatusBarManagerInternal mStatusBar;
+ /**
+ * `true` when building surface layer order for the finish transaction. We want to prevent
+ * wm from touching z-order of surfaces during transitions, but we still need to be able to
+ * calculate the layers for the finishTransaction. So, when assigning layers into the finish
+ * transaction, set this to true so that the {@link canAssignLayers} will allow it.
+ */
+ boolean mBuildingFinishLayers = false;
+
TransitionController(ActivityTaskManagerService atm,
TaskSnapshotController taskSnapshotController,
TransitionTracer transitionTracer) {
@@ -309,6 +317,15 @@ class TransitionController {
return false;
}
+ /**
+ * Whether WM can assign layers to window surfaces at this time. This is usually false while
+ * playing, but can be "opened-up" for certain transition operations like calculating layers
+ * for finishTransaction.
+ */
+ boolean canAssignLayers() {
+ return mBuildingFinishLayers || !isPlaying();
+ }
+
@WindowConfiguration.WindowingMode
int getWindowingModeAtStart(@NonNull WindowContainer wc) {
if (mCollectingTransition == null) return wc.getWindowingMode();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 33b49823c620..bce131b6700b 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -429,6 +429,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
if (insetsTypes == null || insetsTypes.length == 0) {
throw new IllegalArgumentException("Insets type not specified.");
}
+ if (mDisplayContent == null) {
+ // This is possible this container is detached when WM shell is responding to a previous
+ // request. WM shell will be updated when this container is attached again and the
+ // insets need to be updated.
+ Slog.w(TAG, "Can't add local rect insets source provider when detached. " + this);
+ return;
+ }
if (mLocalInsetsSourceProviders == null) {
mLocalInsetsSourceProviders = new SparseArray<>();
}
@@ -1014,6 +1021,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
if (dc != null && dc != this) {
dc.getPendingTransaction().merge(mPendingTransaction);
}
+ if (dc != this && mLocalInsetsSourceProviders != null) {
+ mLocalInsetsSourceProviders.clear();
+ }
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer child = mChildren.get(i);
child.onDisplayChanged(dc);
@@ -2476,7 +2486,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
void assignLayer(Transaction t, int layer) {
// Don't assign layers while a transition animation is playing
// TODO(b/173528115): establish robust best-practices around z-order fighting.
- if (mTransitionController.isPlaying()) return;
+ if (!mTransitionController.canAssignLayers()) return;
final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
if (mSurfaceControl != null && changed) {
setLayer(t, layer);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6ffddd96ecd2..00e8d8bdaaec 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -46,7 +46,6 @@ import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDO
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
-import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH;
import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -652,7 +651,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Whether the system should use BLAST for ViewRootImpl
final boolean mUseBLAST;
// Whether to enable BLASTSyncEngine Transaction passing.
- final boolean mUseBLASTSync = true;
+ static final boolean USE_BLAST_SYNC = true;
final BLASTSyncEngine mSyncEngine;
@@ -787,8 +786,6 @@ public class WindowManagerService extends IWindowManager.Stub
DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
private final Uri mDevEnableNonResizableMultiWindowUri = Settings.Global.getUriFor(
DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW);
- private final Uri mRenderShadowsInCompositorUri = Settings.Global.getUriFor(
- DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
private final Uri mDisplaySettingsPathUri = Settings.Global.getUriFor(
DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
private final Uri mMaximumObscuringOpacityForTouchUri = Settings.Global.getUriFor(
@@ -1050,8 +1047,11 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mWindowsChanged = false;
public interface WindowChangeListener {
- public void windowsChanged();
- public void focusChanged();
+ /** Notify on windows changed */
+ void windowsChanged();
+
+ /** Notify on focus changed */
+ void focusChanged();
}
final HighRefreshRateDenylist mHighRefreshRateDenylist;
@@ -1201,7 +1201,8 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.bool.config_hasPermanentDpad);
mInTouchMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_defaultInTouchMode);
- inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, true /* hasPermission */);
+ inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, /* hasPermission= */ true,
+ DEFAULT_DISPLAY);
mDrawLockTimeoutMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_drawLockTimeoutMillis);
mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
@@ -2128,7 +2129,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
void clearTouchableRegion(Session session, IWindow client) {
- int uid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -2304,12 +2304,6 @@ public class WindowManagerService extends IWindowManager.Stub
|| (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
win.mActivityRecord.checkKeyguardFlagsChanged();
}
- if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0)
- && (mAccessibilityController.hasCallbacks())) {
- // No move or resize, but the controller checks for title changes as well
- mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid(
- uid, win.getDisplayContent().getDisplayId());
- }
if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
updateNonSystemOverlayWindowsVisibilityIfNeeded(
@@ -2546,7 +2540,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.mInRelayout = false;
- if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE
+ if (USE_BLAST_SYNC && win.useBLASTSync() && viewVisibility != View.GONE
&& (win.mSyncSeqId > win.mLastSeqIdSentToRelayout)) {
win.markRedrawForSyncReported();
@@ -3824,7 +3818,9 @@ public class WindowManagerService extends IWindowManager.Stub
/* printlog= */ false);
final long token = Binder.clearCallingIdentity();
try {
- if (mInputManager.setInTouchMode(mode, pid, uid, hasPermission)) {
+ // TODO(b/198499018): Add displayId parameter indicating the target display.
+ // For now, will just pass DEFAULT_DISPLAY for displayId.
+ if (mInputManager.setInTouchMode(mode, pid, uid, hasPermission, DEFAULT_DISPLAY)) {
mInTouchMode = mode;
}
} finally {
@@ -4319,7 +4315,7 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplayChangeController = controller;
}
} catch (RemoteException e) {
- throw new RuntimeException("Unable to set rotation controller");
+ throw new RuntimeException("Unable to set rotation controller", e);
}
}
@@ -5638,7 +5634,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
public boolean useBLASTSync() {
- return mUseBLASTSync;
+ return USE_BLAST_SYNC;
}
@Override
@@ -6498,12 +6494,12 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
+ private void dumpPolicyLocked(PrintWriter pw, String[] args) {
pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
mPolicy.dump(" ", pw, args);
}
- private void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
+ private void dumpAnimatorLocked(PrintWriter pw, boolean dumpAll) {
pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
mAnimator.dumpLocked(pw, " ", dumpAll);
}
@@ -6529,7 +6525,7 @@ public class WindowManagerService extends IWindowManager.Stub
pw.println(ProtoLogImpl.getSingleInstance().getStatus());
}
- private void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
+ private void dumpSessionsLocked(PrintWriter pw) {
pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
for (int i=0; i<mSessions.size(); i++) {
Session s = mSessions.valueAt(i);
@@ -6594,7 +6590,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mForceRemoves != null && mForceRemoves.size() > 0) {
+ if (mForceRemoves != null && !mForceRemoves.isEmpty()) {
pw.println();
pw.println(" Windows force removing:");
for (int i=mForceRemoves.size()-1; i>=0; i--) {
@@ -6609,7 +6605,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mDestroySurface.size() > 0) {
+ if (!mDestroySurface.isEmpty()) {
pw.println();
pw.println(" Windows waiting to destroy their surface:");
for (int i=mDestroySurface.size()-1; i>=0; i--) {
@@ -6626,7 +6622,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- if (mResizingWindows.size() > 0) {
+ if (!mResizingWindows.isEmpty()) {
pw.println();
pw.println(" Windows waiting to resize:");
for (int i=mResizingWindows.size()-1; i>=0; i--) {
@@ -6733,8 +6729,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti,
- boolean dumpAll) {
+ private boolean dumpWindows(PrintWriter pw, String name, boolean dumpAll) {
final ArrayList<WindowState> windows = new ArrayList();
if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
final boolean appsOnly = name.contains("apps");
@@ -6757,7 +6752,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- if (windows.size() <= 0) {
+ if (windows.isEmpty()) {
return false;
}
@@ -6888,17 +6883,17 @@ public class WindowManagerService extends IWindowManager.Stub
return;
} else if ("policy".equals(cmd) || "p".equals(cmd)) {
synchronized (mGlobalLock) {
- dumpPolicyLocked(pw, args, true);
+ dumpPolicyLocked(pw, args);
}
return;
} else if ("animator".equals(cmd) || "a".equals(cmd)) {
synchronized (mGlobalLock) {
- dumpAnimatorLocked(pw, args, true);
+ dumpAnimatorLocked(pw, true);
}
return;
} else if ("sessions".equals(cmd) || "s".equals(cmd)) {
synchronized (mGlobalLock) {
- dumpSessionsLocked(pw, true);
+ dumpSessionsLocked(pw);
}
return;
} else if ("displays".equals(cmd) || "d".equals(cmd)) {
@@ -6945,7 +6940,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
} else {
// Dumping a single name?
- if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
+ if (!dumpWindows(pw, cmd, dumpAll)) {
pw.println("Bad window command, or no windows match: " + cmd);
pw.println("Use -h for help.");
}
@@ -6965,17 +6960,17 @@ public class WindowManagerService extends IWindowManager.Stub
if (dumpAll) {
pw.println(separator);
}
- dumpPolicyLocked(pw, args, dumpAll);
+ dumpPolicyLocked(pw, args);
pw.println();
if (dumpAll) {
pw.println(separator);
}
- dumpAnimatorLocked(pw, args, dumpAll);
+ dumpAnimatorLocked(pw, dumpAll);
pw.println();
if (dumpAll) {
pw.println(separator);
}
- dumpSessionsLocked(pw, dumpAll);
+ dumpSessionsLocked(pw);
pw.println();
if (dumpAll) {
pw.println(separator);
@@ -8256,7 +8251,7 @@ public class WindowManagerService extends IWindowManager.Stub
.setContainerLayer()
.setName("IME Handwriting Surface")
.setCallsite("getHandwritingSurfaceForDisplay")
- .setParent(dc.getOverlayLayer())
+ .setParent(dc.getSurfaceControl())
.build();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 46091d842c2a..658b6acbc16d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -215,7 +215,6 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.WorkSource;
import android.provider.Settings;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
@@ -1703,7 +1702,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mFrozenInsetsState != null ? mFrozenInsetsState : getMergedInsetsState();
final InsetsState insetsStateForWindow = insetsPolicy
.enforceInsetsPolicyForTarget(insetTypeProvidedByWindow,
- getWindowingMode(), isAlwaysOnTop(), rawInsetsState);
+ getWindowingMode(), isAlwaysOnTop(), mAttrs.type, rawInsetsState);
return insetsPolicy.adjustInsetsForWindow(this, insetsStateForWindow,
includeTransient);
}
@@ -3461,10 +3460,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return mClient.asBinder().isBinderAlive();
}
- boolean isClosing() {
- return mAnimatingExit || (mActivityRecord != null && mActivityRecord.isClosingOrEnteringPip());
- }
-
void sendAppVisibilityToClients() {
super.sendAppVisibilityToClients();
@@ -4703,19 +4698,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mActivityRecord != null) {
windowInfo.activityToken = mActivityRecord.token;
}
- windowInfo.title = mAttrs.accessibilityTitle;
- // Panel windows have no public way to set the a11y title directly. Use the
- // regular title as a fallback.
- final boolean isPanelWindow = (mAttrs.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW)
- && (mAttrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW);
- // Accessibility overlays should have titles that work for accessibility, and can't set
- // the a11y title themselves.
- final boolean isAccessibilityOverlay =
- windowInfo.type == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
- if (TextUtils.isEmpty(windowInfo.title) && (isPanelWindow || isAccessibilityOverlay)) {
- final CharSequence title = mAttrs.getTitle();
- windowInfo.title = TextUtils.isEmpty(title) ? null : title;
- }
windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
windowInfo.focused = isFocused();
Task task = getTask();
@@ -5489,17 +5471,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
private void updateScaleIfNeeded() {
- if (mIsChildWindow) {
- // Child window follows parent's scale.
- return;
- }
if (!isVisibleRequested() && !(mIsWallpaper && mToken.isVisible())) {
// Skip if it is requested to be invisible, but if it is wallpaper, it may be in
// transition that still needs to update the scale for zoom effect.
return;
}
- float newHScale = mHScale * mGlobalScale * mWallpaperScale;
- float newVScale = mVScale * mGlobalScale * mWallpaperScale;
+ float globalScale = mGlobalScale;
+ final WindowState parent = getParentWindow();
+ if (parent != null) {
+ // Undo parent's scale because the child surface has inherited scale from parent.
+ globalScale *= parent.mInvGlobalScale;
+ }
+ final float newHScale = mHScale * globalScale * mWallpaperScale;
+ final float newVScale = mVScale * globalScale * mWallpaperScale;
if (mLastHScale != newHScale || mLastVScale != newVScale) {
getSyncTransaction().setMatrix(mSurfaceControl, newHScale, 0, 0, newVScale);
mLastHScale = newHScale;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 437c9344d793..bbb21f8122c5 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -362,7 +362,7 @@ class WindowToken extends WindowContainer<WindowState> {
@Override
void assignLayer(SurfaceControl.Transaction t, int layer) {
if (mRoundedCornerOverlay) {
- super.assignLayer(t, WindowManagerPolicy.SCREEN_DECOR_DISPLAY_OVERLAY_LAYER);
+ super.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
} else {
super.assignLayer(t, layer);
}
@@ -372,7 +372,7 @@ class WindowToken extends WindowContainer<WindowState> {
SurfaceControl.Builder makeSurface() {
final SurfaceControl.Builder builder = super.makeSurface();
if (mRoundedCornerOverlay) {
- builder.setParent(getDisplayContent().getOverlayLayer());
+ builder.setParent(null);
}
return builder;
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 2cd6cf3670c5..74ed3dfec7ba 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -133,6 +133,7 @@ static struct {
jmethodID getContextForDisplay;
jmethodID notifyDropWindow;
jmethodID getParentSurfaceForPointers;
+ jmethodID isPerDisplayTouchModeEnabled;
} gServiceClassInfo;
static struct {
@@ -265,7 +266,7 @@ protected:
virtual ~NativeInputManager();
public:
- NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
+ NativeInputManager(jobject serviceObj, const sp<Looper>& looper);
inline sp<InputManagerInterface> getInputManager() const { return mInputManager; }
@@ -355,6 +356,10 @@ public:
virtual PointerIconStyle getCustomPointerIconId();
virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos);
+ /* --- If touch mode is enabled per display or global --- */
+
+ virtual bool isPerDisplayTouchModeEnabled();
+
private:
sp<InputManagerInterface> mInputManager;
@@ -398,23 +403,17 @@ private:
} mLocked GUARDED_BY(mLock);
std::atomic<bool> mInteractive;
-
void updateInactivityTimeoutLocked();
void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
void ensureSpriteControllerLocked();
sp<SurfaceControl> getParentSurfaceForPointers(int displayId);
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
- static inline JNIEnv* jniEnv() {
- return AndroidRuntime::getJNIEnv();
- }
+ static inline JNIEnv* jniEnv() { return AndroidRuntime::getJNIEnv(); }
};
-
-
-NativeInputManager::NativeInputManager(jobject contextObj,
- jobject serviceObj, const sp<Looper>& looper) :
- mLooper(looper), mInteractive(true) {
+NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& looper)
+ : mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();
mServiceObj = env->NewGlobalRef(serviceObj);
@@ -429,7 +428,6 @@ NativeInputManager::NativeInputManager(jobject contextObj,
mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
}
mInteractive = true;
-
InputManager* im = new InputManager(this, this);
mInputManager = im;
defaultServiceManager()->addService(String16("inputflinger"), im);
@@ -1488,6 +1486,16 @@ void NativeInputManager::setMotionClassifierEnabled(bool enabled) {
mInputManager->getClassifier().setMotionClassifierEnabled(enabled);
}
+bool NativeInputManager::isPerDisplayTouchModeEnabled() {
+ JNIEnv* env = jniEnv();
+ jboolean enabled =
+ env->CallBooleanMethod(mServiceObj, gServiceClassInfo.isPerDisplayTouchModeEnabled);
+ if (checkAndClearExceptionFromCallback(env, "isPerDisplayTouchModeEnabled")) {
+ return false;
+ }
+ return static_cast<bool>(enabled);
+}
+
// ----------------------------------------------------------------------------
static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
@@ -1495,16 +1503,15 @@ static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
env->GetLongField(clazz, gNativeInputManagerServiceImpl.mPtr));
}
-static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
- jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
+static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,
+ jobject messageQueueObj) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == nullptr) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
- NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
- messageQueue->getLooper());
+ NativeInputManager* im = new NativeInputManager(serviceObj, messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
@@ -1677,11 +1684,11 @@ static void nativeSetInputFilterEnabled(JNIEnv* env, jobject nativeImplObj, jboo
}
static jboolean nativeSetInTouchMode(JNIEnv* env, jobject nativeImplObj, jboolean inTouchMode,
- jint pid, jint uid, jboolean hasPermission) {
+ jint pid, jint uid, jboolean hasPermission, jint displayId) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, pid, uid,
- hasPermission);
+ hasPermission, displayId);
}
static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* env, jobject nativeImplObj,
@@ -2312,7 +2319,7 @@ static void nativeSetPointerDisplayId(JNIEnv* env, jobject nativeImplObj, jint d
static const JNINativeMethod gInputManagerMethods[] = {
/* name, signature, funcPtr */
{"init",
- "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
+ "(Lcom/android/server/input/InputManagerService;Landroid/os/"
"MessageQueue;)J",
(void*)nativeInit},
{"start", "()V", (void*)nativeStart},
@@ -2330,7 +2337,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
{"removeInputChannel", "(Landroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
{"pilferPointers", "(Landroid/os/IBinder;)V", (void*)nativePilferPointers},
{"setInputFilterEnabled", "(Z)V", (void*)nativeSetInputFilterEnabled},
- {"setInTouchMode", "(ZIIZ)Z", (void*)nativeSetInTouchMode},
+ {"setInTouchMode", "(ZIIZI)Z", (void*)nativeSetInTouchMode},
{"setMaximumObscuringOpacityForTouch", "(F)V",
(void*)nativeSetMaximumObscuringOpacityForTouch},
{"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent},
@@ -2536,6 +2543,9 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz,
"getParentSurfaceForPointers", "(I)J");
+ GET_METHOD_ID(gServiceClassInfo.isPerDisplayTouchModeEnabled, clazz,
+ "isPerDisplayTouchModeEnabled", "()Z");
+
// InputDevice
FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4c2803fa17da..b4cade344c00 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -18618,9 +18618,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
Objects.requireNonNull(strings, "strings must be provided.");
mInjector.binderWithCleanCallingIdentity(() -> {
- if (mDeviceManagementResourcesProvider.updateStrings(strings))
- sendStringsUpdatedBroadcast(
- strings.stream().map(s -> s.getStringId()).collect(Collectors.toList()));
+ if (mDeviceManagementResourcesProvider.updateStrings(strings)) {
+ sendStringsUpdatedBroadcast(
+ strings.stream().map(s -> s.getStringId()).collect(Collectors.toList()));
+ }
});
}
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index ca9ff6f15f3f..962a07ac6553 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -43,23 +43,23 @@ import static com.android.server.backup.testing.Utils.transferStreamedData;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.intThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.intThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.shadow.api.Shadow.extract;
@@ -2185,7 +2185,7 @@ public class KeyValueBackupTaskTest {
task.waitCancel();
reset(transportMock.transport);
taskFinished.block();
- verifyZeroInteractions(transportMock.transport);
+ verifyNoInteractions(transportMock.transport);
}
@Test
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
index dcffc9e73c0e..f041fbd7bf90 100644
--- a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
@@ -334,18 +334,7 @@ public class SmartspacePerUserService extends
@NonNull
private final SmartspaceConfig mSmartspaceConfig;
private final RemoteCallbackList<ISmartspaceCallback> mCallbacks =
- new RemoteCallbackList<ISmartspaceCallback>() {
- @Override
- public void onCallbackDied(ISmartspaceCallback callback) {
- if (DEBUG) {
- Slog.d(TAG, "Binder died for session Id=" + mSessionId
- + " and callback=" + callback.asBinder());
- }
- if (mCallbacks.getRegisteredCallbackCount() == 0) {
- destroy();
- }
- }
- };
+ new RemoteCallbackList<>();
SmartspaceSessionInfo(
@NonNull final SmartspaceSessionId id,
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 2d0ef405b9d7..c8c87075eda2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -74,7 +74,6 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_W
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WINDOW;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_EXACT_ALARM_DENY_LIST;
-import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_DEVICE_IDLE_FUZZ;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
@@ -3093,37 +3092,6 @@ public class AlarmManagerServiceTest {
optionsSentOnExpiration(false, null);
}
- @Test
- public void alarmStoreMigration() {
- setDeviceConfigBoolean(KEY_LAZY_BATCHING, false);
- final int numAlarms = 10;
- final PendingIntent[] pis = new PendingIntent[numAlarms];
- for (int i = 0; i < numAlarms; i++) {
- pis[i] = getNewMockPendingIntent();
- setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 1, pis[i]);
- }
-
- final ArrayList<Alarm> alarmsBefore = mService.mAlarmStore.asList();
- assertEquals(numAlarms, alarmsBefore.size());
- for (int i = 0; i < numAlarms; i++) {
- final PendingIntent pi = pis[i];
- assertTrue(i + "th PendingIntent missing: ",
- alarmsBefore.removeIf(a -> a.matches(pi, null)));
- }
- assertEquals(BatchingAlarmStore.TAG, mService.mAlarmStore.getName());
-
- setDeviceConfigBoolean(KEY_LAZY_BATCHING, true);
-
- final ArrayList<Alarm> alarmsAfter = mService.mAlarmStore.asList();
- assertEquals(numAlarms, alarmsAfter.size());
- for (int i = 0; i < numAlarms; i++) {
- final PendingIntent pi = pis[i];
- assertTrue(i + "th PendingIntent missing: ",
- alarmsAfter.removeIf(a -> a.matches(pi, null)));
- }
- assertEquals(LazyAlarmStore.TAG, mService.mAlarmStore.getName());
- }
-
private void registerAppIds(String[] packages, Integer[] ids) {
assertEquals(packages.length, ids.length);
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
index ba0e555020ac..7dab1c854625 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
@@ -56,7 +56,6 @@ public class AlarmStoreTest {
public static Object[] stores() {
return new AlarmStore[]{
new LazyAlarmStore(),
- new BatchingAlarmStore(),
};
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
index b42a3b0719df..e59a404ebed4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
@@ -39,6 +39,10 @@ import com.android.server.testutils.spy
import com.android.server.testutils.whenever
import com.android.server.utils.WatchedLongSparseArray
import com.google.common.truth.Truth.assertThat
+import java.io.File
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
import libcore.util.HexEncoding
import org.junit.Before
import org.junit.Rule
@@ -51,10 +55,6 @@ import org.mockito.Mock
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import java.io.File
-import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
@RunWith(JUnit4::class)
class SharedLibrariesImplTest {
@@ -186,7 +186,7 @@ class SharedLibrariesImplTest {
val staticInfo = mSharedLibrariesImpl
.getSharedLibraryInfo(STATIC_LIB_NAME, STATIC_LIB_VERSION)!!
- mSharedLibrariesImpl.removeSharedLibraryLPw(STATIC_LIB_NAME, STATIC_LIB_VERSION)
+ mSharedLibrariesImpl.removeSharedLibrary(STATIC_LIB_NAME, STATIC_LIB_VERSION)
assertThat(mSharedLibrariesImpl.getSharedLibraryInfos(STATIC_LIB_NAME)).isNull()
assertThat(mSharedLibrariesImpl
@@ -208,7 +208,7 @@ class SharedLibrariesImplTest {
staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = 10L)
val latestInfo =
- mSharedLibrariesImpl.getLatestStaticSharedLibraVersionLPr(pair.second)!!
+ mSharedLibrariesImpl.getLatestStaticSharedLibraVersion(pair.second)!!
assertThat(latestInfo).isNotNull()
assertThat(latestInfo.name).isEqualTo(STATIC_LIB_NAME)
@@ -237,7 +237,7 @@ class SharedLibrariesImplTest {
testPackageSetting.setPkgStateLibraryFiles(listOf())
assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
- mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
+ mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg, testPackageSetting,
null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
assertThat(testPackageSetting.usesLibraryFiles).hasSize(1)
@@ -250,7 +250,7 @@ class SharedLibrariesImplTest {
testPackageSetting.setPkgStateLibraryFiles(listOf())
assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
- mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
+ mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg, testPackageSetting,
null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
assertThat(testPackageSetting.usesLibraryFiles).hasSize(2)
@@ -264,7 +264,7 @@ class SharedLibrariesImplTest {
testPackageSetting.setPkgStateLibraryFiles(listOf())
assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
- mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
+ mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg, testPackageSetting,
null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
assertThat(testPackageSetting.usesLibraryFiles).hasSize(3)
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
index 5c4657fb0027..0f2c27c83791 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
@@ -223,7 +223,17 @@ public class PowerManagerServiceMockingTest {
@Override
PowerManagerService.Clock createClock() {
- return () -> mClock.now();
+ return new PowerManagerService.Clock() {
+ @Override
+ public long uptimeMillis() {
+ return mClock.now();
+ }
+
+ @Override
+ public long elapsedRealtime() {
+ return mClock.now();
+ }
+ };
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 56c51507606f..51d78e1d3a11 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -57,7 +57,9 @@ import android.testing.TestableContext;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.DisplayInfo;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.AccessibilityWindowAttributes;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -417,6 +419,20 @@ public class AccessibilityManagerServiceTest {
verify(mMockSystemSupport).unbindImeLocked(mAccessibilityServiceConnection);
}
+ @Test
+ public void testSetAccessibilityWindowAttributes_passThrough() {
+ final int displayId = Display.DEFAULT_DISPLAY;
+ final int userid = 10;
+ final int windowId = 100;
+ final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
+ new WindowManager.LayoutParams());
+
+ mA11yms.setAccessibilityWindowAttributes(displayId, windowId, userid, attributes);
+
+ verify(mMockA11yWindowManager).setAccessibilityWindowAttributes(displayId, windowId, userid,
+ attributes);
+ }
+
public static class FakeInputFilter extends AccessibilityInputFilter {
FakeInputFilter(Context context,
AccessibilityManagerService service) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 4f4be6cd634d..c7757f7832fa 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -42,12 +43,15 @@ import android.graphics.Region;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.SparseArray;
import android.view.Display;
import android.view.IWindow;
import android.view.WindowInfo;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowAttributes;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -136,6 +140,11 @@ public class AccessibilityWindowManagerTest {
when(mMockA11ySecurityPolicy.resolveValidReportedPackageLocked(
anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
+ doAnswer((invocation) -> {
+ onWindowsForAccessibilityChanged(invocation.getArgument(0), false);
+ return null;
+ }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
+
mA11yWindowManager = new AccessibilityWindowManager(new Object(), mHandler,
mMockWindowManagerInternal,
mMockA11yEventSender,
@@ -835,6 +844,23 @@ public class AccessibilityWindowManagerTest {
assertNull(token);
}
+ @Test
+ public void setAccessibilityWindowAttributes_windowIsNotRegistered_titleIsChanged() {
+ final int windowId =
+ getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
+ final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+ layoutParams.accessibilityTitle = "accessibility window title";
+ final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
+ layoutParams);
+
+ mA11yWindowManager.setAccessibilityWindowAttributes(Display.DEFAULT_DISPLAY, windowId,
+ USER_SYSTEM_ID, attributes);
+
+ final AccessibilityWindowInfo a11yWindow = mA11yWindowManager.findA11yWindowInfoByIdLocked(
+ windowId);
+ assertTrue(TextUtils.equals(layoutParams.accessibilityTitle, a11yWindow.getTitle()));
+ }
+
private void registerLeashedTokenAndWindowId() {
mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID);
mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID);
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
index ece0a627f051..b0738fdb78d0 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
@@ -17,7 +17,11 @@
package com.android.server.display;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.PropertyInvalidatedCache;
@@ -45,18 +49,21 @@ public class LogicalDisplayTest {
private LogicalDisplay mLogicalDisplay;
private DisplayDevice mDisplayDevice;
+ private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo();
@Before
public void setUp() {
// Share classloader to allow package private access.
System.setProperty("dexmaker.share_classloader", "true");
mDisplayDevice = mock(DisplayDevice.class);
- DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
- displayDeviceInfo.width = DISPLAY_WIDTH;
- displayDeviceInfo.height = DISPLAY_HEIGHT;
- displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice);
- when(mDisplayDevice.getDisplayDeviceInfoLocked()).thenReturn(displayDeviceInfo);
+
+ mDisplayDeviceInfo.copyFrom(new DisplayDeviceInfo());
+ mDisplayDeviceInfo.width = DISPLAY_WIDTH;
+ mDisplayDeviceInfo.height = DISPLAY_HEIGHT;
+ mDisplayDeviceInfo.flags = DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+ mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
+ when(mDisplayDevice.getDisplayDeviceInfoLocked()).thenReturn(mDisplayDeviceInfo);
// Disable binder caches in this process.
PropertyInvalidatedCache.disableForTestMode();
@@ -103,4 +110,33 @@ public class LogicalDisplayTest {
mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition());
}
+
+ @Test
+ public void testDisplayInputFlags() {
+ SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
+ mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+ verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
+ reset(t);
+
+ mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
+ mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+ verify(t).setDisplayFlags(any(), eq(0));
+ reset(t);
+
+ mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
+ mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+ verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
+ reset(t);
+
+ mLogicalDisplay.setPhase(LogicalDisplay.DISPLAY_PHASE_DISABLED);
+ mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+ verify(t).setDisplayFlags(any(), eq(0));
+ reset(t);
+
+ mLogicalDisplay.setPhase(LogicalDisplay.DISPLAY_PHASE_ENABLED);
+ mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
+ mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+ verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
+ reset(t);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index cc6f2cc5ba3e..0a4da8da943e 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -199,9 +199,6 @@ public class InputMethodUtilsTest {
final InputMethodSubtype nonAutoEnGB = createFakeInputMethodSubtype("en_GB",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoEnIN = createFakeInputMethodSubtype("en_IN",
- SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
- IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
final InputMethodSubtype nonAutoFrCA = createFakeInputMethodSubtype("fr_CA",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
@@ -656,9 +653,6 @@ public class InputMethodUtilsTest {
final InputMethodSubtype nonAutoEnUS = createFakeInputMethodSubtype("en_US",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoEnGB = createFakeInputMethodSubtype("en_GB",
- SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
- IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
final InputMethodSubtype nonAutoFil = createFakeInputMethodSubtype("fil",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
index c30af4cae59d..3f3b8d770f61 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
@@ -32,7 +32,7 @@ import java.util.Arrays;
public class LockSettingsStorageTestable extends LockSettingsStorage {
- public File mStorageDir;
+ public final File mStorageDir;
public PersistentDataBlockManagerInternal mPersistentDataBlockManager;
private byte[] mPersistentData;
@@ -64,25 +64,23 @@ public class LockSettingsStorageTestable extends LockSettingsStorage {
}
@Override
- String getChildProfileLockFile(int userId) {
- return makeDirs(mStorageDir,
- super.getChildProfileLockFile(userId)).getAbsolutePath();
+ File getChildProfileLockFile(int userId) {
+ return remapToStorageDir(super.getChildProfileLockFile(userId));
}
@Override
- String getRebootEscrowServerBlob() {
- return makeDirs(mStorageDir, super.getRebootEscrowServerBlob()).getAbsolutePath();
+ File getRebootEscrowServerBlobFile() {
+ return remapToStorageDir(super.getRebootEscrowServerBlobFile());
}
@Override
- String getRebootEscrowFile(int userId) {
- return makeDirs(mStorageDir, super.getRebootEscrowFile(userId)).getAbsolutePath();
+ File getRebootEscrowFile(int userId) {
+ return remapToStorageDir(super.getRebootEscrowFile(userId));
}
@Override
protected File getSyntheticPasswordDirectoryForUser(int userId) {
- return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
- userId).getAbsolutePath());
+ return remapToStorageDir(super.getSyntheticPasswordDirectoryForUser(userId));
}
@Override
@@ -90,14 +88,9 @@ public class LockSettingsStorageTestable extends LockSettingsStorage {
return mPersistentDataBlockManager;
}
- private File makeDirs(File baseDir, String filePath) {
- File path = new File(filePath);
- if (path.getParent() == null) {
- return new File(baseDir, filePath);
- } else {
- File mappedDir = new File(baseDir, path.getParent());
- mappedDir.mkdirs();
- return new File(mappedDir, path.getName());
- }
+ private File remapToStorageDir(File origPath) {
+ File mappedPath = new File(mStorageDir, origPath.toString());
+ mappedPath.getParentFile().mkdirs();
+ return mappedPath;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index c4df05149d4b..a6638587bf22 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -304,14 +304,15 @@ public class LockSettingsStorageTests {
public void testFileLocation_Owner() {
LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
- assertEquals("/data/system/gatekeeper.profile.key", storage.getChildProfileLockFile(0));
+ assertEquals(new File("/data/system/gatekeeper.profile.key"),
+ storage.getChildProfileLockFile(0));
}
@Test
public void testFileLocation_SecondaryUser() {
LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
- assertEquals("/data/system/users/1/gatekeeper.profile.key",
+ assertEquals(new File("/data/system/users/1/gatekeeper.profile.key"),
storage.getChildProfileLockFile(1));
}
@@ -319,7 +320,7 @@ public class LockSettingsStorageTests {
public void testFileLocation_ProfileToSecondary() {
LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
- assertEquals("/data/system/users/2/gatekeeper.profile.key",
+ assertEquals(new File("/data/system/users/2/gatekeeper.profile.key"),
storage.getChildProfileLockFile(2));
}
@@ -327,7 +328,7 @@ public class LockSettingsStorageTests {
public void testFileLocation_ProfileToOwner() {
LockSettingsStorage storage = new LockSettingsStorage(InstrumentationRegistry.getContext());
- assertEquals("/data/system/users/3/gatekeeper.profile.key",
+ assertEquals(new File("/data/system/users/3/gatekeeper.profile.key"),
storage.getChildProfileLockFile(3));
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
index 7d1cc3cba5d2..48c58bbeb405 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
@@ -52,9 +52,13 @@ import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedActivityImpl;
+import com.android.server.pm.pkg.component.ParsedComponentImpl;
import com.android.server.pm.pkg.component.ParsedInstrumentationImpl;
import com.android.server.pm.pkg.component.ParsedIntentInfoImpl;
+import com.android.server.pm.pkg.component.ParsedPermission;
+import com.android.server.pm.pkg.component.ParsedPermissionImpl;
import com.android.server.pm.pkg.component.ParsedProviderImpl;
+import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
import com.android.server.pm.pkg.parsing.ParsingPackage;
import com.android.server.utils.WatchableTester;
@@ -160,6 +164,17 @@ public class AppsFilterImplTest {
return pkg(packageName).addLibraryName(libName);
}
+ private static ParsingPackage pkgWithCustomPermissions(String packageName,
+ String... permNames) {
+ ParsingPackage newPkg = pkg(packageName);
+ for (String permName : permNames) {
+ ParsedPermission permission = new ParsedPermissionImpl();
+ ((ParsedComponentImpl) permission).setName(permName);
+ newPkg.addPermission(permission);
+ }
+ return newPkg;
+ }
+
private static ParsedActivity createActivity(String packageName, IntentFilter[] filters) {
ParsedActivityImpl activity = new ParsedActivityImpl();
activity.setPackageName(packageName);
@@ -227,8 +242,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemReadyPropogates() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
appsFilter.onSystemReady(mPmInternal);
@@ -239,8 +254,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -264,8 +279,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -313,8 +328,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProvider_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -338,8 +353,8 @@ public class AppsFilterImplTest {
@Test
public void testOnUserUpdated_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -386,8 +401,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesDifferentProvider_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -411,8 +426,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -430,8 +445,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_NoMatchingAction_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -447,8 +462,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -469,8 +484,8 @@ public class AppsFilterImplTest {
@Test
public void testNoQueries_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -486,10 +501,9 @@ public class AppsFilterImplTest {
@Test
public void testNoUsesLibrary_Filters() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
- new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
- mMockHandler);
-
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -513,10 +527,9 @@ public class AppsFilterImplTest {
@Test
public void testUsesLibrary_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
- new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
- mMockHandler);
-
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -541,10 +554,9 @@ public class AppsFilterImplTest {
@Test
public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
- new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
- mMockHandler);
-
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -569,10 +581,9 @@ public class AppsFilterImplTest {
@Test
public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
- final AppsFilterImpl appsFilter = new AppsFilterImpl(mFeatureConfigMock,
- new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
- mMockHandler);
-
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -603,8 +614,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryable_SystemDoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -623,8 +634,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryable_NonSystemFilters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -641,9 +652,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock,
- new String[]{"com.some.package"}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"},
+ /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -662,8 +672,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemSignedTarget_DoesntFilter() throws CertificateException {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
appsFilter.onSystemReady(mPmInternal);
final Signature frameworkSignature = Mockito.mock(Signature.class);
@@ -692,9 +702,8 @@ public class AppsFilterImplTest {
@Test
public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock,
- new String[]{"com.some.package"}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{"com.some.package"},
+ /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -712,8 +721,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemQueryable_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{},
- true /* system force queryable */, null, mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ true, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -731,8 +740,8 @@ public class AppsFilterImplTest {
@Test
public void testQueriesPackage_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -751,8 +760,8 @@ public class AppsFilterImplTest {
when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(false);
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -769,8 +778,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemUid_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -786,8 +795,8 @@ public class AppsFilterImplTest {
@Test
public void testSystemUidSecondaryUser_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -804,8 +813,8 @@ public class AppsFilterImplTest {
@Test
public void testNonSystemUid_NoCallingSetting_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -817,10 +826,10 @@ public class AppsFilterImplTest {
}
@Test
- public void testNoTargetPackage_filters() throws Exception {
+ public void testNoTargetPackage_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -991,8 +1000,8 @@ public class AppsFilterImplTest {
@Test
public void testInitiatingApp_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1010,8 +1019,8 @@ public class AppsFilterImplTest {
@Test
public void testUninstalledInitiatingApp_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1029,8 +1038,8 @@ public class AppsFilterImplTest {
@Test
public void testOriginatingApp_Filters() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1055,8 +1064,8 @@ public class AppsFilterImplTest {
@Test
public void testInstallingApp_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1081,8 +1090,8 @@ public class AppsFilterImplTest {
@Test
public void testInstrumentation_DoesntFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1110,8 +1119,8 @@ public class AppsFilterImplTest {
@Test
public void testWhoCanSee() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1185,8 +1194,8 @@ public class AppsFilterImplTest {
@Test
public void testOnChangeReport() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
watcher.register();
simulateAddBasicAndroid(appsFilter);
@@ -1260,8 +1269,8 @@ public class AppsFilterImplTest {
@Test
public void testOnChangeReportedFilter() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
final WatchableTester watcher = new WatchableTester(appsFilter, "onChange filter");
@@ -1287,8 +1296,8 @@ public class AppsFilterImplTest {
public void testAppsFilterRead() throws Exception {
when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock);
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1338,8 +1347,8 @@ public class AppsFilterImplTest {
@Test
public void testSdkSandbox_canSeeForceQueryable() throws Exception {
final AppsFilterImpl appsFilter =
- new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
- mMockHandler);
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
simulateAddBasicAndroid(appsFilter);
appsFilter.onSystemReady(mPmInternal);
@@ -1358,10 +1367,34 @@ public class AppsFilterImplTest {
@Test
public void testSdkSandbox_cannotSeeNonForceQueryable() throws Exception {
final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package"), DUMMY_TARGET_APPID,
+ setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
+
+ int callingUid = 20123;
+ assertTrue(Process.isSdkSandboxUid(callingUid));
+
+ assertTrue(
+ appsFilter.shouldFilterApplication(mSnapshot, callingUid,
+ null /* callingSetting */, target, SYSTEM_USER));
+ }
+
+ @Test
+ public void testSdkSandbox_implicitAccessGranted_canSeePackage() throws Exception {
+ final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockHandler);
+ final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
+ watcher.register();
simulateAddBasicAndroid(appsFilter);
+ watcher.verifyChangeReported("addBasic");
appsFilter.onSystemReady(mPmInternal);
+ watcher.verifyChangeReported("systemReady");
PackageSetting target = simulateAddPackage(appsFilter,
pkg("com.some.package"), DUMMY_TARGET_APPID,
@@ -1370,11 +1403,181 @@ public class AppsFilterImplTest {
int callingUid = 20123;
assertTrue(Process.isSdkSandboxUid(callingUid));
+ // Without granting the implicit access the app shouldn't be visible to the sdk sandbox uid.
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, callingUid,
null /* callingSetting */, target, SYSTEM_USER));
+
+ appsFilter.grantImplicitAccess(callingUid, target.getAppId(), false /* retainOnUpdate */);
+ watcher.verifyChangeReported("grantImplicitAccess");
+
+ // After implicit access was granted the app should be visible to the sdk sandbox uid.
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, callingUid,
+ null /* callingSetting */, target, SYSTEM_USER));
+ }
+
+ @Test
+ public void testUsesPermission_installPermissionDefinerBeforeRequester_DoesntFilter()
+ throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ final PackageSetting target = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package",
+ "com.some.custom_permission"),
+ DUMMY_TARGET_APPID);
+ final PackageSetting calling = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package").addUsesPermission(
+ new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
+ DUMMY_CALLING_APPID);
+
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
+ }
+
+ @Test
+ public void testUsesPermission_installPermissionRequesterBeforeDefiner_DoesntFilter()
+ throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ final PackageSetting calling = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package").addUsesPermission(
+ new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
+ DUMMY_CALLING_APPID);
+
+ final PackageSetting target = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package",
+ "com.some.custom_permission"),
+ DUMMY_TARGET_APPID);
+
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
+ }
+
+ @Test
+ public void testUsesPermission_visibilityFromPermissionDefinerToRequester_Filters()
+ throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ final PackageSetting calling = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package",
+ "com.some.custom_permission"),
+ DUMMY_CALLING_APPID);
+
+ final PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package").addUsesPermission(
+ new ParsedUsesPermissionImpl("com.some.custom_permission", 0)),
+ DUMMY_TARGET_APPID);
+
+ assertTrue(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
+ }
+
+ @Test
+ public void testUsesPermission_multipleCustomPermissions() throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+ final PackageSetting target = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package",
+ "com.some.custom_permission1", "com.some.custom_permission2"),
+ DUMMY_TARGET_APPID);
+
+ final PackageSetting calling1 = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package")
+ .addUsesPermission(new ParsedUsesPermissionImpl(
+ "com.some.custom_permission1", 0)),
+ DUMMY_CALLING_APPID);
+
+ final PackageSetting calling2 = simulateAddPackage(appsFilter,
+ pkg("com.some.another.package")
+ .addUsesPermission(new ParsedUsesPermissionImpl(
+ "com.some.custom_permission2", 0))
+ .addUsesPermission(new ParsedUsesPermissionImpl(
+ "com.some.custom_permission3", 0)),
+ DUMMY_CALLING_APPID + 1);
+
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling1, target,
+ SYSTEM_USER));
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID + 1,
+ calling2, target, SYSTEM_USER));
+ assertTrue(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling1,
+ calling2, SYSTEM_USER));
+ }
+
+ @Test
+ public void testUsesPermission_multiplePermissionDefiners_DoesntFilter() throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+
+ final PackageSetting target1 = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package1", "com.some.custom_permission"),
+ DUMMY_TARGET_APPID);
+ final PackageSetting target2 = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package2", "com.some.custom_permission"),
+ DUMMY_TARGET_APPID + 1);
+ final PackageSetting calling = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package")
+ .addUsesPermission(new ParsedUsesPermissionImpl(
+ "com.some.custom_permission", 0)),
+ DUMMY_CALLING_APPID);
+
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target1,
+ SYSTEM_USER));
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target2,
+ SYSTEM_USER));
+
}
+ @Test
+ public void testNoUsesPermission_Filters() throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady(mPmInternal);
+
+
+ final PackageSetting target = simulateAddPackage(appsFilter,
+ pkgWithCustomPermissions("com.some.package", "com.some.custom_permission"),
+ DUMMY_TARGET_APPID);
+ final PackageSetting calling = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package"),
+ DUMMY_CALLING_APPID);
+
+ assertTrue(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
+ }
private List<Integer> toList(int[] array) {
ArrayList<Integer> ret = new ArrayList<>(array.length);
for (int i = 0; i < array.length; i++) {
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 78f7f66ec7eb..f1f423d537dc 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -158,6 +158,7 @@ public class PowerManagerServiceTest {
private UserSwitchedReceiver mUserSwitchedReceiver;
private Resources mResourcesSpy;
private OffsettableClock mClock;
+ private long mLastElapsedRealtime;
private TestLooper mTestLooper;
private static class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
@@ -286,7 +287,18 @@ public class PowerManagerServiceTest {
@Override
PowerManagerService.Clock createClock() {
- return () -> mClock.now();
+ return new PowerManagerService.Clock() {
+ @Override
+ public long uptimeMillis() {
+ return mClock.now();
+ }
+
+ @Override
+ public long elapsedRealtime() {
+ mLastElapsedRealtime = mClock.now();
+ return mLastElapsedRealtime;
+ }
+ };
}
@Override
@@ -1686,6 +1698,7 @@ public class PowerManagerServiceTest {
mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_DOZING, eventTime2,
0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
+ long eventElapsedRealtime1 = mLastElapsedRealtime;
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
PowerManager.GO_TO_SLEEP_REASON_APPLICATION);
@@ -1693,19 +1706,20 @@ public class PowerManagerServiceTest {
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE,
eventTime3, /* uid= */ 0, PowerManager.WAKE_REASON_PLUGGED_IN, /* opUid= */
0, /* opPackageName= */ null, /* details= */ null);
+ long eventElapsedRealtime2 = mLastElapsedRealtime;
PowerManager.WakeData wakeData = mService.getLocalServiceInstance().getLastWakeup();
assertThat(wakeData.wakeTime).isEqualTo(eventTime3);
assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN);
- assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2);
+ assertThat(wakeData.sleepDurationRealtime)
+ .isEqualTo(eventElapsedRealtime2 - eventElapsedRealtime1);
// The global wake time and reason as well as sleep duration shouldn't change when another
// PowerGroup wakes up.
mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_AWAKE,
eventTime4, /* uid= */ 0, PowerManager.WAKE_REASON_CAMERA_LAUNCH, /* opUid= */
0, /* opPackageName= */ null, /* details= */ null);
- assertThat(wakeData.wakeTime).isEqualTo(eventTime3);
- assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN);
- assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2);
+ PowerManager.WakeData wakeData2 = mService.getLocalServiceInstance().getLastWakeup();
+ assertThat(wakeData2).isEqualTo(wakeData);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
index d016d7e3e748..1c6add2ffd61 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
@@ -21,9 +21,7 @@ import static org.junit.Assert.assertTrue;
import android.annotation.UserIdInt;
import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.util.IndentingPrintWriter;
diff --git a/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeSuggestionTest.java
index af403a20ae7b..f25d94e0d7ef 100644
--- a/core/tests/coretests/src/android/app/timedetector/GnssTimeSuggestionTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeSuggestionTest.java
@@ -14,11 +14,9 @@
* limitations under the License.
*/
-package android.app.timedetector;
+package com.android.server.timedetector;
-import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
-import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
-import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+import static com.android.server.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -55,17 +53,6 @@ public class GnssTimeSuggestionTest {
assertEquals(one, two);
}
- @Test
- public void testParcelable() {
- GnssTimeSuggestion suggestion = new GnssTimeSuggestion(ARBITRARY_TIME);
- assertRoundTripParcelable(suggestion);
-
- // DebugInfo should also be stored (but is not checked by equals()
- suggestion.addDebugInfo("This is debug info");
- GnssTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
- assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
- }
-
@Test(expected = IllegalArgumentException.class)
public void testParseCommandLineArg_noReferenceTime() {
ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
index aad5cd65c4f7..6402e1298124 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
@@ -19,15 +19,12 @@ package com.android.server.timedetector;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AlarmManager;
-import android.app.timedetector.GnssTimeSuggestion;
-import android.app.timedetector.TimeDetector;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
@@ -56,10 +53,10 @@ public final class GnssTimeUpdateServiceTest {
private static final long ELAPSED_REALTIME_MS = ELAPSED_REALTIME_NS / 1_000_000L;
@Mock private Context mMockContext;
- @Mock private TimeDetector mMockTimeDetector;
@Mock private AlarmManager mMockAlarmManager;
@Mock private LocationManager mMockLocationManager;
- @Mock private LocationManagerInternal mLocationManagerInternal;
+ @Mock private LocationManagerInternal mMockLocationManagerInternal;
+ @Mock private TimeDetectorInternal mMockTimeDetectorInternal;
private GnssTimeUpdateService mGnssTimeUpdateService;
@@ -67,31 +64,12 @@ public final class GnssTimeUpdateServiceTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mMockContext.createAttributionContext(anyString()))
- .thenReturn(mMockContext);
-
- when(mMockContext.getSystemServiceName(TimeDetector.class))
- .thenReturn((TimeDetector.class).getSimpleName());
- when(mMockContext.getSystemService(TimeDetector.class))
- .thenReturn(mMockTimeDetector);
-
- when(mMockContext.getSystemServiceName(LocationManager.class))
- .thenReturn((LocationManager.class).getSimpleName());
- when(mMockContext.getSystemService(LocationManager.class))
- .thenReturn(mMockLocationManager);
-
- when(mMockContext.getSystemServiceName(AlarmManager.class))
- .thenReturn((AlarmManager.class).getSimpleName());
- when(mMockContext.getSystemService(AlarmManager.class))
- .thenReturn(mMockAlarmManager);
-
when(mMockLocationManager.hasProvider(LocationManager.GPS_PROVIDER))
.thenReturn(true);
- LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
-
- mGnssTimeUpdateService =
- new GnssTimeUpdateService(mMockContext);
+ mGnssTimeUpdateService = new GnssTimeUpdateService(
+ mMockContext, mMockAlarmManager, mMockLocationManager, mMockLocationManagerInternal,
+ mMockTimeDetectorInternal);
}
@After
@@ -105,7 +83,7 @@ public final class GnssTimeUpdateServiceTest {
ELAPSED_REALTIME_MS, GNSS_TIME);
GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
LocationTime locationTime = new LocationTime(GNSS_TIME, ELAPSED_REALTIME_NS);
- doReturn(locationTime).when(mLocationManagerInternal).getGnssTimeMillis();
+ doReturn(locationTime).when(mMockLocationManagerInternal).getGnssTimeMillis();
mGnssTimeUpdateService.requestGnssTimeUpdates();
@@ -124,7 +102,7 @@ public final class GnssTimeUpdateServiceTest {
locationListener.onLocationChanged(location);
verify(mMockLocationManager).removeUpdates(locationListener);
- verify(mMockTimeDetector).suggestGnssTime(timeSuggestion);
+ verify(mMockTimeDetectorInternal).suggestGnssTime(timeSuggestion);
verify(mMockAlarmManager).set(
eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
anyLong(),
@@ -135,7 +113,7 @@ public final class GnssTimeUpdateServiceTest {
@Test
public void testLocationListenerOnLocationChanged_nullLocationTime_doesNotSuggestGnssTime() {
- doReturn(null).when(mLocationManagerInternal).getGnssTimeMillis();
+ doReturn(null).when(mMockLocationManagerInternal).getGnssTimeMillis();
mGnssTimeUpdateService.requestGnssTimeUpdates();
@@ -154,7 +132,7 @@ public final class GnssTimeUpdateServiceTest {
locationListener.onLocationChanged(location);
verify(mMockLocationManager).removeUpdates(locationListener);
- verify(mMockTimeDetector, never()).suggestGnssTime(any());
+ verify(mMockTimeDetectorInternal, never()).suggestGnssTime(any());
verify(mMockAlarmManager).set(
eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
anyLong(),
diff --git a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java b/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeSuggestionTest.java
index 0e09dd3e9aab..f5a37b964508 100644
--- a/core/tests/coretests/src/android/app/timedetector/NetworkTimeSuggestionTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeSuggestionTest.java
@@ -14,11 +14,9 @@
* limitations under the License.
*/
-package android.app.timedetector;
+package com.android.server.timedetector;
-import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
-import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
-import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+import static com.android.server.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -32,60 +30,66 @@ public class NetworkTimeSuggestionTest {
private static final TimestampedValue<Long> ARBITRARY_TIME =
new TimestampedValue<>(1111L, 2222L);
+ private static final int ARBITRARY_UNCERTAINTY_MILLIS = 3333;
@Test
public void testEquals() {
- NetworkTimeSuggestion one = new NetworkTimeSuggestion(ARBITRARY_TIME);
+ NetworkTimeSuggestion one = new NetworkTimeSuggestion(
+ ARBITRARY_TIME, ARBITRARY_UNCERTAINTY_MILLIS);
assertEquals(one, one);
- NetworkTimeSuggestion two = new NetworkTimeSuggestion(ARBITRARY_TIME);
+ NetworkTimeSuggestion two =
+ new NetworkTimeSuggestion(ARBITRARY_TIME, ARBITRARY_UNCERTAINTY_MILLIS);
assertEquals(one, two);
assertEquals(two, one);
TimestampedValue<Long> differentTime = new TimestampedValue<>(
ARBITRARY_TIME.getReferenceTimeMillis() + 1,
ARBITRARY_TIME.getValue());
- NetworkTimeSuggestion three = new NetworkTimeSuggestion(differentTime);
+ NetworkTimeSuggestion three = new NetworkTimeSuggestion(
+ differentTime, ARBITRARY_UNCERTAINTY_MILLIS);
assertNotEquals(one, three);
assertNotEquals(three, one);
+ int differentUncertainty = ARBITRARY_UNCERTAINTY_MILLIS + 1;
+ NetworkTimeSuggestion four = new NetworkTimeSuggestion(
+ ARBITRARY_TIME, differentUncertainty);
+ assertNotEquals(one, four);
+ assertNotEquals(four, 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() {
- NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(ARBITRARY_TIME);
- assertRoundTripParcelable(suggestion);
-
- // DebugInfo should also be stored (but is not checked by equals()
- suggestion.addDebugInfo("This is debug info");
- NetworkTimeSuggestion rtSuggestion = roundTripParcelable(suggestion);
- assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
- }
-
@Test(expected = IllegalArgumentException.class)
public void testParseCommandLineArg_noReferenceTime() {
ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
- "--unix_epoch_time 12345");
+ "--unix_epoch_time 12345 --uncertainty_millis 111");
NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
}
@Test(expected = IllegalArgumentException.class)
public void testParseCommandLineArg_noUnixEpochTime() {
ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
- "--reference_time 54321");
+ "--reference_time 54321 --uncertainty_millis 111");
+ NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testParseCommandLineArg_noUncertaintyMillis() {
+ ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+ "--reference_time 54321 --unix_epoch_time 12345");
NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
}
@Test
public void testParseCommandLineArg_validSuggestion() {
ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
- "--reference_time 54321 --unix_epoch_time 12345");
+ "--reference_time 54321 --unix_epoch_time 12345 --uncertainty_millis 111");
TimestampedValue<Long> timeSignal = new TimestampedValue<>(54321L, 12345L);
- NetworkTimeSuggestion expectedSuggestion = new NetworkTimeSuggestion(timeSignal);
+ NetworkTimeSuggestion expectedSuggestion = new NetworkTimeSuggestion(timeSignal, 111);
NetworkTimeSuggestion actualSuggestion =
NetworkTimeSuggestion.parseCommandLineArg(testShellCommand);
assertEquals(expectedSuggestion, actualSuggestion);
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
index 06512fbfed06..f8092a67e8c7 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorInternalImplTest.java
@@ -20,6 +20,7 @@ import static org.mockito.Mockito.mock;
import android.content.Context;
import android.os.HandlerThread;
+import android.os.TimestampedValue;
import androidx.test.runner.AndroidJUnit4;
@@ -55,14 +56,41 @@ public class TimeDetectorInternalImplTest {
mMockContext, mTestHandler, mFakeTimeDetectorStrategy);
}
- @Test
- public void placeholder() {
- // A placeholder test until there are real methods to test.
- }
-
@After
public void tearDown() throws Exception {
mHandlerThread.quit();
mHandlerThread.join();
}
+
+ @Test
+ public void testSuggestNetworkTime() throws Exception {
+ NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
+
+ mTimeDetectorInternal.suggestNetworkTime(networkTimeSuggestion);
+ mTestHandler.assertTotalMessagesEnqueued(1);
+
+ mTestHandler.waitForMessagesToBeProcessed();
+ mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(networkTimeSuggestion);
+ }
+
+ private static NetworkTimeSuggestion createNetworkTimeSuggestion() {
+ TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
+ return new NetworkTimeSuggestion(timeValue, 123);
+ }
+
+ @Test
+ public void testSuggestGnssTime() throws Exception {
+ GnssTimeSuggestion gnssTimeSuggestion = createGnssTimeSuggestion();
+
+ mTimeDetectorInternal.suggestGnssTime(gnssTimeSuggestion);
+ mTestHandler.assertTotalMessagesEnqueued(1);
+
+ mTestHandler.waitForMessagesToBeProcessed();
+ mFakeTimeDetectorStrategy.verifySuggestGnssTimeCalled(gnssTimeSuggestion);
+ }
+
+ private static GnssTimeSuggestion createGnssTimeSuggestion() {
+ TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
+ return new GnssTimeSuggestion(timeValue);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 702ebeb3a4f9..b9c74baaf3d3 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -38,9 +38,7 @@ import static org.mockito.Mockito.when;
import android.app.time.ExternalTimeSuggestion;
import android.app.time.ITimeDetectorListener;
import android.app.time.TimeConfiguration;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.app.timedetector.TimePoint;
import android.content.Context;
@@ -63,6 +61,7 @@ import org.junit.runner.RunWith;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.net.InetSocketAddress;
import java.time.Instant;
@RunWith(AndroidJUnit4.class)
@@ -319,10 +318,10 @@ public class TimeDetectorServiceTest {
public void testSuggestNetworkTime_withoutPermission() {
doThrow(new SecurityException("Mock"))
.when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
- NetworkTimeSuggestion NetworkTimeSuggestion = createNetworkTimeSuggestion();
+ NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
try {
- mTimeDetectorService.suggestNetworkTime(NetworkTimeSuggestion);
+ mTimeDetectorService.suggestNetworkTime(networkTimeSuggestion);
fail();
} finally {
verify(mMockContext).enforceCallingOrSelfPermission(
@@ -334,15 +333,15 @@ public class TimeDetectorServiceTest {
public void testSuggestNetworkTime() throws Exception {
doNothing().when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
- NetworkTimeSuggestion NetworkTimeSuggestion = createNetworkTimeSuggestion();
- mTimeDetectorService.suggestNetworkTime(NetworkTimeSuggestion);
+ NetworkTimeSuggestion networkTimeSuggestion = createNetworkTimeSuggestion();
+ mTimeDetectorService.suggestNetworkTime(networkTimeSuggestion);
mTestHandler.assertTotalMessagesEnqueued(1);
verify(mMockContext).enforceCallingOrSelfPermission(
eq(android.Manifest.permission.SET_TIME), anyString());
mTestHandler.waitForMessagesToBeProcessed();
- mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(NetworkTimeSuggestion);
+ mFakeTimeDetectorStrategy.verifySuggestNetworkTimeCalled(networkTimeSuggestion);
}
@Test(expected = SecurityException.class)
@@ -407,8 +406,8 @@ public class TimeDetectorServiceTest {
@Test
public void testLatestNetworkTime() {
- NtpTrustedTime.TimeResult latestNetworkTime =
- new NtpTrustedTime.TimeResult(1234L, 54321L, 999L);
+ NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
+ 1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
when(mMockNtpTrustedTime.getCachedTimeResult())
.thenReturn(latestNetworkTime);
TimePoint expected = new TimePoint(latestNetworkTime.getTimeMillis(),
@@ -467,7 +466,7 @@ public class TimeDetectorServiceTest {
private static NetworkTimeSuggestion createNetworkTimeSuggestion() {
TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
- return new NetworkTimeSuggestion(timeValue);
+ return new NetworkTimeSuggestion(timeValue, 123);
}
private static GnssTimeSuggestion createGnssTimeSuggestion() {
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index 15a8996aef4c..aeb5c65c8692 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -29,9 +29,7 @@ import static org.junit.Assert.fail;
import android.annotation.UserIdInt;
import android.app.time.ExternalTimeSuggestion;
-import android.app.timedetector.GnssTimeSuggestion;
import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.NetworkTimeSuggestion;
import android.app.timedetector.TelephonyTimeSuggestion;
import android.os.TimestampedValue;
@@ -1573,7 +1571,7 @@ public class TimeDetectorStrategyImplTest {
new TimestampedValue<>(
mFakeEnvironment.peekElapsedRealtimeMillis(),
suggestedTime.toEpochMilli());
- return new NetworkTimeSuggestion(unixEpochTime);
+ return new NetworkTimeSuggestion(unixEpochTime, 123);
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java
index 79f8b0e8d4c8..0f667b3a690b 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/GeolocationTimeZoneSuggestionTest.java
@@ -16,8 +16,13 @@
package com.android.server.timezonedetector;
+import static com.android.server.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+import android.os.ShellCommand;
import org.junit.Test;
@@ -66,4 +71,40 @@ public class GeolocationTimeZoneSuggestionTest {
assertNotEquals(certain1v1, certain3);
assertNotEquals(certain3, certain1v1);
}
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testParseCommandLineArg_noZoneIdsArg() {
+ ShellCommand testShellCommand =
+ createShellCommandWithArgsAndOptions(Collections.emptyList());
+ GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
+ }
+
+ @Test
+ public void testParseCommandLineArg_zoneIdsUncertain() {
+ ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+ "--zone_ids UNCERTAIN");
+ assertNull(GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand)
+ .getZoneIds());
+ }
+
+ @Test
+ public void testParseCommandLineArg_zoneIdsEmpty() {
+ ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("--zone_ids EMPTY");
+ assertEquals(Collections.emptyList(),
+ GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand).getZoneIds());
+ }
+
+ @Test
+ public void testParseCommandLineArg_zoneIdsPresent() {
+ ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
+ "--zone_ids Europe/London,Europe/Paris");
+ assertEquals(Arrays.asList("Europe/London", "Europe/Paris"),
+ GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand).getZoneIds());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testParseCommandLineArg_unknownArgument() {
+ ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("--bad_arg 0");
+ GeolocationTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java
new file mode 100644
index 000000000000..b96c82fc396c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ShellCommandTestSupport.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.timezonedetector;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.os.ShellCommand;
+
+import org.mockito.stubbing.Answer;
+
+import java.util.Arrays;
+import java.util.List;
+
+/** Utility methods related to {@link ShellCommand} objects used in several tests. */
+public final class ShellCommandTestSupport {
+ private ShellCommandTestSupport() {}
+
+ public static ShellCommand createShellCommandWithArgsAndOptions(String argsWithSpaces) {
+ return createShellCommandWithArgsAndOptions(Arrays.asList(argsWithSpaces.split(" ")));
+ }
+
+ public static ShellCommand createShellCommandWithArgsAndOptions(List<String> args) {
+ ShellCommand command = mock(ShellCommand.class);
+ class ArgProvider {
+ private int mCount;
+
+ String getNext() {
+ if (mCount >= args.size()) {
+ return null;
+ }
+ return args.get(mCount++);
+ }
+
+ String getNextRequired() {
+ String next = getNext();
+ if (next == null) {
+ throw new IllegalArgumentException("No next");
+ }
+ return next;
+ }
+ }
+ ArgProvider argProvider = new ArgProvider();
+ when(command.getNextArg()).thenAnswer(
+ (Answer<String>) invocation -> argProvider.getNext());
+ when(command.getNextOption()).thenAnswer(
+ (Answer<String>) invocation -> argProvider.getNext());
+ when(command.getNextArgRequired()).thenAnswer(
+ (Answer<String>) invocation -> argProvider.getNextRequired());
+ return command;
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index d4886e440c41..f2b1dc9132d5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -18,6 +18,7 @@ package com.android.server.notification;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
@@ -74,6 +75,8 @@ public class PermissionHelperTest extends UiServiceTestCase {
private PermissionHelper mPermissionHelper;
+ private static final int USER_FLAG_MASK = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -183,7 +186,7 @@ public class PermissionHelperTest extends UiServiceTestCase {
verify(mPermManager).grantRuntimePermission(
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
- FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
+ USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
FLAG_PERMISSION_USER_SET, true, 10);
}
@@ -202,7 +205,7 @@ public class PermissionHelperTest extends UiServiceTestCase {
verify(mPermManager).grantRuntimePermission(
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
- FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
+ USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
FLAG_PERMISSION_USER_SET, true, 10);
}
@@ -216,7 +219,7 @@ public class PermissionHelperTest extends UiServiceTestCase {
verify(mPermManager).revokeRuntimePermission(
eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
- FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
+ USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT,
FLAG_PERMISSION_USER_SET, true, 10);
}
@@ -230,7 +233,7 @@ public class PermissionHelperTest extends UiServiceTestCase {
verify(mPermManager).grantRuntimePermission(
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
- FLAG_PERMISSION_USER_SET, 0, true, 10);
+ USER_FLAG_MASK, 0, true, 10);
}
@Test
@@ -243,7 +246,7 @@ public class PermissionHelperTest extends UiServiceTestCase {
verify(mPermManager).revokeRuntimePermission(
eq("pkg"), eq(Manifest.permission.POST_NOTIFICATIONS), eq(10), anyString());
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
- FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0,
+ USER_FLAG_MASK | FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0,
true, 10);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 8bead5774548..7817e8176e76 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -20,6 +20,7 @@ import static com.android.server.notification.SnoozeHelper.EXTRA_KEY;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
@@ -39,7 +40,6 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
@@ -50,7 +50,6 @@ import android.util.Xml;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.util.FastXmlSerializer;
import com.android.server.UiServiceTestCase;
import com.android.server.pm.PackageManagerService;
@@ -60,9 +59,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -198,18 +195,6 @@ public class SnoozeHelperTest extends UiServiceTestCase {
}
@Test
- public void testCleanupContextShouldRemovePersistedRecord() {
- NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
- mSnoozeHelper.snooze(r, "context");
- mSnoozeHelper.cleanupPersistedContext(r.getSbn().getKey());
- assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
- r.getUser().getIdentifier(),
- r.getSbn().getPackageName(),
- r.getSbn().getKey()
- ));
- }
-
- @Test
public void testReadNoneSnoozedNotification() throws XmlPullParserException,
IOException, InterruptedException {
NotificationRecord r = getNotificationRecord(
@@ -219,8 +204,9 @@ public class SnoozeHelperTest extends UiServiceTestCase {
assertEquals("should see a zero value for unsnoozed notification",
0L,
mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
- UserHandle.SYSTEM.getIdentifier(),
- "not_my_package", r.getKey()).longValue());
+ UserHandle.SYSTEM.getIdentifier(), "not_my_package",
+ getNotificationRecord("not_my_package", 1, "one",
+ UserHandle.SYSTEM).getKey()).longValue());
}
@Test
@@ -592,7 +578,7 @@ public class SnoozeHelperTest extends UiServiceTestCase {
}
@Test
- public void testClearData() {
+ public void testClearData_userPackage() {
// snooze 2 from same package
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM);
@@ -616,17 +602,72 @@ public class SnoozeHelperTest extends UiServiceTestCase {
}
@Test
+ public void testClearData_user() {
+ // snooze 2 from same package
+ NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+ NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two", UserHandle.SYSTEM);
+ NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
+ NotificationRecord r4 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
+ mSnoozeHelper.snooze(r, 1000);
+ mSnoozeHelper.snooze(r2, 1000);
+ mSnoozeHelper.snooze(r3, "until");
+ mSnoozeHelper.snooze(r4, "until");
+
+ assertTrue(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
+ assertTrue(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
+ assertTrue(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
+ assertTrue(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_ALL, r4.getSbn().getPackageName(), r4.getKey()));
+
+ // clear data
+ mSnoozeHelper.clearData(UserHandle.USER_SYSTEM);
+
+ // nothing in USER_SYSTEM snoozed; alarms canceled
+ assertFalse(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
+ assertFalse(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r2.getSbn().getPackageName(), r2.getKey()));
+ assertFalse(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
+ assertTrue(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, r4.getSbn().getPackageName(), r4.getKey()));
+
+ assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+ r3.getUser().getIdentifier(), r3.getSbn().getPackageName(),
+ r3.getSbn().getKey()));
+ assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+ r4.getUser().getIdentifier(), r4.getSbn().getPackageName(),
+ r4.getSbn().getKey()));
+ assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+ r.getUser().getIdentifier(), r.getSbn().getPackageName(),
+ r.getSbn().getKey()).longValue());
+ assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+ r2.getUser().getIdentifier(), r2.getSbn().getPackageName(),
+ r2.getSbn().getKey()).longValue());
+
+ // 2 for initial timed-snoozes, once each for canceling the USER_SYSTEM snoozes
+ verify(mAm, times(5)).cancel(any(PendingIntent.class));
+ }
+
+ @Test
public void testClearData_otherRecordsUntouched() {
// 2 packages, 2 users
NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+ NotificationRecord rb = getNotificationRecord("pkg", 1, "oneb", UserHandle.SYSTEM);
NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL);
NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM);
mSnoozeHelper.snooze(r, 1000);
+ mSnoozeHelper.snooze(rb, "until");
mSnoozeHelper.snooze(r2, 1000);
mSnoozeHelper.snooze(r3, 1000);
assertTrue(mSnoozeHelper.isSnoozed(
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
assertTrue(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey()));
+ assertTrue(mSnoozeHelper.isSnoozed(
UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
assertTrue(mSnoozeHelper.isSnoozed(
UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
@@ -636,12 +677,22 @@ public class SnoozeHelperTest extends UiServiceTestCase {
assertFalse(mSnoozeHelper.isSnoozed(
UserHandle.USER_SYSTEM, r.getSbn().getPackageName(), r.getKey()));
+ assertFalse(mSnoozeHelper.isSnoozed(
+ UserHandle.USER_SYSTEM, rb.getSbn().getPackageName(), rb.getKey()));
assertTrue(mSnoozeHelper.isSnoozed(
UserHandle.USER_ALL, r2.getSbn().getPackageName(), r2.getKey()));
assertTrue(mSnoozeHelper.isSnoozed(
UserHandle.USER_SYSTEM, r3.getSbn().getPackageName(), r3.getKey()));
+
+ assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification(
+ rb.getUser().getIdentifier(), rb.getSbn().getPackageName(),
+ rb.getSbn().getKey()));
+ assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
+ r.getUser().getIdentifier(), r.getSbn().getPackageName(),
+ r.getSbn().getKey()).longValue());
+
// once for each initial snooze, once for canceling one snooze
- verify(mAm, times(4)).cancel(any(PendingIntent.class));
+ verify(mAm, times(5)).cancel(any(PendingIntent.class));
}
private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 5b909a343a59..1d52b7f540a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.content.ComponentName.createRelative;
+import static android.view.WindowManager.TRANSIT_OPEN;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -75,6 +76,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
private ActivityRecord mTrampolineActivity;
private ActivityRecord mTopActivity;
private ActivityOptions mActivityOptions;
+ private Transition mTransition;
private boolean mLaunchTopByTrampoline;
private boolean mNewActivityCreated = true;
private long mExpectedStartedId;
@@ -98,6 +100,11 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
.setTask(mTrampolineActivity.getTask())
.setComponent(createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, "TopActivity"))
.build();
+ mTopActivity.mDisplayContent.mOpeningApps.add(mTopActivity);
+ mTransition = new Transition(TRANSIT_OPEN, 0 /* flags */,
+ mTopActivity.mTransitionController, createTestBLASTSyncEngine());
+ mTransition.mParticipants.add(mTopActivity);
+ mTopActivity.mTransitionController.moveToCollecting(mTransition);
// becomes invisible when covered by mTopActivity
mTrampolineActivity.mVisibleRequested = false;
}
@@ -437,11 +444,13 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
@Test
public void testActivityDrawnBeforeTransition() {
mTopActivity.setVisible(false);
- notifyActivityLaunching(mTopActivity.intent);
+ onIntentStarted(mTopActivity.intent);
// Assume the activity is launched the second time consecutively. The drawn event is from
// the first time (omitted in test) launch that is earlier than transition.
doReturn(true).when(mTopActivity).isReportedDrawn();
notifyWindowsDrawn(mTopActivity);
+ verifyNoMoreInteractions(mLaunchObserver);
+
notifyActivityLaunched(START_SUCCESS, mTopActivity);
// If the launching activity was drawn when starting transition, the launch event should
// be reported successfully.
@@ -452,6 +461,18 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
}
@Test
+ public void testActivityDrawnWithoutTransition() {
+ mTopActivity.mDisplayContent.mOpeningApps.remove(mTopActivity);
+ mTransition.mParticipants.remove(mTopActivity);
+ onIntentStarted(mTopActivity.intent);
+ notifyAndVerifyActivityLaunched(mTopActivity);
+ notifyWindowsDrawn(mTopActivity);
+ // Even if there is no notifyTransitionStarting, the launch event can still be reported
+ // because the drawn activity is not involved in transition.
+ verifyOnActivityLaunchFinished(mTopActivity);
+ }
+
+ @Test
public void testConcurrentLaunches() {
onActivityLaunched(mTopActivity);
clearInvocations(mLaunchObserver);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index f2d6273f2b26..513791d2b8a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -47,6 +47,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
@@ -89,6 +90,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
+ assumeFalse(WindowManagerService.sEnableShellTransitions);
mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 40e266c71328..11a7c7ddf778 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2118,7 +2118,6 @@ public class DisplayContentTests extends WindowTestsBase {
final WindowState appWin2 = createWindow(null, TYPE_BASE_APPLICATION, act2, "appWin2");
appWin2.setHasSurface(true);
assertTrue(appWin2.canBeImeTarget());
- doReturn(true).when(appWin1).isClosing();
doReturn(true).when(appWin1).inTransitionSelfOrParent();
// Test step 3: Verify appWin2 will be the next IME target and the IME snapshot surface will
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index ffa21fadff6b..6c161cf088f7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -27,6 +27,7 @@ import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -44,12 +45,15 @@ import static org.mockito.Mockito.verify;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
+import android.util.SparseArray;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.InsetsVisibilities;
import androidx.test.filters.SmallTest;
+import com.android.internal.util.function.TriConsumer;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -269,15 +273,18 @@ public class InsetsStateControllerTest extends WindowTestsBase {
@Test
public void testImeForDispatch() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+ final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
// IME cannot be the IME target.
ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
WindowContainerInsetsSourceProvider statusBarProvider =
getController().getSourceProvider(ITYPE_STATUS_BAR);
- statusBarProvider.setWindowContainer(statusBar, null, ((displayFrames, windowState, rect) ->
+ final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverrideProviders =
+ new SparseArray<>();
+ imeOverrideProviders.put(TYPE_INPUT_METHOD, ((displayFrames, windowState, rect) ->
rect.set(0, 1, 2, 3)));
+ statusBarProvider.setWindowContainer(statusBar, null, imeOverrideProviders);
getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
statusBar.setControllableInsetProvider(statusBarProvider);
statusBar.updateSourceFrame(statusBar.getFrame());
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 1a64f5e3a356..685a8f4a1f5a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -29,8 +29,6 @@ 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;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
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.never;
@@ -48,7 +46,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
@@ -81,11 +78,6 @@ public class WindowManagerServiceTests extends WindowTestsBase {
@Rule
public ExpectedException mExpectedException = ExpectedException.none();
- private boolean isAutomotive() {
- return getInstrumentation().getTargetContext().getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_AUTOMOTIVE);
- }
-
@Test
public void testAddWindowToken() {
IBinder token = mock(IBinder.class);
@@ -301,7 +293,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
mWm.setInTouchMode(!currentTouchMode);
verify(mWm.mInputManager).setInTouchMode(
- !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true);
+ !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true,
+ DEFAULT_DISPLAY);
}
@Test
@@ -316,7 +309,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
mWm.setInTouchMode(!currentTouchMode);
verify(mWm.mInputManager).setInTouchMode(
- !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false);
+ !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false,
+ DEFAULT_DISPLAY);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 446ec8b2680b..334cfd5fbb8f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -664,12 +664,11 @@ public class WindowStateTests extends WindowTestsBase {
assertEquals(expectedChildPos, childPos);
// Surface should apply the scale.
+ final SurfaceControl.Transaction t = w.getPendingTransaction();
w.prepareSurfaces();
- verify(w.getPendingTransaction()).setMatrix(w.getSurfaceControl(),
- overrideScale, 0, 0, overrideScale);
+ verify(t).setMatrix(w.mSurfaceControl, overrideScale, 0, 0, overrideScale);
// Child surface inherits parent's scale, so it doesn't need to scale.
- verify(child.getPendingTransaction(), never()).setMatrix(any(), anyInt(), anyInt(),
- anyInt(), anyInt());
+ verify(t, never()).setMatrix(any(), anyInt(), anyInt(), anyInt(), anyInt());
// According to "dp * density / 160 = px", density is scaled and the size in dp is the same.
final CompatibilityInfo compatInfo = cmp.compatibilityInfoForPackageLocked(
@@ -686,6 +685,13 @@ public class WindowStateTests extends WindowTestsBase {
final Rect unscaledClientBounds = new Rect(clientConfig.windowConfiguration.getBounds());
unscaledClientBounds.scale(overrideScale);
assertEquals(w.getWindowConfiguration().getBounds(), unscaledClientBounds);
+
+ // Child window without scale (e.g. different app) should apply inverse scale of parent.
+ doReturn(1f).when(cmp).getCompatScale(anyString(), anyInt());
+ final WindowState child2 = createWindow(w, TYPE_APPLICATION_SUB_PANEL, "child2");
+ clearInvocations(t);
+ child2.prepareSurfaces();
+ verify(t).setMatrix(child2.mSurfaceControl, w.mInvGlobalScale, 0, 0, w.mInvGlobalScale);
}
@UseTestDisplay(addWindows = {W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE})
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 84bfff6e592a..a0b01a7fc27d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2377,10 +2377,9 @@ public class UsageStatsService extends SystemService implements
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
@Override
public void setAppStandbyBucket(String packageName, int bucket, int userId) {
- getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
- "No permission to change app standby state");
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
@@ -2426,10 +2425,9 @@ public class UsageStatsService extends SystemService implements
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
@Override
public void setAppStandbyBuckets(ParceledListSlice appBuckets, int userId) {
- getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
- "No permission to change app standby state");
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
@@ -2477,12 +2475,10 @@ public class UsageStatsService extends SystemService implements
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE)
@Override
public void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime,
int userId) {
- getContext().enforceCallingPermission(
- Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE,
- "No permission to change app launch estimates");
final long token = Binder.clearCallingIdentity();
try {
@@ -2493,11 +2489,9 @@ public class UsageStatsService extends SystemService implements
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE)
@Override
public void setEstimatedLaunchTimes(ParceledListSlice estimatedLaunchTimes, int userId) {
- getContext().enforceCallingPermission(
- Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE,
- "No permission to change app launch estimates");
final long token = Binder.clearCallingIdentity();
try {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index bcfee82000a4..7699262f6bce 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1149,9 +1149,9 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public void setDisabled(boolean disabled) {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
if (mTemporarilyDisabled == disabled) {
if (DEBUG) Slog.d(TAG, "setDisabled(): already " + disabled);
@@ -1207,6 +1207,7 @@ public class VoiceInteractionManagerService extends SystemService {
//----------------- Hotword Detection/Validation APIs --------------------------------//
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION)
@Override
public void updateState(
@NonNull Identity voiceInteractorIdentity,
@@ -1214,7 +1215,6 @@ public class VoiceInteractionManagerService extends SystemService {
@Nullable SharedMemory sharedMemory,
IHotwordRecognitionStatusCallback callback,
int detectorType) {
- enforceCallingPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION);
synchronized (this) {
enforceIsCurrentVoiceInteractionService();
@@ -1256,13 +1256,12 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD})
@Override
public void startListeningFromMic(
AudioFormat audioFormat,
IMicrophoneHotwordDetectionVoiceInteractionCallback callback)
throws RemoteException {
- enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
- enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
synchronized (this) {
enforceIsCurrentVoiceInteractionService();
@@ -1322,13 +1321,12 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD})
@Override
public void triggerHardwareRecognitionEventForTest(
SoundTrigger.KeyphraseRecognitionEvent event,
IHotwordRecognitionStatusCallback callback)
throws RemoteException {
- enforceCallingPermission(Manifest.permission.RECORD_AUDIO);
- enforceCallingPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD);
synchronized (this) {
enforceIsCurrentVoiceInteractionService();
@@ -1669,10 +1667,10 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public boolean showSessionForActiveService(Bundle args, int sourceFlags,
IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
if (DEBUG_USER) Slog.d(TAG, "showSessionForActiveService()");
synchronized (this) {
@@ -1700,9 +1698,9 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public void hideCurrentSession() throws RemoteException {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
if (mImpl == null) {
return;
@@ -1721,9 +1719,9 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public void launchVoiceAssistFromKeyguard() {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
if (mImpl == null) {
Slog.w(TAG, "launchVoiceAssistFromKeyguard without running voice interaction"
@@ -1739,34 +1737,34 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public boolean isSessionRunning() {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
return mImpl != null && mImpl.mActiveSession != null;
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public boolean activeServiceSupportsAssist() {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
return mImpl != null && mImpl.mInfo != null && mImpl.mInfo.getSupportsAssist();
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public boolean activeServiceSupportsLaunchFromKeyguard() throws RemoteException {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
return mImpl != null && mImpl.mInfo != null
&& mImpl.mInfo.getSupportsLaunchFromKeyguard();
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public void onLockscreenShown() {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
if (mImpl == null) {
return;
@@ -1786,19 +1784,19 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public void registerVoiceInteractionSessionListener(
IVoiceInteractionSessionListener listener) {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
mVoiceInteractionSessionListeners.register(listener);
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
@Override
public void getActiveServiceSupportedActions(List<String> voiceActions,
IVoiceActionCheckCallback callback) {
- enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
if (mImpl == null) {
try {
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 37b4e657973b..d1d16ff8b641 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -495,6 +495,9 @@ public abstract class CallScreeningService extends Service {
* Note: Calls will still be logged with type
* {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
* is set.
+ * <p>
+ * Note: Only the carrier and system call screening apps can use this parameter;
+ * this parameter is ignored otherwise.
*/
public Builder setSkipCallLog(boolean shouldSkipCallLog) {
mShouldSkipCallLog = shouldSkipCallLog;
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 0f7dde5a18d9..9fcf44e36337 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1269,7 +1269,7 @@ public class TelecomManager {
if (service != null) {
try {
return service.getPhoneAccountsSupportingScheme(uriScheme,
- mContext.getOpPackageName());
+ mContext.getOpPackageName()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e);
}
@@ -1312,7 +1312,7 @@ public class TelecomManager {
if (service != null) {
try {
return service.getSelfManagedPhoneAccounts(mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getSelfManagedPhoneAccounts()", e);
}
@@ -1340,7 +1340,7 @@ public class TelecomManager {
if (service != null) {
try {
return service.getOwnSelfManagedPhoneAccounts(mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag()).getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1366,7 +1366,7 @@ public class TelecomManager {
if (service != null) {
try {
return service.getCallCapablePhoneAccounts(includeDisabledAccounts,
- mContext.getOpPackageName(), mContext.getAttributionTag());
+ mContext.getOpPackageName(), mContext.getAttributionTag()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts("
+ includeDisabledAccounts + ")", e);
@@ -1390,7 +1390,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getPhoneAccountsForPackage(mContext.getPackageName());
+ return service.getPhoneAccountsForPackage(mContext.getPackageName()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
}
@@ -1450,7 +1450,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getAllPhoneAccounts();
+ return service.getAllPhoneAccounts().getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
}
@@ -1469,7 +1469,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getAllPhoneAccountHandles();
+ return service.getAllPhoneAccountHandles().getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 101280abce85..f1a6dd1d769d 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -24,6 +24,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.telecom.PhoneAccount;
+import android.content.pm.ParceledListSlice;
/**
* Interface used to interact with Telecom. Mostly this is used by TelephonyManager for passing
@@ -57,31 +58,31 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#getCallCapablePhoneAccounts
*/
- List<PhoneAccountHandle> getCallCapablePhoneAccounts(
+ ParceledListSlice<PhoneAccountHandle> getCallCapablePhoneAccounts(
boolean includeDisabledAccounts, String callingPackage, String callingFeatureId);
/**
* @see TelecomServiceImpl#getSelfManagedPhoneAccounts
*/
- List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage,
+ ParceledListSlice<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage,
String callingFeatureId);
/**
* @see TelecomServiceImpl#getOwnSelfManagedPhoneAccounts
*/
- List<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
+ ParceledListSlice<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
String callingFeatureId);
/**
* @see TelecomManager#getPhoneAccountsSupportingScheme
*/
- List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
+ ParceledListSlice<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
String callingPackage);
/**
* @see TelecomManager#getPhoneAccountsForPackage
*/
- List<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
+ ParceledListSlice<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
/**
* @see TelecomManager#getPhoneAccount
@@ -96,12 +97,12 @@ interface ITelecomService {
/**
* @see TelecomManager#getAllPhoneAccounts
*/
- List<PhoneAccount> getAllPhoneAccounts();
+ ParceledListSlice<PhoneAccount> getAllPhoneAccounts();
/**
* @see TelecomManager#getAllPhoneAccountHandles
*/
- List<PhoneAccountHandle> getAllPhoneAccountHandles();
+ ParceledListSlice<PhoneAccountHandle> getAllPhoneAccountHandles();
/**
* @see TelecomServiceImpl#getSimCallManager
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 24374ee64719..a7468a9d268d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8417,6 +8417,51 @@ public class TelephonyManager {
}
/**
+ * Fetches the sim service table from the EFUST/EFIST based on the application type
+ * {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}. The return value is hexaString format
+ * representing X bytes (x >= 1). Each bit of every byte indicates which optional services
+ * are available for the given application type.
+ * The USIM service table EF is described in as per Section 4.2.8 of 3GPP TS 31.102.
+ * The ISIM service table EF is described in as per Section 4.2.7 of 3GPP TS 31.103.
+ * The list of services mapped to the exact nth byte of response as mentioned in Section 4.2
+ * .7 of 3GPP TS 31.103. Eg. Service n°1: Local Phone Book, Service n°2: Fixed Dialling
+ * Numbers (FDN) - Bit 1 and 2 of the 1st Byte represent service Local Phone Book and Fixed
+ * Dialling Numbers (FDN)respectively. The coding format for each service type should be
+ * interpreted as bit = 1: service available;bit = 0:service not available.
+ *
+ * @param appType of type int of either {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}.
+ * @return HexString represents sim service table else null.
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ * @hide
+ */
+
+ @Nullable
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ public String getSimServiceTable(int appType) {
+ try {
+ IPhoneSubInfo info = getSubscriberInfoService();
+ if (info == null) {
+ Rlog.e(TAG, "getSimServiceTable(): IPhoneSubInfo is null");
+ return null;
+ }
+ //Fetches the sim service table based on subId and appType
+ if (appType == APPTYPE_ISIM) {
+ return info.getIsimIst(getSubId());
+ } else if ((appType == APPTYPE_USIM)) {
+ return info.getSimServiceTable(getSubId(), APPTYPE_USIM);
+ } else {
+ return null;
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getSimServiceTable(): RemoteException=" + ex.getMessage());
+ } catch (NullPointerException ex) {
+ Rlog.e(TAG, "getSimServiceTable(): NullPointerException=" + ex.getMessage());
+ }
+ return null;
+ }
+
+ /**
* Resets the {@link android.telephony.ims.ImsService} associated with the specified sim slot.
* Used by diagnostic apps to force the IMS stack to be disabled and re-enabled in an effort to
* recover from scenarios where the {@link android.telephony.ims.ImsService} gets in to a bad
@@ -15921,6 +15966,17 @@ public class TelephonyManager {
}
/**
+ * Setup sIPhoneSubInfo for testing.
+ * @hide
+ */
+ @VisibleForTesting
+ public static void setupIPhoneSubInfoForTest(IPhoneSubInfo iPhoneSubInfo) {
+ synchronized (sCacheLock) {
+ sIPhoneSubInfo = iPhoneSubInfo;
+ }
+ }
+
+ /**
* Whether device can connect to 5G network when two SIMs are active.
* @hide
* TODO b/153669716: remove or make system API.
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 78335fd54917..4fa7f43ddde4 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -232,4 +232,26 @@ interface IPhoneSubInfo {
*/
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
String getSmscIdentity(int subId, int appType);
+
+ /**
+ * Fetches the sim service table from the EFUST/EFIST based on the application type
+ * {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}. The return value is hexaString format
+ * representing X bytes (x >= 1). Each bit of every byte indicates which optional services
+ * are available for the given application type.
+ * The USIM service table EF is described in as per Section 4.2.8 of 3GPP TS 31.102.
+ * The ISIM service table EF is described in as per Section 4.2.7 of 3GPP TS 31.103.
+ * The list of services mapped to the exact nth byte of response as mentioned in Section 4.2
+ * .7 of 3GPP TS 31.103. Eg. Service n°1: Local Phone Book, Service n°2: Fixed Dialling
+ * Numbers (FDN) - Bit 1 and 2 of the 1st Byte represent service Local Phone Book and Fixed
+ * Dialling Numbers (FDN)respectively. The coding format for each service type should be
+ * interpreted as bit = 1: service available;bit = 0:service not available.
+ *
+ * @param appType of type int of either {@link #APPTYPE_USIM} or {@link #APPTYPE_ISIM}.
+ * @return HexString represents sim service table else null.
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ * @hide
+ */
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)")
+ String getSimServiceTable(int subId, int appType);
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
new file mode 100644
index 000000000000..24c46619d376
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Presubmit
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import org.junit.Assume
+import org.junit.Test
+
+/**
+ * Base test class containing common assertions for [ComponentMatcher.NAV_BAR],
+ * [ComponentMatcher.TASK_BAR], [ComponentMatcher.STATUS_BAR], and general assertions
+ * (layers visible in consecutive states, entire screen covered, etc.)
+ */
+abstract class BaseTest @JvmOverloads constructor(
+ protected val testSpec: FlickerTestParameter,
+ protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
+ protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
+) {
+ init {
+ testSpec.setIsTablet(
+ WindowManagerStateHelper(instrumentation).currentState.wmState.isTablet
+ )
+ }
+
+ /**
+ * Specification of the test transition to execute
+ */
+ abstract val transition: FlickerBuilder.() -> Unit
+
+ /**
+ * Entry point for the test runner. It will use this method to initialize and cache
+ * flicker executions
+ */
+ @FlickerBuilderProvider
+ fun buildFlicker(): FlickerBuilder {
+ return FlickerBuilder(instrumentation).apply {
+ setup {
+ test {
+ testSpec.setIsTablet(wmHelper.currentState.wmState.isTablet)
+ }
+ }
+ transition()
+ }
+ }
+
+ /**
+ * Checks that all parts of the screen are covered during the transition
+ */
+ @Presubmit
+ @Test
+ open fun entireScreenCovered() = testSpec.entireScreenCovered()
+
+ /**
+ * Checks that the [ComponentMatcher.NAV_BAR] layer is visible during the whole transition
+ *
+ * Note: Phones only
+ */
+ @Presubmit
+ @Test
+ open fun navBarLayerIsVisibleAtStartAndEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerIsVisibleAtStartAndEnd()
+ }
+
+ /**
+ * Checks the position of the [ComponentMatcher.NAV_BAR] at the start and end of the transition
+ *
+ * Note: Phones only
+ */
+ @Presubmit
+ @Test
+ open fun navBarLayerPositionAtStartAndEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerPositionAtStartAndEnd()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.NAV_BAR] window is visible during the whole transition
+ *
+ * Note: Phones only
+ */
+ @Presubmit
+ @Test
+ open fun navBarWindowIsAlwaysVisible() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarWindowIsAlwaysVisible()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.TASK_BAR] layer is visible during the whole transition
+ *
+ * Note: Large screen only
+ */
+ @Presubmit
+ @Test
+ open fun taskBarLayerIsVisibleAtStartAndEnd() {
+ Assume.assumeTrue(testSpec.isTablet)
+ testSpec.taskBarLayerIsVisibleAtStartAndEnd()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.TASK_BAR] window is visible during the whole transition
+ *
+ * Note: Large screen only
+ */
+ @Presubmit
+ @Test
+ open fun taskBarWindowIsAlwaysVisible() {
+ Assume.assumeTrue(testSpec.isTablet)
+ testSpec.taskBarWindowIsAlwaysVisible()
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible during the whole transition
+ */
+ @Presubmit
+ @Test
+ open fun statusBarLayerIsVisibleAtStartAndEnd() =
+ testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /**
+ * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the
+ * transition
+ */
+ @Presubmit
+ @Test
+ open fun statusBarLayerPositionAtStartAndEnd() = testSpec.statusBarLayerPositionAtStartAndEnd()
+
+ /**
+ * Checks that the [ComponentMatcher.STATUS_BAR] window is visible during the whole transition
+ */
+ @Presubmit
+ @Test
+ open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
+
+ /**
+ * Checks that all layers that are visible on the trace, are visible for at least 2
+ * consecutive entries.
+ */
+ @Presubmit
+ @Test
+ open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ testSpec.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry()
+ }
+ }
+
+ /**
+ * Checks that all windows that are visible on the trace, are visible for at least 2
+ * consecutive entries.
+ */
+ @Presubmit
+ @Test
+ open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ testSpec.assertWm {
+ this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index 2e97eb14249a..d173b7250548 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -19,25 +19,36 @@ package com.android.server.wm.flicker
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.common.IComponentMatcher
/**
- * Checks that [FlickerComponentName.STATUS_BAR] window is visible and above the app windows in
+ * Checks that [ComponentMatcher.STATUS_BAR] window is visible and above the app windows in
* all WM trace entries
*/
-fun FlickerTestParameter.statusBarWindowIsVisible() {
+fun FlickerTestParameter.statusBarWindowIsAlwaysVisible() {
assertWm {
- this.isAboveAppWindowVisible(FlickerComponentName.STATUS_BAR)
+ this.isAboveAppWindowVisible(ComponentMatcher.STATUS_BAR)
}
}
/**
- * Checks that [FlickerComponentName.NAV_BAR] window is visible and above the app windows in
+ * Checks that [ComponentMatcher.NAV_BAR] window is visible and above the app windows in
* all WM trace entries
*/
-fun FlickerTestParameter.navBarWindowIsVisible() {
+fun FlickerTestParameter.navBarWindowIsAlwaysVisible() {
assertWm {
- this.isAboveAppWindowVisible(FlickerComponentName.NAV_BAR)
+ this.isAboveAppWindowVisible(ComponentMatcher.NAV_BAR)
+ }
+}
+
+/**
+ * Checks that [ComponentMatcher.TASK_BAR] window is visible and above the app windows in
+ * all WM trace entries
+ */
+fun FlickerTestParameter.taskBarWindowIsAlwaysVisible() {
+ assertWm {
+ this.isAboveAppWindowVisible(ComponentMatcher.TASK_BAR)
}
}
@@ -75,113 +86,126 @@ fun FlickerTestParameter.entireScreenCovered(allStates: Boolean = true) {
}
/**
- * Checks that [FlickerComponentName.NAV_BAR] layer is visible at the start and end of the SF
+ * Checks that [ComponentMatcher.NAV_BAR] layer is visible at the start and end of the SF
+ * trace
+ */
+fun FlickerTestParameter.navBarLayerIsVisibleAtStartAndEnd() {
+ assertLayersStart {
+ this.isVisible(ComponentMatcher.NAV_BAR)
+ }
+ assertLayersEnd {
+ this.isVisible(ComponentMatcher.NAV_BAR)
+ }
+}
+
+/**
+ * Checks that [ComponentMatcher.TASK_BAR] layer is visible at the start and end of the SF
* trace
*/
-fun FlickerTestParameter.navBarLayerIsVisible() {
+fun FlickerTestParameter.taskBarLayerIsVisibleAtStartAndEnd() {
assertLayersStart {
- this.isVisible(FlickerComponentName.NAV_BAR)
+ this.isVisible(ComponentMatcher.TASK_BAR)
}
assertLayersEnd {
- this.isVisible(FlickerComponentName.NAV_BAR)
+ this.isVisible(ComponentMatcher.TASK_BAR)
}
}
/**
- * Checks that [FlickerComponentName.STATUS_BAR] layer is visible at the start and end of the SF
+ * Checks that [ComponentMatcher.STATUS_BAR] layer is visible at the start and end of the SF
* trace
*/
-fun FlickerTestParameter.statusBarLayerIsVisible() {
+fun FlickerTestParameter.statusBarLayerIsVisibleAtStartAndEnd() {
assertLayersStart {
- this.isVisible(FlickerComponentName.STATUS_BAR)
+ this.isVisible(ComponentMatcher.STATUS_BAR)
}
assertLayersEnd {
- this.isVisible(FlickerComponentName.STATUS_BAR)
+ this.isVisible(ComponentMatcher.STATUS_BAR)
}
}
/**
- * Asserts that the [FlickerComponentName.NAV_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.NAV_BAR] layer is at the correct position at the start
* of the SF trace
*/
-fun FlickerTestParameter.navBarLayerPositionStart() {
+fun FlickerTestParameter.navBarLayerPositionAtStart() {
assertLayersStart {
val display = this.entry.displays.firstOrNull { !it.isVirtual }
?: error("There is no display!")
- this.visibleRegion(FlickerComponentName.NAV_BAR)
+ this.visibleRegion(ComponentMatcher.NAV_BAR)
.coversExactly(WindowUtils.getNavigationBarPosition(display, isGesturalNavigation))
}
}
/**
- * Asserts that the [FlickerComponentName.NAV_BAR] layer is at the correct position at the end
+ * Asserts that the [ComponentMatcher.NAV_BAR] layer is at the correct position at the end
* of the SF trace
*/
-fun FlickerTestParameter.navBarLayerPositionEnd() {
+fun FlickerTestParameter.navBarLayerPositionAtEnd() {
assertLayersEnd {
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
- this.visibleRegion(FlickerComponentName.NAV_BAR)
+ this.visibleRegion(ComponentMatcher.NAV_BAR)
.coversExactly(WindowUtils.getNavigationBarPosition(display, isGesturalNavigation))
}
}
/**
- * Asserts that the [FlickerComponentName.NAV_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.NAV_BAR] layer is at the correct position at the start
* and end of the SF trace
*/
-fun FlickerTestParameter.navBarLayerRotatesAndScales() {
- navBarLayerPositionStart()
- navBarLayerPositionEnd()
+fun FlickerTestParameter.navBarLayerPositionAtStartAndEnd() {
+ navBarLayerPositionAtStart()
+ navBarLayerPositionAtEnd()
}
/**
- * Asserts that the [FlickerComponentName.STATUS_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.STATUS_BAR] layer is at the correct position at the start
* of the SF trace
*/
-fun FlickerTestParameter.statusBarLayerPositionStart() {
+fun FlickerTestParameter.statusBarLayerPositionAtStart() {
assertLayersStart {
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
- this.visibleRegion(FlickerComponentName.STATUS_BAR)
+ this.visibleRegion(ComponentMatcher.STATUS_BAR)
.coversExactly(WindowUtils.getStatusBarPosition(display))
}
}
/**
- * Asserts that the [FlickerComponentName.STATUS_BAR] layer is at the correct position at the end
+ * Asserts that the [ComponentMatcher.STATUS_BAR] layer is at the correct position at the end
* of the SF trace
*/
-fun FlickerTestParameter.statusBarLayerPositionEnd() {
+fun FlickerTestParameter.statusBarLayerPositionAtEnd() {
assertLayersEnd {
val display = this.entry.displays.minByOrNull { it.id }
?: throw RuntimeException("There is no display!")
- this.visibleRegion(FlickerComponentName.STATUS_BAR)
+ this.visibleRegion(ComponentMatcher.STATUS_BAR)
.coversExactly(WindowUtils.getStatusBarPosition(display))
}
}
/**
- * Asserts that the [FlickerComponentName.STATUS_BAR] layer is at the correct position at the start
+ * Asserts that the [ComponentMatcher.STATUS_BAR] layer is at the correct position at the start
* and end of the SF trace
*/
-fun FlickerTestParameter.statusBarLayerRotatesScales() {
- statusBarLayerPositionStart()
- statusBarLayerPositionEnd()
+fun FlickerTestParameter.statusBarLayerPositionAtStartAndEnd() {
+ statusBarLayerPositionAtStart()
+ statusBarLayerPositionAtEnd()
}
/**
- * Asserts that the visibleRegion of the [FlickerComponentName.SNAPSHOT] layer can cover
+ * Asserts that the visibleRegion of the [ComponentMatcher.SNAPSHOT] layer can cover
* the visibleRegion of the given app component exactly
*/
fun FlickerTestParameter.snapshotStartingWindowLayerCoversExactlyOnApp(
- component: FlickerComponentName
+ component: IComponentMatcher
) {
assertLayers {
invoke("snapshotStartingWindowLayerCoversExactlyOnApp") {
val snapshotLayers = it.subjects.filter { subject ->
subject.name.contains(
- FlickerComponentName.SNAPSHOT.toLayerName()) && subject.isVisible
+ ComponentMatcher.SNAPSHOT.toLayerName()) && subject.isVisible
}
// Verify the size of snapshotRegion covers appVisibleRegion exactly in animation.
if (snapshotLayers.isNotEmpty()) {
@@ -218,8 +242,8 @@ fun FlickerTestParameter.snapshotStartingWindowLayerCoversExactlyOnApp(
* otherwise we won't and the layer must appear immediately.
*/
fun FlickerTestParameter.replacesLayer(
- originalLayer: FlickerComponentName,
- newLayer: FlickerComponentName,
+ originalLayer: IComponentMatcher,
+ newLayer: IComponentMatcher,
ignoreEntriesWithRotationLayer: Boolean = false,
ignoreSnapshot: Boolean = false,
ignoreSplashscreen: Boolean = true
@@ -228,10 +252,10 @@ fun FlickerTestParameter.replacesLayer(
val assertion = this.isVisible(originalLayer)
if (ignoreEntriesWithRotationLayer) {
- assertion.then().isVisible(FlickerComponentName.ROTATION, isOptional = true)
+ assertion.then().isVisible(ComponentMatcher.ROTATION, isOptional = true)
}
if (ignoreSnapshot) {
- assertion.then().isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ assertion.then().isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
}
if (ignoreSplashscreen) {
assertion.then().isSplashScreenVisibleFor(newLayer, isOptional = true)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
index ed411b5eaf02..4cf669148497 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
@@ -16,13 +16,12 @@
package com.android.server.wm.flicker.activityembedding
-import android.app.Instrumentation
-import androidx.test.platform.app.InstrumentationRegistry
+import com.android.server.wm.flicker.BaseTest
+import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.Before
-abstract class ActivityEmbeddingTestBase {
- val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+abstract class ActivityEmbeddingTestBase(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
val testApp = ActivityEmbeddingAppHelper(instrumentation)
@Before
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
index 28a72f4da592..4e91ce16f567 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
@@ -16,11 +16,11 @@
package com.android.server.wm.flicker.activityembedding
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -42,25 +42,24 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenActivityEmbeddingPlaceholderSplit(private val testSpec: FlickerTestParameter) :
- ActivityEmbeddingTestBase() {
-
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- testApp.launchViaIntent(wmHelper)
- }
- }
- transitions {
- testApp.launchPlaceholderSplit(wmHelper)
+class OpenActivityEmbeddingPlaceholderSplit(
+ testSpec: FlickerTestParameter
+) : ActivityEmbeddingTestBase(testSpec) {
+
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
}
- teardown {
- test {
- device.pressHome()
- testApp.exit(wmHelper)
- }
+ }
+ transitions {
+ testApp.launchPlaceholderSplit(wmHelper)
+ }
+ teardown {
+ test {
+ device.pressHome()
+ testApp.exit(wmHelper)
}
}
}
@@ -90,6 +89,66 @@ class OpenActivityEmbeddingPlaceholderSplit(private val testSpec: FlickerTestPar
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() =
+ super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index d0f1dfddaed0..d53d96bbfe38 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -24,9 +24,6 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -68,6 +65,7 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransition(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
@@ -82,29 +80,7 @@ class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun statusBarLayerRotatesScales() {
- // This test doesn't work in shell transitions because of b/206753786
- assumeFalse(isShellTransitionsEnabled)
- super.statusBarLayerRotatesScales()
- }
-
- @FlakyTest(bugId = 214452854)
- @Test
- fun statusBarLayerRotatesScales_shellTransit() {
- assumeTrue(isShellTransitionsEnabled)
- super.statusBarLayerRotatesScales()
- }
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 229762973)
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
companion object {
/**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index b178e8c7eced..1348d7a0a91c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -64,6 +64,7 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransition(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
@@ -82,20 +83,7 @@ class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun statusBarLayerRotatesScales() {
- super.statusBarLayerRotatesScales()
- }
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 229762973)
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
companion object {
/**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index 730e5bcc3280..7ff093474399 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -16,39 +16,25 @@
package com.android.server.wm.flicker.close
-import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.LAUNCHER
import org.junit.Test
/**
* Base test class for transitions that close an app back to the launcher screen
*/
-abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter) {
- protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+abstract class CloseAppTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
- protected val tapl = LauncherInstrumentation()
- /**
- * Specification of the test transition to execute
- */
- protected open val transition: FlickerBuilder.() -> Unit = {
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
setup {
test {
tapl.setExpectedRotation(testSpec.startRotation)
@@ -66,98 +52,6 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter)
}
/**
- * Entry point for the test runner. It will use this method to initialize and cache
- * flicker executions
- */
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- transition()
- }
- }
-
- /**
- * Checks that the navigation bar window is visible during the whole transition
- */
- @Presubmit
- @Test
- open fun navBarWindowIsVisible() {
- testSpec.navBarWindowIsVisible()
- }
-
- /**
- * Checks that the status bar window is visible during the whole transition
- */
- @Presubmit
- @Test
- open fun statusBarWindowIsVisible() {
- testSpec.statusBarWindowIsVisible()
- }
-
- /**
- * Checks that the navigation bar layer is visible during the whole transition
- */
- @Presubmit
- @Test
- open fun navBarLayerIsVisible() {
- testSpec.navBarLayerIsVisible()
- }
-
- /**
- * Checks that the status bar layer is visible during the whole transition
- */
- @Presubmit
- @Test
- open fun statusBarLayerIsVisible() {
- testSpec.statusBarLayerIsVisible()
- }
-
- /**
- * Checks the position of the navigation bar at the start and end of the transition
- */
- @Presubmit
- @Test
- open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- /**
- * Checks the position of the status bar at the start and end of the transition
- */
- @Presubmit
- @Test
- open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- /**
- * Checks that all windows that are visible on the trace, are visible for at least 2
- * consecutive entries.
- */
- @Presubmit
- @Test
- open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
- }
- }
-
- /**
- * Checks that all layers that are visible on the trace, are visible for at least 2
- * consecutive entries.
- */
- @Presubmit
- @Test
- open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry()
- }
- }
-
- /**
- * Checks that all parts of the screen are covered during the transition
- */
- @Presubmit
- @Test
- open fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- /**
* Checks that [testApp] is the top visible app window at the start of the transition and
* that it is replaced by [LAUNCHER] during the transition
*/
@@ -165,9 +59,9 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter)
@Test
open fun launcherReplacesAppWindowAsTopWindow() {
testSpec.assertWm {
- this.isAppWindowOnTop(testApp.component)
- .then()
- .isAppWindowOnTop(LAUNCHER)
+ this.isAppWindowOnTop(testApp)
+ .then()
+ .isAppWindowOnTop(LAUNCHER)
}
}
@@ -180,8 +74,8 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter)
open fun launcherWindowBecomesVisible() {
testSpec.assertWm {
this.isAppWindowNotOnTop(LAUNCHER)
- .then()
- .isAppWindowOnTop(LAUNCHER)
+ .then()
+ .isAppWindowOnTop(LAUNCHER)
}
}
@@ -192,7 +86,7 @@ abstract class CloseAppTransition(protected val testSpec: FlickerTestParameter)
@Test
open fun launcherLayerReplacesApp() {
testSpec.replacesLayer(
- testApp.component,
+ testApp,
LAUNCHER,
ignoreEntriesWithRotationLayer = testSpec.isLandscapeOrSeascapeAtStart
)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
index a01f633cbae4..af3a8c502008 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
@@ -26,7 +26,7 @@ import androidx.window.extensions.WindowExtensions
import androidx.window.extensions.WindowExtensionsProvider
import androidx.window.extensions.embedding.ActivityEmbeddingComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.common.windowmanager.WindowManagerState.Companion.STATE_RESUMED
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
@@ -35,7 +35,7 @@ import org.junit.Assume.assumeNotNull
class ActivityEmbeddingAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.ACTIVITY_EMBEDDING_LAUNCHER_NAME,
- component: FlickerComponentName = MAIN_ACTIVITY_COMPONENT,
+ component: IComponentMatcher = MAIN_ACTIVITY_COMPONENT,
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
index 2dbf304a0f23..28858d4843a1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
@@ -20,15 +20,15 @@ import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
- class FixedOrientationAppHelper @JvmOverloads constructor(
+class FixedOrientationAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.PORTRAIT_ONLY_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.PORTRAIT_ONLY_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
- ) : StandardAppHelper(instr, launcherName, component, launcherStrategy) \ No newline at end of file
+ ) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
index cd184ac10c22..f536a151d8fd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
@@ -23,7 +23,7 @@ import android.view.WindowInsets.Type.statusBars
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import java.util.regex.Pattern
@@ -33,7 +33,7 @@ class ImeAppAutoFocusHelper @JvmOverloads constructor(
private val rotation: Int,
private val imePackageName: String = IME_PACKAGE,
launcherName: String = ActivityOptions.IME_ACTIVITY_AUTO_FOCUS_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.IME_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent()
) : ImeAppHelper(instr, launcherName, component) {
override fun openIME(wmHelper: WindowManagerStateHelper) {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 8ac9a75aff94..db64c4769715 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -22,14 +22,14 @@ import android.support.test.launcherhelper.LauncherStrategyFactory
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
open class ImeAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.IME_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.IME_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
@@ -80,7 +80,7 @@ open class ImeAppHelper @JvmOverloads constructor(
}
finishButton.click()
wmHelper.StateSyncBuilder()
- .withActivityRemoved(component)
+ .withActivityRemoved(this)
.waitForAndVerify()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
index 438aeeb2cc74..f74054ea4459 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
@@ -20,7 +20,7 @@ import android.app.Instrumentation
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
@@ -29,7 +29,7 @@ class ImeEditorPopupDialogAppHelper @JvmOverloads constructor(
private val rotation: Int,
private val imePackageName: String = IME_PACKAGE,
launcherName: String = ActivityOptions.EDITOR_POPUP_DIALOG_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.EDITOR_POPUP_DIALOG_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
) : ImeAppHelper(instr, launcherName, component) {
override fun openIME(wmHelper: WindowManagerStateHelper) {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
index 16c4c254f9e3..7f8b5633391b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
@@ -20,15 +20,15 @@ import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
class ImeStateInitializeHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.IME_ACTIVITY_INITIALIZE_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.IME_ACTIVITY_INITIALIZE_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy) \ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
index 1a2543cb8f97..79656a0bef9e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
@@ -23,14 +23,14 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
class NewTasksAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
@@ -47,7 +47,7 @@ class NewTasksAppHelper @JvmOverloads constructor(
}
button.click()
wmHelper.StateSyncBuilder()
- .withFullScreenApp(component)
+ .withFullScreenApp(this)
.waitForAndVerify()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
index f7ca5ce1c001..a9769d01caff 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
@@ -20,15 +20,15 @@ import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
class NonResizeableAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.NON_RESIZEABLE_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.NON_RESIZEABLE_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy) \ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
index 00b208bc8c23..50d036c4450f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
@@ -22,14 +22,14 @@ import android.support.test.launcherhelper.LauncherStrategyFactory
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
class NotificationAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.NOTIFICATION_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.NOTIFICATION_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
index 7bab981ce231..459ca5b3208f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
@@ -20,15 +20,15 @@ import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
class SeamlessRotationAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.SEAMLESS_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy) \ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
index bd2e5756b4a9..4952dbaeb551 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
@@ -20,15 +20,15 @@ import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
class ShowWhenLockedAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.SHOW_WHEN_LOCKED_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.SHOW_WHEN_LOCKED_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy) \ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
index f6a8817e5b08..6bddcac21a4d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
@@ -20,15 +20,15 @@ import android.app.Instrumentation
import android.support.test.launcherhelper.ILauncherStrategy
import android.support.test.launcherhelper.LauncherStrategyFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
class SimpleAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.SIMPLE_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
.launcherStrategy
-) : StandardAppHelper(instr, launcherName, component, launcherStrategy) \ No newline at end of file
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
index 8519da14aa2d..a17344f3879b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
@@ -23,14 +23,14 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
class TwoActivitiesAppHelper @JvmOverloads constructor(
instr: Instrumentation,
launcherName: String = ActivityOptions.BUTTON_ACTIVITY_LAUNCHER_NAME,
- component: FlickerComponentName =
+ component: IComponentMatcher =
ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME.toFlickerComponent(),
launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
.getInstance(instr)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index 67d2067d1b06..6b8fde21e53d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -16,28 +16,18 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -61,42 +51,23 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeAutoOpenWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- testApp.launchViaIntent(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
}
- teardown {
- eachRun {
- testApp.exit(wmHelper)
- }
- }
- transitions {
- testApp.closeIME(wmHelper)
+ }
+ teardown {
+ eachRun {
+ testApp.exit(wmHelper)
}
}
- }
-
- @Presubmit
- @Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ transitions {
+ testApp.closeIME(wmHelper)
}
}
@@ -104,27 +75,15 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter
@Test
fun imeAppWindowIsAlwaysVisible() {
testSpec.assertWm {
- this.isAppWindowOnTop(testApp.component)
+ this.isAppWindowOnTop(testApp)
}
}
@Presubmit
@Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- @Presubmit
- @Test
fun imeLayerVisibleStart() {
testSpec.assertLayersStart {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
}
}
@@ -132,7 +91,7 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter
@Test
fun imeLayerInvisibleEnd() {
testSpec.assertLayersEnd {
- this.isInvisible(FlickerComponentName.IME)
+ this.isInvisible(ComponentMatcher.IME)
}
}
@@ -144,23 +103,7 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter
@Test
fun imeAppLayerIsAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
- }
- }
-
- @Presubmit
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- @FlakyTest(bugId = 206753786)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry()
+ this.isVisible(testApp)
}
}
@@ -169,12 +112,14 @@ class CloseImeAutoOpenWindowToAppTest(private val testSpec: FlickerTestParameter
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3,
+ .getConfigNonRotationTests(
+ repetitions = 3,
// b/190352379 (IME doesn't show on app launch in 90 degrees)
supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index dcb5dad3e931..99c3ac652f3f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -16,28 +16,18 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -61,46 +51,27 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeAutoOpenWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- testApp.launchViaIntent(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
}
- teardown {
- eachRun {
- testApp.exit(wmHelper)
- }
- }
- transitions {
- device.pressHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .withImeGone()
- .waitForAndVerify()
+ }
+ teardown {
+ eachRun {
+ testApp.exit(wmHelper)
}
}
- }
-
- @Presubmit
- @Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ transitions {
+ device.pressHome()
+ wmHelper.StateSyncBuilder()
+ .withHomeActivityVisible()
+ .withImeGone()
+ .waitForAndVerify()
}
}
@@ -108,21 +79,17 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete
@Test
fun imeAppWindowBecomesInvisible() {
testSpec.assertWm {
- this.isAppWindowOnTop(testApp.component)
+ this.isAppWindowOnTop(testApp)
.then()
- .isAppWindowNotOnTop(testApp.component)
+ .isAppWindowNotOnTop(testApp)
}
}
@Presubmit
@Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- @Presubmit
- @Test
fun imeLayerVisibleStart() {
testSpec.assertLayersStart {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
}
}
@@ -130,7 +97,7 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete
@Test
fun imeLayerInvisibleEnd() {
testSpec.assertLayersEnd {
- this.isInvisible(FlickerComponentName.IME)
+ this.isInvisible(ComponentMatcher.IME)
}
}
@@ -142,35 +109,9 @@ class CloseImeAutoOpenWindowToHomeTest(private val testSpec: FlickerTestParamete
@Test
fun imeAppLayerBecomesInvisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
.then()
- .isInvisible(testApp.component)
- }
- }
-
- @Presubmit
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- @FlakyTest(bugId = 206753786)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry(listOf(
- FlickerComponentName.IME,
- FlickerComponentName.SPLASH_SCREEN))
+ .isInvisible(testApp)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
index b979f3ec3442..53f43184dde6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
@@ -16,23 +16,19 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
import android.platform.test.annotations.Postsubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeEditorPopupDialogAppHelper
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,44 +40,94 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-class CloseImeEditorPopupDialogTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeEditorPopupDialogTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val imeTestApp = ImeEditorPopupDialogAppHelper(instrumentation, testSpec.startRotation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- imeTestApp.launchViaIntent(wmHelper)
- imeTestApp.openIME(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ imeTestApp.launchViaIntent(wmHelper)
+ imeTestApp.openIME(wmHelper)
}
- transitions {
- imeTestApp.dismissDialog(wmHelper)
+ }
+ transitions {
+ imeTestApp.dismissDialog(wmHelper)
+ wmHelper.StateSyncBuilder()
+ .withImeGone()
+ .waitForAndVerify()
+ }
+ teardown {
+ eachRun {
+ device.pressHome()
wmHelper.StateSyncBuilder()
- .withImeGone()
+ .withHomeActivityVisible()
.waitForAndVerify()
- }
- teardown {
- eachRun {
- device.pressHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .waitForAndVerify()
- imeTestApp.exit(wmHelper)
- }
+ imeTestApp.exit(wmHelper)
}
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() =
+ super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
@Postsubmit
@Test
@@ -91,12 +137,12 @@ class CloseImeEditorPopupDialogTest(private val testSpec: FlickerTestParameter)
@Test
fun imeLayerAndImeSnapshotVisibleOnScreen() {
testSpec.assertLayers {
- this.isVisible(FlickerComponentName.IME)
- .then()
- .isVisible(FlickerComponentName.IME_SNAPSHOT)
- .then()
- .isInvisible(FlickerComponentName.IME_SNAPSHOT, isOptional = true)
- .isInvisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
+ .then()
+ .isVisible(ComponentMatcher.IME_SNAPSHOT)
+ .then()
+ .isInvisible(ComponentMatcher.IME_SNAPSHOT, isOptional = true)
+ .isInvisible(ComponentMatcher.IME)
}
}
@@ -105,15 +151,17 @@ class CloseImeEditorPopupDialogTest(private val testSpec: FlickerTestParameter)
fun imeSnapshotAssociatedOnAppVisibleRegion() {
testSpec.assertLayers {
this.invoke("imeSnapshotAssociatedOnAppVisibleRegion") {
- val imeSnapshotLayers = it.subjects.filter {
- subject -> subject.name.contains(
- FlickerComponentName.IME_SNAPSHOT.toLayerName()) && subject.isVisible
+ val imeSnapshotLayers = it.subjects.filter { subject ->
+ subject.name.contains(
+ ComponentMatcher.IME_SNAPSHOT.toLayerName()
+ ) && subject.isVisible
}
if (imeSnapshotLayers.isNotEmpty()) {
val visibleAreas = imeSnapshotLayers.mapNotNull { imeSnapshotLayer ->
- imeSnapshotLayer.layer?.visibleRegion }.toTypedArray()
+ imeSnapshotLayer.layer?.visibleRegion
+ }.toTypedArray()
val imeVisibleRegion = RegionSubject.assertThat(visibleAreas, this, timestamp)
- val appVisibleRegion = it.visibleRegion(imeTestApp.component)
+ val appVisibleRegion = it.visibleRegion(imeTestApp)
if (imeVisibleRegion.region.isNotEmpty) {
imeVisibleRegion.coversAtMost(appVisibleRegion.region)
}
@@ -127,14 +175,14 @@ class CloseImeEditorPopupDialogTest(private val testSpec: FlickerTestParameter)
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 2,
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- ),
- supportedRotations = listOf(Surface.ROTATION_0)
- )
+ .getConfigNonRotationTests(
+ repetitions = 2,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ ),
+ supportedRotations = listOf(Surface.ROTATION_0)
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index 928bb5346671..113fddff87b5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -16,27 +16,19 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
+import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -52,96 +44,63 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppHelper(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- testApp.launchViaIntent(wmHelper)
- }
- eachRun {
- testApp.openIME(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ testApp.launchViaIntent(wmHelper)
}
- teardown {
- test {
- testApp.exit(wmHelper)
- }
+ eachRun {
+ testApp.openIME(wmHelper)
}
- transitions {
- testApp.closeIME(wmHelper)
+ }
+ teardown {
+ test {
+ testApp.exit(wmHelper)
}
}
+ transitions {
+ testApp.closeIME(wmHelper)
+ }
}
+ /** {@inheritDoc} */
@Presubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
testSpec.assertWm {
this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(
- FlickerComponentName.IME,
- FlickerComponentName.SPLASH_SCREEN,
- FlickerComponentName.SNAPSHOT))
+ ComponentMatcher.IME,
+ ComponentMatcher.SPLASH_SCREEN,
+ ComponentMatcher.SNAPSHOT))
}
}
+ /** {@inheritDoc} */
@Presubmit
@Test
- fun imeAppWindowIsAlwaysVisible() {
- testSpec.assertWm {
- this.isAppWindowOnTop(testApp.component)
- }
- }
-
- @Presubmit
- @Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- @Presubmit
- @Test
- fun navBarLayerRotatesAndScales() {
- assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
- testSpec.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ Assume.assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
+ testSpec.navBarLayerPositionAtStartAndEnd()
}
@FlakyTest
@Test
- fun navBarLayerRotatesAndScales_Flaky() {
- assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
- testSpec.navBarLayerRotatesAndScales()
+ fun navBarLayerPositionAtStartAndEndLandscapeOrSeascapeAtStart() {
+ Assume.assumeFalse(testSpec.isTablet)
+ Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ testSpec.navBarLayerPositionAtStartAndEnd()
}
+ /** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry()
- }
- }
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
@Presubmit
@Test
@@ -151,7 +110,15 @@ class CloseImeWindowToAppTest(private val testSpec: FlickerTestParameter) {
@Test
fun imeAppLayerIsAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
+ }
+ }
+
+ @Presubmit
+ @Test
+ fun imeAppWindowIsAlwaysVisible() {
+ testSpec.assertWm {
+ this.isAppWindowOnTop(testApp)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index 3ff809d38330..f00a7ab3b77d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -16,27 +16,18 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -52,108 +43,85 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class CloseImeWindowToHomeTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class CloseImeWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppHelper(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- testApp.launchViaIntent(wmHelper)
- testApp.openIME(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
+ testApp.openIME(wmHelper)
}
- transitions {
- device.pressHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .withImeGone()
- .waitForAndVerify()
- }
- teardown {
- test {
- testApp.exit(wmHelper)
- }
+ }
+ transitions {
+ device.pressHome()
+ wmHelper.StateSyncBuilder()
+ .withHomeActivityVisible()
+ .withImeGone()
+ .waitForAndVerify()
+ }
+ teardown {
+ test {
+ testApp.exit(wmHelper)
}
}
}
+ /** {@inheritDoc} */
@Presubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry(listOf(
- FlickerComponentName.IME,
- FlickerComponentName.SPLASH_SCREEN,
- FlickerComponentName.SNAPSHOT))
+ this.visibleWindowsShownMoreThanOneConsecutiveEntry(
+ listOf(
+ ComponentMatcher.IME,
+ ComponentMatcher.SPLASH_SCREEN,
+ ComponentMatcher.SNAPSHOT
+ )
+ )
}
}
+ /** {@inheritDoc} */
@Presubmit
@Test
- fun imeWindowBecomesInvisible() = testSpec.imeWindowBecomesInvisible()
-
- @Presubmit
- @Test
- fun imeAppWindowBecomesInvisible() {
- testSpec.assertWm {
- this.isAppWindowVisible(testApp.component)
- .then()
- .isAppWindowInvisible(testApp.component)
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ testSpec.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(
+ ComponentMatcher.IME,
+ ComponentMatcher.SPLASH_SCREEN
+ )
+ )
}
}
@Presubmit
@Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
+ fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
@Presubmit
@Test
- fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
+ fun imeWindowBecomesInvisible() = testSpec.imeWindowBecomesInvisible()
@Presubmit
@Test
- fun imeAppLayerBecomesInvisible() {
- testSpec.assertLayers {
- this.isVisible(testApp.component)
- .then()
- .isInvisible(testApp.component)
+ fun imeAppWindowBecomesInvisible() {
+ testSpec.assertWm {
+ this.isAppWindowVisible(testApp)
+ .then()
+ .isAppWindowInvisible(testApp)
}
}
@Presubmit
@Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- @FlakyTest(bugId = 206753786)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ fun imeAppLayerBecomesInvisible() {
testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry(listOf(
- FlickerComponentName.IME,
- FlickerComponentName.SPLASH_SCREEN))
+ this.isVisible(testApp)
+ .then()
+ .isInvisible(testApp)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
index ba78e25580ec..19cab3c20dae 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
@@ -18,52 +18,52 @@
package com.android.server.wm.flicker.ime
import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
fun FlickerTestParameter.imeLayerBecomesVisible() {
assertLayers {
- this.isInvisible(FlickerComponentName.IME)
+ this.isInvisible(ComponentMatcher.IME)
.then()
- .isVisible(FlickerComponentName.IME)
+ .isVisible(ComponentMatcher.IME)
}
}
fun FlickerTestParameter.imeLayerBecomesInvisible() {
assertLayers {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
.then()
- .isInvisible(FlickerComponentName.IME)
+ .isInvisible(ComponentMatcher.IME)
}
}
fun FlickerTestParameter.imeWindowIsAlwaysVisible(rotatesScreen: Boolean = false) {
if (rotatesScreen) {
assertWm {
- this.isNonAppWindowVisible(FlickerComponentName.IME)
+ this.isNonAppWindowVisible(ComponentMatcher.IME)
.then()
- .isNonAppWindowInvisible(FlickerComponentName.IME)
+ .isNonAppWindowInvisible(ComponentMatcher.IME)
.then()
- .isNonAppWindowVisible(FlickerComponentName.IME)
+ .isNonAppWindowVisible(ComponentMatcher.IME)
}
} else {
assertWm {
- this.isNonAppWindowVisible(FlickerComponentName.IME)
+ this.isNonAppWindowVisible(ComponentMatcher.IME)
}
}
}
fun FlickerTestParameter.imeWindowBecomesVisible() {
assertWm {
- this.isNonAppWindowInvisible(FlickerComponentName.IME)
+ this.isNonAppWindowInvisible(ComponentMatcher.IME)
.then()
- .isNonAppWindowVisible(FlickerComponentName.IME)
+ .isNonAppWindowVisible(ComponentMatcher.IME)
}
}
fun FlickerTestParameter.imeWindowBecomesInvisible() {
assertWm {
- this.isNonAppWindowVisible(FlickerComponentName.IME)
+ this.isNonAppWindowVisible(ComponentMatcher.IME)
.then()
- .isNonAppWindowInvisible(FlickerComponentName.IME)
+ .isNonAppWindowInvisible(ComponentMatcher.IME)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index d1761fca899b..95c73df257c7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -16,8 +16,7 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowInsets.Type.ime
@@ -25,14 +24,13 @@ import android.view.WindowInsets.Type.navigationBars
import android.view.WindowInsets.Type.statusBars
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.FixMethodOrder
@@ -49,63 +47,121 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class LaunchAppShowImeAndDialogThemeAppTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class LaunchAppShowImeAndDialogThemeAppTest(
+ testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- testApp.launchViaIntent(wmHelper)
- wmHelper.StateSyncBuilder()
- .withImeShown()
- .waitForAndVerify()
- testApp.startDialogThemedActivity(wmHelper)
- // Verify IME insets isn't visible on dialog since it's non-IME focusable window
- assertFalse(testApp.getInsetsVisibleFromDialog(ime()))
- assertTrue(testApp.getInsetsVisibleFromDialog(statusBars()))
- assertTrue(testApp.getInsetsVisibleFromDialog(navigationBars()))
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
+ wmHelper.StateSyncBuilder()
+ .withImeShown()
+ .waitForAndVerify()
+ testApp.startDialogThemedActivity(wmHelper)
+ // Verify IME insets isn't visible on dialog since it's non-IME focusable window
+ assertFalse(testApp.getInsetsVisibleFromDialog(ime()))
+ assertTrue(testApp.getInsetsVisibleFromDialog(statusBars()))
+ assertTrue(testApp.getInsetsVisibleFromDialog(navigationBars()))
}
- teardown {
- eachRun {
- testApp.exit(wmHelper)
- }
- }
- transitions {
- testApp.dismissDialog(wmHelper)
+ }
+ teardown {
+ eachRun {
+ testApp.exit(wmHelper)
}
}
+ transitions {
+ testApp.dismissDialog(wmHelper)
+ }
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
/**
- * Checks that [FlickerComponentName.IME] layer becomes visible during the transition
+ * Checks that [ComponentMatcher.IME] layer becomes visible during the transition
*/
- @FlakyTest(bugId = 215884488)
+ @Presubmit
@Test
fun imeWindowIsAlwaysVisible() = testSpec.imeWindowIsAlwaysVisible()
/**
- * Checks that [FlickerComponentName.IME] layer is visible at the end of the transition
+ * Checks that [ComponentMatcher.IME] layer is visible at the end of the transition
*/
- @FlakyTest(bugId = 227142436)
+ @Presubmit
@Test
fun imeLayerExistsEnd() {
testSpec.assertLayersEnd {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
}
}
/**
- * Checks that [FlickerComponentName.IME_SNAPSHOT] layer is invisible always.
+ * Checks that [ComponentMatcher.IME_SNAPSHOT] layer is invisible always.
*/
@Presubmit
@Test
fun imeSnapshotNotVisible() {
testSpec.assertLayers {
- this.isInvisible(FlickerComponentName.IME_SNAPSHOT)
+ this.isInvisible(ComponentMatcher.IME_SNAPSHOT)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
index d393ace3254d..442ff1a36eba 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
@@ -16,13 +16,12 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -30,7 +29,7 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
import com.android.server.wm.flicker.helpers.ImeStateInitializeHelper
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -69,68 +68,124 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class LaunchAppShowImeOnStartTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class LaunchAppShowImeOnStartTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
private val initializeApp = ImeStateInitializeHelper(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- initializeApp.launchViaIntent(wmHelper)
- this.setRotation(testSpec.startRotation)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ initializeApp.launchViaIntent(wmHelper)
+ this.setRotation(testSpec.startRotation)
}
- teardown {
- eachRun {
- initializeApp.exit(wmHelper)
- testApp.exit(wmHelper)
- }
- }
- transitions {
- testApp.launchViaIntent(wmHelper)
- wmHelper.StateSyncBuilder()
- .withImeShown()
- .waitForAndVerify()
+ }
+ teardown {
+ eachRun {
+ initializeApp.exit(wmHelper)
+ testApp.exit(wmHelper)
}
}
+ transitions {
+ testApp.launchViaIntent(wmHelper)
+ wmHelper.StateSyncBuilder()
+ .withImeShown()
+ .waitForAndVerify()
+ }
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
/**
- * Checks that [FlickerComponentName.IME] window becomes visible during the transition
+ * Checks that [ComponentMatcher.IME] window becomes visible during the transition
*/
@Presubmit
@Test
fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
/**
- * Checks that [FlickerComponentName.IME] layer becomes visible during the transition
+ * Checks that [ComponentMatcher.IME] layer becomes visible during the transition
*/
@Presubmit
@Test
fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
/**
- * Checks that [FlickerComponentName.IME] layer is invisible at the start of the transition
+ * Checks that [ComponentMatcher.IME] layer is invisible at the start of the transition
*/
@Presubmit
@Test
fun imeLayerNotExistsStart() {
testSpec.assertLayersStart {
- this.isInvisible(FlickerComponentName.IME)
+ this.isInvisible(ComponentMatcher.IME)
}
}
/**
- * Checks that [FlickerComponentName.IME] layer is visible at the end of the transition
+ * Checks that [ComponentMatcher.IME] layer is visible at the end of the transition
*/
@Presubmit
@Test
fun imeLayerExistsEnd() {
testSpec.assertLayersEnd {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
index 1854d6e5506e..5296e3060a8d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
@@ -16,25 +16,19 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -52,39 +46,40 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class OpenImeWindowAndCloseTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowAndCloseTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val simpleApp = SimpleAppHelper(instrumentation)
private val testApp = ImeAppHelper(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- simpleApp.launchViaIntent(wmHelper)
- testApp.launchViaIntent(wmHelper)
- testApp.openIME(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ simpleApp.launchViaIntent(wmHelper)
+ testApp.launchViaIntent(wmHelper)
+ testApp.openIME(wmHelper)
}
- transitions {
- testApp.finishActivity(wmHelper)
- }
- teardown {
- test {
- simpleApp.exit(wmHelper)
- }
+ }
+ transitions {
+ testApp.finishActivity(wmHelper)
+ }
+ teardown {
+ test {
+ simpleApp.exit(wmHelper)
}
}
}
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
@Presubmit
@Test
@@ -92,48 +87,21 @@ class OpenImeWindowAndCloseTest(private val testSpec: FlickerTestParameter) {
@Presubmit
@Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- @Presubmit
- @Test
fun imeLayerBecomesInvisible() = testSpec.imeLayerBecomesInvisible()
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry()
- }
- }
-
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
- }
- }
-
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0),
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- )
+ .getConfigNonRotationTests(
+ repetitions = 3,
+ supportedRotations = listOf(Surface.ROTATION_0),
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
)
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index 4f26fc284198..b8686bc8e7ef 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -16,16 +16,12 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,11 +29,7 @@ import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.navBarWindowIsVisible
import com.android.server.wm.flicker.snapshotStartingWindowLayerCoversExactlyOnApp
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -54,58 +46,57 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class OpenImeWindowFromFixedOrientationAppTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowFromFixedOrientationAppTest(
+ testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
- private val taplInstrumentation = LauncherInstrumentation()
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- // Launch the activity with expecting IME will be shown.
- imeTestApp.launchViaIntent(wmHelper)
- }
- eachRun {
- // Swiping out the IME activity to home.
- taplInstrumentation.goHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .waitForAndVerify()
- }
- }
- transitions {
- // Bring the exist IME activity to the front in landscape mode device rotation.
- setRotation(Surface.ROTATION_90)
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ // Launch the activity with expecting IME will be shown.
imeTestApp.launchViaIntent(wmHelper)
}
- teardown {
- test {
- imeTestApp.exit(wmHelper)
- }
+ eachRun {
+ // Swiping out the IME activity to home.
+ device.pressHome()
+ wmHelper.StateSyncBuilder()
+ .withHomeActivityVisible()
+ .waitForAndVerify()
+ }
+ }
+ transitions {
+ // Bring the exist IME activity to the front in landscape mode device rotation.
+ setRotation(Surface.ROTATION_90)
+ imeTestApp.launchViaIntent(wmHelper)
+ }
+ teardown {
+ test {
+ imeTestApp.exit(wmHelper)
}
}
}
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
@Presubmit
@Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
-
- @FlakyTest(bugId = 206753786)
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
+ fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
@Presubmit
@Test
@@ -114,7 +105,7 @@ class OpenImeWindowFromFixedOrientationAppTest(private val testSpec: FlickerTest
@Postsubmit
@Test
fun snapshotStartingWindowLayerCoversExactlyOnApp() {
- testSpec.snapshotStartingWindowLayerCoversExactlyOnApp(imeTestApp.component)
+ testSpec.snapshotStartingWindowLayerCoversExactlyOnApp(imeTestApp)
}
companion object {
@@ -128,13 +119,13 @@ class OpenImeWindowFromFixedOrientationAppTest(private val testSpec: FlickerTest
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_90),
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- )
+ .getConfigNonRotationTests(
+ repetitions = 3,
+ supportedRotations = listOf(Surface.ROTATION_90),
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
)
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index dbec3643c39f..fdc2193b7eb8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -16,27 +16,17 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -52,97 +42,50 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-class OpenImeWindowTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppHelper(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- testApp.launchViaIntent(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ testApp.launchViaIntent(wmHelper)
}
- transitions {
- testApp.openIME(wmHelper)
+ }
+ transitions {
+ testApp.openIME(wmHelper)
+ }
+ teardown {
+ eachRun {
+ testApp.closeIME(wmHelper)
}
- teardown {
- eachRun {
- testApp.closeIME(wmHelper)
- }
- test {
- testApp.exit(wmHelper)
- }
+ test {
+ testApp.exit(wmHelper)
}
}
}
@Presubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
- @Presubmit
- @Test
fun imeWindowBecomesVisible() = testSpec.imeWindowBecomesVisible()
@Presubmit
@Test
fun appWindowAlwaysVisibleOnTop() {
testSpec.assertWm {
- this.isAppWindowOnTop(testApp.component)
+ this.isAppWindowOnTop(testApp)
}
}
@Presubmit
@Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- @Presubmit
- @Test
fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
@Presubmit
@Test
fun layerAlwaysVisible() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
- }
- }
-
- @Presubmit
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- @FlakyTest(bugId = 206753786)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry()
- }
- }
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ this.isVisible(testApp)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
index eedbd5d3dba8..0f809eef1dd4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
@@ -16,15 +16,12 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -32,16 +29,14 @@ import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.server.wm.traces.common.WindowManagerConditionsFactory
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
+import org.junit.Assume
import org.junit.FixMethodOrder
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -56,44 +51,39 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
- private val statusBarInvisible = WindowManagerConditionsFactory.isStatusBarVisible().negate()
- private val navBarInvisible = WindowManagerConditionsFactory.isNavBarVisible().negate()
-
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- imeTestApp.launchViaIntent(wmHelper)
- }
- }
- transitions {
- device.pressRecentApps()
- val builder = wmHelper.StateSyncBuilder()
- .withRecentsActivityVisible()
- waitNavStatusBarVisibility(builder)
- builder.waitForAndVerify()
+
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ imeTestApp.launchViaIntent(wmHelper)
}
- teardown {
- test {
- device.pressHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .waitForAndVerify()
- imeTestApp.exit(wmHelper)
- }
+ }
+ transitions {
+ device.pressRecentApps()
+ val builder = wmHelper.StateSyncBuilder()
+ .withRecentsActivityVisible()
+ waitNavStatusBarVisibility(builder)
+ builder.waitForAndVerify()
+ }
+ teardown {
+ test {
+ device.pressHome()
+ wmHelper.StateSyncBuilder()
+ .withHomeActivityVisible()
+ .waitForAndVerify()
+ imeTestApp.exit(wmHelper)
}
}
}
/**
- * The bars (including status bar and navigation bar) are expected to be hidden while
- * entering overview in landscape if launcher is set to portrait only. Because
- * "showing portrait overview (launcher) in landscape display" is an intermediate state
- * depending on the touch-up to decide the intention of gesture, the display may keep in
+ * The bars (including [ComponentMatcher.STATUS_BAR] and [ComponentMatcher.NAV_BAR]) are
+ * expected to be hidden while entering overview in landscape if launcher is set to portrait
+ * only. Because "showing portrait overview (launcher) in landscape display" is an intermediate
+ * state depending on the touch-up to decide the intention of gesture, the display may keep in
* landscape if return to app, or change to portrait if the gesture is to swipe-to-home.
*
* So instead of showing landscape bars with portrait launcher at the same time
@@ -104,20 +94,28 @@ class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
*/
private fun waitNavStatusBarVisibility(stateSync: WindowManagerStateHelper.StateSyncBuilder) {
when {
- testSpec.isLandscapeOrSeascapeAtStart ->
- stateSync.add(statusBarInvisible)
+ testSpec.isLandscapeOrSeascapeAtStart && !testSpec.isTablet ->
+ stateSync.add(WindowManagerConditionsFactory.isStatusBarVisible().negate())
else ->
- stateSync.withNavBarStatusBarVisible()
+ stateSync.withNavOrTaskBarVisible().withStatusBarVisible()
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
@Presubmit
@Test
@@ -127,9 +125,10 @@ class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
@Presubmit
@Test
- fun navBarLayerIsVisible3Button() {
- assumeFalse(testSpec.isGesturalNavigation)
- testSpec.navBarLayerIsVisible()
+ fun navBarLayerIsVisibleAtStartAndEnd3Button() {
+ Assume.assumeFalse(testSpec.isTablet)
+ Assume.assumeFalse(testSpec.isGesturalNavigation)
+ testSpec.navBarLayerIsVisibleAtStartAndEnd()
}
/**
@@ -137,10 +136,11 @@ class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
*/
@Presubmit
@Test
- fun navBarLayerIsVisibleInPortraitGestural() {
- assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
- assumeTrue(testSpec.isGesturalNavigation)
- testSpec.navBarLayerIsVisible()
+ fun navBarLayerIsVisibleAtStartAndEndGestural() {
+ Assume.assumeFalse(testSpec.isTablet)
+ Assume.assumeTrue(testSpec.isGesturalNavigation)
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ testSpec.navBarLayerIsVisibleAtStartAndEnd()
}
/**
@@ -150,50 +150,115 @@ class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
@Postsubmit
@Test
fun navBarLayerIsInvisibleInLandscapeGestural() {
- assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
- assumeTrue(testSpec.isGesturalNavigation)
- assumeTrue(isShellTransitionsEnabled)
+ Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ Assume.assumeTrue(testSpec.isGesturalNavigation)
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ testSpec.assertLayersStart {
+ this.isVisible(ComponentMatcher.NAV_BAR)
+ }
+ testSpec.assertLayersEnd {
+ this.isInvisible(ComponentMatcher.NAV_BAR)
+ }
+ }
+
+ /**
+ * In the legacy transitions, the nav bar is not marked as invisible.
+ * In the new transitions this is fixed and the nav bar shows as invisible
+ */
+ @Presubmit
+ @Test
+ fun statusBarLayerIsInvisibleInLandscapePhone() {
+ Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ Assume.assumeTrue(testSpec.isGesturalNavigation)
+ Assume.assumeFalse(testSpec.isTablet)
testSpec.assertLayersStart {
- this.isVisible(FlickerComponentName.NAV_BAR)
+ this.isVisible(ComponentMatcher.STATUS_BAR)
}
testSpec.assertLayersEnd {
- this.isInvisible(FlickerComponentName.NAV_BAR)
+ this.isInvisible(ComponentMatcher.STATUS_BAR)
}
}
+ /**
+ * In the legacy transitions, the nav bar is not marked as invisible.
+ * In the new transitions this is fixed and the nav bar shows as invisible
+ */
+ @Presubmit
+ @Test
+ fun statusBarLayerIsInvisibleInLandscapeTablet() {
+ Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ Assume.assumeTrue(testSpec.isGesturalNavigation)
+ Assume.assumeTrue(testSpec.isTablet)
+ testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+ }
+
+ /** {@inheritDoc} */
+ @Ignore("Visibility changes depending on orientation and navigation mode")
+ override fun navBarLayerIsVisibleAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Visibility changes depending on orientation and navigation mode")
+ override fun navBarLayerPositionAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Visibility changes depending on orientation and navigation mode")
+ override fun statusBarLayerPositionAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Visibility changes depending on orientation and navigation mode")
+ override fun statusBarLayerIsVisibleAtStartAndEnd() { }
+
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() =
+ super.taskBarLayerIsVisibleAtStartAndEnd()
+
@Postsubmit
@Test
fun statusBarLayerIsVisibleInPortrait() {
- assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
- testSpec.statusBarLayerIsVisible()
+ Assume.assumeFalse(testSpec.isLandscapeOrSeascapeAtStart)
+ testSpec.statusBarLayerIsVisibleAtStartAndEnd()
}
@Presubmit
@Test
- fun statusBarLayerIsInvisibleInLandscape() {
- assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ fun statusBarLayerIsInvisibleInLandscapeShell() {
+ Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ Assume.assumeFalse(testSpec.isTablet)
+ Assume.assumeTrue(isShellTransitionsEnabled)
testSpec.assertLayersStart {
- this.isVisible(FlickerComponentName.STATUS_BAR)
+ this.isVisible(ComponentMatcher.STATUS_BAR)
}
testSpec.assertLayersEnd {
- this.isInvisible(FlickerComponentName.STATUS_BAR)
+ this.isInvisible(ComponentMatcher.STATUS_BAR)
}
}
- @FlakyTest(bugId = 228011606)
+ @Presubmit
+ @Test
+ fun statusBarLayerIsVisibleInLandscapeLegacy() {
+ Assume.assumeTrue(testSpec.isLandscapeOrSeascapeAtStart)
+ Assume.assumeTrue(testSpec.isTablet)
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ testSpec.statusBarLayerIsVisibleAtStartAndEnd()
+ }
+
+ @Presubmit
@Test
fun imeLayerIsVisibleAndAssociatedWithAppWidow() {
testSpec.assertLayersStart {
- isVisible(FlickerComponentName.IME).visibleRegion(FlickerComponentName.IME)
- .coversAtMost(isVisible(imeTestApp.component)
- .visibleRegion(imeTestApp.component).region)
+ isVisible(ComponentMatcher.IME).visibleRegion(ComponentMatcher.IME)
+ .coversAtMost(
+ isVisible(imeTestApp)
+ .visibleRegion(imeTestApp).region
+ )
}
testSpec.assertLayers {
this.invoke("imeLayerIsVisibleAndAlignAppWidow") {
- val imeVisibleRegion = it.visibleRegion(FlickerComponentName.IME)
- val appVisibleRegion = it.visibleRegion(imeTestApp.component)
+ val imeVisibleRegion = it.visibleRegion(ComponentMatcher.IME)
+ val appVisibleRegion = it.visibleRegion(imeTestApp)
if (imeVisibleRegion.region.isNotEmpty) {
- it.isVisible(FlickerComponentName.IME)
+ it.isVisible(ComponentMatcher.IME)
imeVisibleRegion.coversAtMost(appVisibleRegion.region)
}
}
@@ -211,14 +276,14 @@ class OpenImeWindowToOverViewTest(private val testSpec: FlickerTestParameter) {
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 1,
- supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- )
+ .getConfigNonRotationTests(
+ repetitions = 1,
+ supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
)
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index 7d4724c48bbb..e91126096b82 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -16,34 +16,23 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group2
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.reopenAppFromOverview
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.LAUNCHER
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
-import org.junit.Before
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.LAUNCHER
+import org.junit.Assume
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -59,61 +48,67 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group2
-open class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
- @Before
- open fun before() {
- assumeFalse(isShellTransitionsEnabled)
- }
-
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- testApp.launchViaIntent(wmHelper)
- testApp.openIME(wmHelper)
- }
- eachRun {
- this.setRotation(testSpec.startRotation)
- device.pressRecentApps()
- wmHelper.StateSyncBuilder()
- .withRecentsActivityVisible()
- .waitForAndVerify()
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ testApp.launchViaIntent(wmHelper)
+ testApp.openIME(wmHelper)
}
- transitions {
- device.reopenAppFromOverview(wmHelper)
+ eachRun {
+ this.setRotation(testSpec.startRotation)
+ device.pressRecentApps()
wmHelper.StateSyncBuilder()
- .withImeShown()
+ .withRecentsActivityVisible()
.waitForAndVerify()
}
- teardown {
- test {
- testApp.exit(wmHelper)
- }
+ }
+ transitions {
+ device.reopenAppFromOverview(wmHelper)
+ wmHelper.StateSyncBuilder()
+ .withImeShown()
+ .waitForAndVerify()
+ }
+ teardown {
+ test {
+ testApp.exit(wmHelper)
}
}
}
- @Presubmit
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 206753786)
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+ /** {@inheritDoc} */
@Presubmit
@Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ // depends on how much of the animation transactions are sent to SF at once
+ // sometimes this layer appears for 2-3 frames, sometimes for only 1
+ val recentTaskComponent = ComponentMatcher("", "RecentTaskScreenshotSurface")
+ testSpec.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry(
+ listOf(ComponentMatcher.SPLASH_SCREEN,
+ ComponentMatcher.SNAPSHOT, recentTaskComponent)
+ )
+ }
+ }
+ /** {@inheritDoc} */
@Presubmit
@Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- val component = FlickerComponentName("", "RecentTaskScreenshotSurface")
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ val component = ComponentMatcher("", "RecentTaskScreenshotSurface")
testSpec.assertWm {
this.visibleWindowsShownMoreThanOneConsecutiveEntry(
- ignoreWindows = listOf(FlickerComponentName.SPLASH_SCREEN,
- FlickerComponentName.SNAPSHOT,
+ ignoreWindows = listOf(ComponentMatcher.SPLASH_SCREEN,
+ ComponentMatcher.SNAPSHOT,
component)
)
}
@@ -136,66 +131,53 @@ open class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
@Presubmit
@Test
fun imeAppWindowVisibilityLegacy() {
- assumeFalse(isShellTransitionsEnabled)
+ Assume.assumeFalse(isShellTransitionsEnabled)
// the app starts visible in live tile, and stays visible for the duration of entering
// and exiting overview. However, legacy transitions seem to have a bug which causes
// everything to restart during the test, so expect the app to disappear and come back.
// Since we log 1x per frame, sometimes the activity visibility and the app visibility
// are updated together, sometimes not, thus ignore activity check at the start
testSpec.assertWm {
- this.isAppWindowVisible(testApp.component)
+ this.isAppWindowVisible(testApp)
.then()
- .isAppWindowInvisible(testApp.component)
+ .isAppWindowInvisible(testApp)
.then()
- .isAppWindowVisible(testApp.component)
+ .isAppWindowVisible(testApp)
}
}
@FlakyTest(bugId = 204570898)
@Test
fun imeAppWindowVisibility() {
- assumeTrue(isShellTransitionsEnabled)
+ Assume.assumeTrue(isShellTransitionsEnabled)
// the app starts visible in live tile, and stays visible for the duration of entering
// and exiting overview. Since we log 1x per frame, sometimes the activity visibility
// and the app visibility are updated together, sometimes not, thus ignore activity
// check at the start
testSpec.assertWm {
- this.isAppWindowVisible(testApp.component)
+ this.isAppWindowVisible(testApp)
}
}
@Presubmit
@Test
- // During testing the launcher is always in portrait mode
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- @Presubmit
- @Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
- @Presubmit
- @Test
fun imeLayerIsBecomesVisibleLegacy() {
- assumeFalse(isShellTransitionsEnabled)
+ Assume.assumeFalse(isShellTransitionsEnabled)
testSpec.assertLayers {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
.then()
- .isInvisible(FlickerComponentName.IME)
+ .isInvisible(ComponentMatcher.IME)
.then()
- .isVisible(FlickerComponentName.IME)
+ .isVisible(ComponentMatcher.IME)
}
}
@FlakyTest(bugId = 204570898)
@Test
fun imeLayerIsBecomesVisible() {
- assumeTrue(isShellTransitionsEnabled)
+ Assume.assumeTrue(isShellTransitionsEnabled)
testSpec.assertLayers {
- this.isVisible(FlickerComponentName.IME)
+ this.isVisible(ComponentMatcher.IME)
}
}
@@ -203,33 +185,11 @@ open class ReOpenImeWindowTest(private val testSpec: FlickerTestParameter) {
@Test
fun appLayerReplacesLauncher() {
testSpec.assertLayers {
- this.isVisible(FlickerComponentName.LAUNCHER)
+ this.isVisible(ComponentMatcher.LAUNCHER)
.then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isVisible(testApp.component)
- }
- }
-
- @Presubmit
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- @FlakyTest(bugId = 206753786)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- @Presubmit
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- // depends on how much of the animation transactions are sent to SF at once
- // sometimes this layer appears for 2-3 frames, sometimes for only 1
- val recentTaskComponent = FlickerComponentName("", "RecentTaskScreenshotSurface")
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry(
- listOf(FlickerComponentName.SPLASH_SCREEN,
- FlickerComponentName.SNAPSHOT, recentTaskComponent)
- )
+ .isVisible(testApp)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
deleted file mode 100644
index 5362a41fcb22..000000000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest_ShellTransit.kt
+++ /dev/null
@@ -1,48 +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.wm.flicker.ime
-
-import android.platform.test.annotations.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import org.junit.Assume
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test IME window opening transitions.
- * To run this test: `atest FlickerTests:ReOpenImeWindowTest`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-@FlakyTest(bugId = 221854428)
-class ReOpenImeWindowTest_ShellTransit(private val testSpec: FlickerTestParameter)
- : ReOpenImeWindowTest(testSpec) {
- @Before
- override fun before() {
- Assume.assumeTrue(isShellTransitionsEnabled)
- }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index d1188467cc01..0aeeb0358271 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -16,13 +16,12 @@
package com.android.server.wm.flicker.ime
-import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,9 +32,7 @@ import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.Assume
import org.junit.Before
import org.junit.FixMethodOrder
@@ -54,8 +51,9 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
@Presubmit
-open class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+open class SwitchImeWindowsFromGestureNavTest(
+ testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
private val testApp = SimpleAppHelper(instrumentation)
private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
@@ -64,132 +62,157 @@ open class SwitchImeWindowsFromGestureNavTest(private val testSpec: FlickerTestP
Assume.assumeFalse(isShellTransitionsEnabled)
}
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- this.setRotation(testSpec.startRotation)
- testApp.launchViaIntent(wmHelper)
- wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
- .waitForAndVerify()
-
- imeTestApp.launchViaIntent(wmHelper)
- wmHelper.StateSyncBuilder()
- .withFullScreenApp(imeTestApp.component)
- .waitForAndVerify()
-
- imeTestApp.openIME(wmHelper)
- }
- }
- teardown {
- eachRun {
- device.pressHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .waitForAndVerify()
- testApp.exit(wmHelper)
- imeTestApp.exit(wmHelper)
- }
- }
- transitions {
- // [Step1]: Swipe right from imeTestApp to testApp task
- createTag(TAG_IME_VISIBLE)
- val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
- device.swipe(0, displayBounds.bounds.height,
- displayBounds.bounds.width, displayBounds.bounds.height, 50)
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ this.setRotation(testSpec.startRotation)
+ testApp.launchViaIntent(wmHelper)
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp)
+ .waitForAndVerify()
+ imeTestApp.launchViaIntent(wmHelper)
wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
+ .withFullScreenApp(imeTestApp)
.waitForAndVerify()
- createTag(TAG_IME_INVISIBLE)
+
+ imeTestApp.openIME(wmHelper)
}
- transitions {
- // [Step2]: Swipe left to back to imeTestApp task
- val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
- device.swipe(displayBounds.bounds.width, displayBounds.bounds.height,
- 0, displayBounds.bounds.height, 50)
+ }
+ teardown {
+ eachRun {
+ device.pressHome()
wmHelper.StateSyncBuilder()
- .withFullScreenApp(imeTestApp.component)
+ .withHomeActivityVisible()
.waitForAndVerify()
+ testApp.exit(wmHelper)
+ imeTestApp.exit(wmHelper)
}
}
+ transitions {
+ // [Step1]: Swipe right from imeTestApp to testApp task
+ createTag(TAG_IME_VISIBLE)
+ val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
+ device.swipe(
+ 0, displayBounds.bounds.height,
+ displayBounds.bounds.width, displayBounds.bounds.height, 50
+ )
+
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp)
+ .waitForAndVerify()
+ createTag(TAG_IME_INVISIBLE)
+ }
+ transitions {
+ // [Step2]: Swipe left to back to imeTestApp task
+ val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
+ device.swipe(
+ displayBounds.bounds.width, displayBounds.bounds.height,
+ 0, displayBounds.bounds.height, 50
+ )
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(imeTestApp)
+ .waitForAndVerify()
+ }
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
@Test
fun imeAppWindowVisibility() {
testSpec.assertWm {
- isAppWindowVisible(imeTestApp.component)
+ isAppWindowVisible(imeTestApp)
.then()
- .isAppSnapshotStartingWindowVisibleFor(testApp.component, isOptional = true)
+ .isAppSnapshotStartingWindowVisibleFor(testApp, isOptional = true)
.then()
- .isAppWindowVisible(testApp.component)
+ .isAppWindowVisible(testApp)
.then()
- .isAppSnapshotStartingWindowVisibleFor(imeTestApp.component, isOptional = true)
+ .isAppSnapshotStartingWindowVisibleFor(imeTestApp, isOptional = true)
.then()
- .isAppWindowVisible(imeTestApp.component)
- }
- }
-
- @Test
- fun navBarLayerIsVisibleAroundSwitching() {
- testSpec.assertLayersStart {
- isVisible(FlickerComponentName.NAV_BAR)
- }
- testSpec.assertLayersEnd {
- isVisible(FlickerComponentName.NAV_BAR)
+ .isAppWindowVisible(imeTestApp)
}
}
@Test
- fun statusBarLayerIsVisibleAroundSwitching() {
+ open fun imeLayerIsVisibleWhenSwitchingToImeApp() {
testSpec.assertLayersStart {
- isVisible(FlickerComponentName.STATUS_BAR)
- }
- testSpec.assertLayersEnd {
- isVisible(FlickerComponentName.STATUS_BAR)
- }
- }
-
- @Test
- fun imeLayerIsVisibleWhenSwitchingToImeApp() {
- testSpec.assertLayersStart {
- isVisible(FlickerComponentName.IME)
+ isVisible(ComponentMatcher.IME)
}
testSpec.assertLayersTag(TAG_IME_VISIBLE) {
- isVisible(FlickerComponentName.IME)
+ isVisible(ComponentMatcher.IME)
}
testSpec.assertLayersEnd {
- isVisible(FlickerComponentName.IME)
+ isVisible(ComponentMatcher.IME)
}
}
@Test
fun imeLayerIsInvisibleWhenSwitchingToTestApp() {
testSpec.assertLayersTag(TAG_IME_INVISIBLE) {
- isInvisible(FlickerComponentName.IME)
+ isInvisible(ComponentMatcher.IME)
}
}
- @Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
- @Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- ),
- supportedRotations = listOf(Surface.ROTATION_0)
- )
+ .getConfigNonRotationTests(
+ repetitions = 3,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ ),
+ supportedRotations = listOf(Surface.ROTATION_0)
+ )
}
private const val TAG_IME_VISIBLE = "imeVisible"
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
index 3dbe1ec17b82..457e973392f7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest_ShellTransit.kt
@@ -24,8 +24,8 @@ import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume
import org.junit.Before
-
import org.junit.FixMethodOrder
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -39,11 +39,30 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-@FlakyTest(bugId = 228012334)
-class SwitchImeWindowsFromGestureNavTest_ShellTransit(testSpec: FlickerTestParameter)
- : SwitchImeWindowsFromGestureNavTest(testSpec) {
+class SwitchImeWindowsFromGestureNavTest_ShellTransit(
+ testSpec: FlickerTestParameter
+) : SwitchImeWindowsFromGestureNavTest(testSpec) {
@Before
override fun before() {
Assume.assumeTrue(isShellTransitionsEnabled)
}
+
+ @FlakyTest(bugId = 228012334)
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ @FlakyTest(bugId = 228012334)
+ @Test
+ override fun imeLayerIsVisibleWhenSwitchingToImeApp() =
+ super.imeLayerIsVisibleWhenSwitchingToImeApp()
+
+ @FlakyTest(bugId = 228012334)
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ @FlakyTest(bugId = 228012334)
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index a33f0ea5a074..86b8e5fa1647 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -16,21 +16,18 @@
package com.android.server.wm.flicker.launch
-import android.app.Instrumentation
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.TwoActivitiesAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import org.junit.FixMethodOrder
import org.junit.Test
@@ -59,39 +56,36 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-class ActivitiesTransitionTest(val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+class ActivitiesTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp: TwoActivitiesAppHelper = TwoActivitiesAppHelper(instrumentation)
- private val tapl = LauncherInstrumentation()
- /**
- * Entry point for the test runner. It will use this method to initialize and cache
- * flicker executions
- */
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- tapl.setExpectedRotation(testSpec.startRotation)
- testApp.launchViaIntent(wmHelper)
- }
- }
- teardown {
- test {
- testApp.exit(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ tapl.setExpectedRotation(testSpec.startRotation)
+ testApp.launchViaIntent(wmHelper)
}
- transitions {
- testApp.openSecondActivity(device, wmHelper)
- tapl.pressBack()
- wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
- .waitForAndVerify()
+ }
+ teardown {
+ test {
+ testApp.exit(wmHelper)
}
}
+ transitions {
+ testApp.openSecondActivity(device, wmHelper)
+ tapl.pressBack()
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp)
+ .waitForAndVerify()
+ }
}
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 206753786)
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
/**
* Checks that the [ActivityOptions.BUTTON_ACTIVITY_COMPONENT_NAME] activity is visible at
* the start of the transition, that
@@ -116,14 +110,7 @@ class ActivitiesTransitionTest(val testSpec: FlickerTestParameter) {
}
/**
- * Checks that all parts of the screen are covered during the transition
- */
- @Presubmit
- @Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- /**
- * Checks that the [FlickerComponentName.LAUNCHER] window is not on top. The launcher cannot be
+ * Checks that the [ComponentMatcher.LAUNCHER] window is not on top. The launcher cannot be
* asserted with `isAppWindowVisible` because it contains 2 windows with the exact same name,
* and both are never simultaneously visible
*/
@@ -131,17 +118,17 @@ class ActivitiesTransitionTest(val testSpec: FlickerTestParameter) {
@Test
fun launcherWindowNotOnTop() {
testSpec.assertWm {
- this.isAppWindowNotOnTop(FlickerComponentName.LAUNCHER)
+ this.isAppWindowNotOnTop(ComponentMatcher.LAUNCHER)
}
}
/**
- * Checks that the [FlickerComponentName.LAUNCHER] layer is never visible during the transition
+ * Checks that the [ComponentMatcher.LAUNCHER] layer is never visible during the transition
*/
@Presubmit
@Test
fun launcherLayerNotVisible() {
- testSpec.assertLayers { this.isInvisible(FlickerComponentName.LAUNCHER) }
+ testSpec.assertLayers { this.isInvisible(ComponentMatcher.LAUNCHER) }
}
companion object {
@@ -155,7 +142,7 @@ class ActivitiesTransitionTest(val testSpec: FlickerTestParameter) {
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests(repetitions = 3)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
index c92704464817..accf8afe14ea 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
@@ -54,11 +54,10 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-class OpenAppColdFromIcon(testSpec: FlickerTestParameter) :
- OpenAppFromLauncherTransition(testSpec) {
- /**
- * Defines the transition used to run the test
- */
+class OpenAppColdFromIcon(
+ testSpec: FlickerTestParameter
+) : OpenAppFromLauncherTransition(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
@@ -82,85 +81,107 @@ class OpenAppColdFromIcon(testSpec: FlickerTestParameter) :
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun appWindowAsTopWindowAtEnd() =
+ super.appWindowAsTopWindowAtEnd()
+
+ /** {@inheritDoc} */
@Postsubmit
@Test
override fun appWindowReplacesLauncherAsTopWindow() =
super.appWindowReplacesLauncherAsTopWindow()
+ /** {@inheritDoc} */
@Postsubmit
@Test
override fun appLayerBecomesVisible() =
super.appLayerBecomesVisible()
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
+
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun appLayerReplacesLauncher() =
- super.appLayerReplacesLauncher()
+ override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun appWindowBecomesTopWindow() =
- super.appWindowBecomesTopWindow()
+ override fun entireScreenCovered() = super.entireScreenCovered()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun appWindowBecomesVisible() =
- super.appWindowBecomesVisible()
+ override fun focusChanges() = super.focusChanges()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun entireScreenCovered() =
- super.entireScreenCovered()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun focusChanges() =
- super.focusChanges()
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarLayerIsVisible() =
- super.navBarLayerIsVisible()
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarLayerRotatesAndScales() =
- super.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarWindowIsVisible() =
- super.navBarWindowIsVisible()
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarLayerRotatesScales() =
- super.statusBarLayerRotatesScales()
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarLayerIsVisible() =
- super.statusBarLayerIsVisible()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarWindowIsVisible() =
- super.statusBarWindowIsVisible()
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+ /** {@inheritDoc} */
@Postsubmit
@Test
override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ /** {@inheritDoc} */
@Postsubmit
@Test
override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ /** {@inheritDoc} */
@Postsubmit
@Test
- override fun appWindowIsTopWindowAtEnd() =
- super.appWindowIsTopWindowAtEnd()
+ override fun appWindowIsTopWindowAtEnd() = super.appWindowIsTopWindowAtEnd()
companion object {
/**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index e52b6c326b73..60a1591542ce 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -54,11 +54,10 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-open class OpenAppColdTest(testSpec: FlickerTestParameter) :
- OpenAppFromLauncherTransition(testSpec) {
- /**
- * Defines the transition used to run the test
- */
+open class OpenAppColdTest(
+ testSpec: FlickerTestParameter
+) : OpenAppFromLauncherTransition(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
@@ -81,41 +80,14 @@ open class OpenAppColdTest(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun navBarLayerRotatesAndScales() {
- super.navBarLayerRotatesAndScales()
- }
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
/** {@inheritDoc} */
@Presubmit
@Test
override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun appWindowReplacesLauncherAsTopWindow() =
- super.appWindowReplacesLauncherAsTopWindow()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
-
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
index 027a04fab4e3..2d4d7986a67e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
@@ -19,17 +19,18 @@ package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Presubmit
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.Test
/**
* Base class for app launch tests
*/
-abstract class OpenAppFromLauncherTransition(testSpec: FlickerTestParameter) :
- OpenAppTransition(testSpec) {
+abstract class OpenAppFromLauncherTransition(
+ testSpec: FlickerTestParameter
+) : OpenAppTransition(testSpec) {
/**
- * Checks that the focus changes from the launcher to [testApp]
+ * Checks that the focus changes from the [ComponentMatcher.LAUNCHER] to [testApp]
*/
@Presubmit
@Test
@@ -40,31 +41,44 @@ abstract class OpenAppFromLauncherTransition(testSpec: FlickerTestParameter) :
}
/**
- * Checks that [FlickerComponentName.LAUNCHER] layer is visible at the start of the transition,
+ * Checks that [ComponentMatcher.LAUNCHER] layer is visible at the start of the transition,
* and is replaced by [testApp], which remains visible until the end
*/
open fun appLayerReplacesLauncher() {
- testSpec.replacesLayer(FlickerComponentName.LAUNCHER, testApp.component,
- ignoreEntriesWithRotationLayer = true, ignoreSnapshot = true,
- ignoreSplashscreen = true)
+ testSpec.replacesLayer(
+ ComponentMatcher.LAUNCHER, testApp,
+ ignoreEntriesWithRotationLayer = true, ignoreSnapshot = true,
+ ignoreSplashscreen = true
+ )
}
/**
- * Checks that [FlickerComponentName.LAUNCHER] window is visible at the start of the
- * transition, and is replaced by a snapshot or splash screen (optional), and finally, is
- * replaced by [testApp], which remains visible until the end
+ * Checks that [ComponentMatcher.LAUNCHER] window is the top window at the start of the
+ * transition, and is replaced by a [ComponentMatcher.SNAPSHOT] or
+ * [ComponentMatcher.SPLASH_SCREEN], or [testApp], which remains visible until the end
*/
@Presubmit
@Test
open fun appWindowReplacesLauncherAsTopWindow() {
testSpec.assertWm {
- this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
- .then()
- .isAppWindowOnTop(
- testApp.component
- .or(FlickerComponentName.SNAPSHOT)
- .or(FlickerComponentName.SPLASH_SCREEN)
- )
+ this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
+ .then()
+ .isAppWindowOnTop(
+ testApp
+ .or(ComponentMatcher.SNAPSHOT)
+ .or(ComponentMatcher.SPLASH_SCREEN)
+ )
+ }
+ }
+
+ /**
+ * Checks that [testApp] window is the top window at the en dof the trace
+ */
+ @Presubmit
+ @Test
+ open fun appWindowAsTopWindowAtEnd() {
+ testSpec.assertWmEnd {
+ this.isAppWindowOnTop(testApp)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index fcf7c1d6917f..242a884b2852 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -24,9 +24,12 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
+import com.android.server.wm.flicker.navBarLayerPositionAtEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
import org.junit.FixMethodOrder
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -87,35 +90,41 @@ open class OpenAppFromLockNotificationCold(testSpec: FlickerTestParameter) :
@Test
override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
+ /** {@inheritDoc} */
+ @Ignore("Display is off at the start")
+ override fun navBarLayerPositionAtStartAndEnd() { }
+
/**
- * Checks the position of the navigation bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the position of the [ComponentMatcher.NAV_BAR] at the end of the transition
*/
@Postsubmit
@Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+ fun navBarLayerPositionAtEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerPositionAtEnd()
+ }
+
+ /** {@inheritDoc} */
+ @Ignore("Display is off at the start")
+ override fun statusBarLayerPositionAtStartAndEnd() { }
/**
- * Checks the position of the status bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the
+ * transition
*/
@Postsubmit
@Test
- override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
+ fun statusBarLayerPositionEnd() = testSpec.statusBarLayerPositionAtEnd()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@@ -125,7 +134,7 @@ open class OpenAppFromLockNotificationCold(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@@ -135,7 +144,8 @@ open class OpenAppFromLockNotificationCold(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
/** {@inheritDoc} */
@Postsubmit
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index 46f378e97726..361950514582 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -18,16 +18,19 @@ package com.android.server.wm.flicker.launch
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerPositionAtEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
import org.junit.FixMethodOrder
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -83,16 +86,16 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) :
testSpec.assertWm {
this.hasNoVisibleAppWindow()
.then()
- .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isAppWindowOnTop(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
+ .isAppWindowOnTop(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
.then()
- .isAppWindowOnTop(testApp.component)
+ .isAppWindowOnTop(testApp)
}
}
/**
- * Checks that the screen is locked.
+ * Checks that the screen is locked at the start of the transition
*/
@Test
@Postsubmit
@@ -113,35 +116,41 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) :
override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun navBarLayerPositionAtStartAndEnd() { }
+
/**
- * Checks the position of the navigation bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the position of the [ComponentMatcher.NAV_BAR] at the end of the transition
*/
@Postsubmit
@Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+ fun navBarLayerPositionAtEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerPositionAtEnd()
+ }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun statusBarLayerPositionAtStartAndEnd() { }
/**
- * Checks the position of the status bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the position of the [ComponentMatcher.STATUS_BAR] at the start and end of the
+ * transition
*/
@Postsubmit
@Test
- override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
+ fun statusBarLayerPositionEnd() = testSpec.statusBarLayerPositionAtEnd()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@@ -151,7 +160,7 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@@ -166,7 +175,8 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
/** {@inheritDoc} */
@Postsubmit
@@ -180,6 +190,12 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) :
override fun appWindowIsTopWindowAtEnd() =
super.appWindowIsTopWindowAtEnd()
+ /** {@inheritDoc} */
+ @Presubmit
+ @Test
+ override fun appWindowBecomesTopWindow_ShellTransit() =
+ super.appWindowBecomesTopWindow_ShellTransit()
+
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
index f7ec940d90cd..29730591c957 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
@@ -26,9 +26,7 @@ import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ShowWhenLockedAppHelper
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -67,7 +65,7 @@ class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParamet
// Launch an activity that is shown when the device is locked
showWhenLockedApp.launchViaIntent(wmHelper)
wmHelper.StateSyncBuilder()
- .withFullScreenApp(showWhenLockedApp.component)
+ .withFullScreenApp(showWhenLockedApp)
.waitForAndVerify()
device.sleep()
@@ -90,9 +88,9 @@ class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParamet
testSpec.assertWm {
this.hasNoVisibleAppWindow()
.then()
- .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isAppWindowOnTop(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isAppWindowOnTop(showWhenLockedApp.component)
+ .isAppWindowOnTop(showWhenLockedApp)
}
}
@@ -100,11 +98,11 @@ class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParamet
@Postsubmit
fun showWhenLockedAppLayerBecomesVisible() {
testSpec.assertLayers {
- this.isInvisible(showWhenLockedApp.component)
+ this.isInvisible(showWhenLockedApp)
.then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isVisible(showWhenLockedApp.component)
+ .isVisible(showWhenLockedApp)
}
}
@@ -113,79 +111,11 @@ class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParamet
@Test
override fun entireScreenCovered() = super.entireScreenCovered()
- /**
- * Checks the position of the navigation bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
- */
- @Postsubmit
- @Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
-
- /**
- * Checks the position of the status bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
- */
- @Postsubmit
- @Test
- override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun appLayerBecomesVisible() = super.appLayerBecomesVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
-
/** {@inheritDoc} */
@Postsubmit
@Test
override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun appWindowIsTopWindowAtEnd() =
- super.appWindowIsTopWindowAtEnd()
-
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
index 85024e744dea..5a4b3693f665 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
@@ -17,13 +17,14 @@
package com.android.server.wm.flicker.launch
import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.flicker.statusBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.navBarLayerPositionAtEnd
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
+import org.junit.Ignore
import org.junit.Test
/**
@@ -35,26 +36,25 @@ abstract class OpenAppFromLockTransition(testSpec: FlickerTestParameter) :
/**
* Defines the transition used to run the test
*/
- override val transition: FlickerBuilder.() -> Unit
- get() = {
- super.transition(this)
- setup {
- eachRun {
- device.sleep()
- wmHelper.StateSyncBuilder()
- .withoutTopVisibleAppWindows()
- .waitForAndVerify()
- }
+ override val transition: FlickerBuilder.() -> Unit = {
+ super.transition(this)
+ setup {
+ eachRun {
+ device.sleep()
+ wmHelper.StateSyncBuilder()
+ .withoutTopVisibleAppWindows()
+ .waitForAndVerify()
}
- teardown {
- eachRun {
- testApp.exit(wmHelper)
- }
- }
- transitions {
- testApp.launchViaIntent(wmHelper)
+ }
+ teardown {
+ eachRun {
+ testApp.exit(wmHelper)
}
}
+ transitions {
+ testApp.launchViaIntent(wmHelper)
+ }
+ }
/**
* Check that we go from no focus to focus on the [testApp]
@@ -77,17 +77,16 @@ abstract class OpenAppFromLockTransition(testSpec: FlickerTestParameter) :
testSpec.assertWm {
this.hasNoVisibleAppWindow()
.then()
- .isAppWindowOnTop(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isAppWindowOnTop(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isAppWindowOnTop(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
+ .isAppWindowOnTop(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
.then()
- .isAppWindowOnTop(testApp.component)
+ .isAppWindowOnTop(testApp)
}
}
/**
- * Checks that the screen is locked at the start of the transition ([colorFadComponent])
- * layer is visible
+ * Checks that the screen is locked at the start of the transition
*/
@Presubmit
@Test
@@ -102,36 +101,53 @@ abstract class OpenAppFromLockTransition(testSpec: FlickerTestParameter) :
@Test
override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun navBarLayerPositionAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun statusBarLayerPositionAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun taskBarLayerIsVisibleAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun taskBarWindowIsAlwaysVisible() { }
+
/**
- * Checks the position of the navigation bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the position of the [ComponentMatcher.NAV_BAR] at the end of the transition
*/
@Presubmit
@Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+ open fun navBarLayerPositionAtEnd() {
+ Assume.assumeFalse(testSpec.isTablet)
+ testSpec.navBarLayerPositionAtEnd()
+ }
/**
- * Checks the position of the status bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the position of the [ComponentMatcher.STATUS_BAR] at the end of the transition
*/
- @Postsubmit
+ @Presubmit
@Test
- override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerPositionEnd()
+ fun statusBarLayerPositionAtEnd() = testSpec.statusBarLayerPositionAtEnd()
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun statusBarLayerIsVisibleAtStartAndEnd() { }
/**
- * Checks that the status bar layer is visible at the end of the trace
+ * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible at the end of the trace
*
* It is not possible to check at the start because the screen is off
*/
@Presubmit
@Test
- override fun statusBarLayerIsVisible() {
+ fun statusBarLayerIsVisibleAtEnd() {
testSpec.assertLayersEnd {
- this.isVisible(FlickerComponentName.STATUS_BAR)
+ this.isVisible(ComponentMatcher.STATUS_BAR)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
index eaf4daca6e20..dbe541882fa8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
@@ -42,8 +42,10 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
@Postsubmit
-open class OpenAppFromNotificationCold(testSpec: FlickerTestParameter) :
- OpenAppFromNotificationWarm(testSpec) {
+open class OpenAppFromNotificationCold(
+ testSpec: FlickerTestParameter
+) : OpenAppFromNotificationWarm(testSpec) {
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
@@ -59,10 +61,81 @@ open class OpenAppFromNotificationCold(testSpec: FlickerTestParameter) :
}
}
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun entireScreenCovered() = super.entireScreenCovered()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun notificationAppWindowVisibleAtEnd() = super.notificationAppWindowVisibleAtEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun notificationAppWindowOnTopAtEnd() = super.notificationAppWindowOnTopAtEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun notificationAppLayerVisibleAtEnd() = super.notificationAppLayerVisibleAtEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun appWindowBecomesTopWindow() = super.appWindowBecomesTopWindow()
+
+ /** {@inheritDoc} */
@Test
@Postsubmit
override fun appWindowBecomesVisible() = appWindowBecomesVisible_coldStart()
+ /** {@inheritDoc} */
@Test
@Postsubmit
override fun appLayerBecomesVisible() = appLayerBecomesVisible_coldStart()
@@ -84,7 +157,7 @@ open class OpenAppFromNotificationCold(testSpec: FlickerTestParameter) :
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests(repetitions = 3)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
index 9e9b0c9a1fd9..6e3e74df0193 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
@@ -52,12 +52,14 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
@Postsubmit
-open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
- OpenAppTransition(testSpec) {
+open class OpenAppFromNotificationWarm(
+ testSpec: FlickerTestParameter
+) : OpenAppTransition(testSpec) {
override val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
open val openingNotificationsFromLockScreen = false
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
@@ -68,7 +70,7 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
eachRun {
testApp.launchViaIntent(wmHelper)
wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
+ .withFullScreenApp(testApp)
.waitForAndVerify()
testApp.postNotification(wmHelper)
tapl.goHome()
@@ -83,11 +85,14 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
var endY = 3 * device.displayHeight / 4
var steps = 25
if (openingNotificationsFromLockScreen) {
- val wm = instrumentation.context.getSystemService(WindowManager::class.java)
+ val wm: WindowManager =
+ instrumentation.context.getSystemService(WindowManager::class.java)
+ ?: error("Unable to connect to WindowManager service")
val metricInsets = wm.currentWindowMetrics.windowInsets
val insets = metricInsets.getInsetsIgnoringVisibility(
- WindowInsets.Type.statusBars()
- or WindowInsets.Type.displayCutout())
+ WindowInsets.Type.statusBars()
+ or WindowInsets.Type.displayCutout()
+ )
startY = insets.top + 100
endY = device.displayHeight / 2
@@ -101,14 +106,17 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
instrumentation.uiAutomation.syncInputTransactions()
// Launch the activity by clicking the notification
- val notification = device.wait(Until.findObject(
- By.text("Flicker Test Notification")), 2000L)
+ val notification = device.wait(
+ Until.findObject(
+ By.text("Flicker Test Notification")
+ ), 2000L
+ )
notification?.click() ?: error("Notification not found")
instrumentation.uiAutomation.syncInputTransactions()
// Wait for the app to launch
wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
+ .withFullScreenApp(testApp)
.waitForAndVerify()
}
@@ -119,74 +127,43 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
}
}
- @Test
+ /** {@inheritDoc} */
@Postsubmit
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
@Test
- @Postsubmit
- override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
- @Test
+ /** {@inheritDoc} */
@Postsubmit
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
@Test
- @Postsubmit
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
- @Test
+ /** {@inheritDoc} */
@Postsubmit
- override fun appWindowBecomesVisible() = appWindowBecomesVisible_warmStart()
-
@Test
- @Postsubmit
- override fun appLayerBecomesVisible() = appLayerBecomesVisible_warmStart()
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
- @Test
- @Postsubmit
- fun notificationAppWindowVisibleAtEnd() {
- testSpec.assertWmEnd {
- this.isAppWindowVisible(testApp.component)
- }
- }
-
- @Test
+ /** {@inheritDoc} */
@Postsubmit
- fun notificationAppWindowOnTopAtEnd() {
- testSpec.assertWmEnd {
- this.isAppWindowOnTop(testApp.component)
- }
- }
-
@Test
- @Postsubmit
- fun notificationAppLayerVisibleAtEnd() {
- testSpec.assertLayersEnd {
- this.isVisible(testApp.component)
- }
- }
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun appWindowBecomesTopWindow() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- super.appWindowBecomesTopWindow()
- }
+ override fun appWindowBecomesVisible() = appWindowBecomesVisible_warmStart()
- @FlakyTest(bugId = 229738092)
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun appWindowBecomesTopWindow_ShellTransit() {
- Assume.assumeTrue(isShellTransitionsEnabled)
- super.appWindowBecomesTopWindow()
- }
+ override fun appLayerBecomesVisible() = appLayerBecomesVisible_warmStart()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@@ -196,12 +173,12 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
/** {@inheritDoc} */
@Postsubmit
@Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
@Postsubmit
@@ -215,6 +192,45 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
override fun appWindowIsTopWindowAtEnd() =
super.appWindowIsTopWindowAtEnd()
+ @Postsubmit
+ @Test
+ open fun notificationAppWindowVisibleAtEnd() {
+ testSpec.assertWmEnd {
+ this.isAppWindowVisible(testApp)
+ }
+ }
+
+ @Postsubmit
+ @Test
+ open fun notificationAppWindowOnTopAtEnd() {
+ testSpec.assertWmEnd {
+ this.isAppWindowOnTop(testApp)
+ }
+ }
+
+ @Postsubmit
+ @Test
+ open fun notificationAppLayerVisibleAtEnd() {
+ testSpec.assertLayersEnd {
+ this.isVisible(testApp)
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun appWindowBecomesTopWindow() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ super.appWindowBecomesTopWindow()
+ }
+
+ @FlakyTest(bugId = 229738092)
+ @Test
+ open fun appWindowBecomesTopWindow_ShellTransit() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ super.appWindowBecomesTopWindow()
+ }
+
companion object {
/**
* Creates the test configurations.
@@ -226,7 +242,7 @@ open class OpenAppFromNotificationWarm(testSpec: FlickerTestParameter) :
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests(repetitions = 3)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index c7883d65856d..34c0b2396d01 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -25,9 +25,7 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import com.android.server.wm.flicker.helpers.setRotation
-import org.junit.Assume
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -58,8 +56,9 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) :
- OpenAppFromLauncherTransition(testSpec) {
+open class OpenAppFromOverviewTest(
+ testSpec: FlickerTestParameter
+) : OpenAppFromLauncherTransition(testSpec) {
/**
* Defines the transition used to run the test
@@ -77,8 +76,12 @@ open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) :
wmHelper.StateSyncBuilder()
.withHomeActivityVisible()
.waitForAndVerify()
- // Launcher is always ROTATION_0
- tapl.setExpectedRotation(Surface.ROTATION_0)
+ // By default, launcher doesn't rotate on phones, but rotates on tablets
+ if (testSpec.isTablet) {
+ tapl.setExpectedRotation(testSpec.startRotation)
+ } else {
+ tapl.setExpectedRotation(Surface.ROTATION_0)
+ }
tapl.workspace.switchToOverview()
wmHelper.StateSyncBuilder()
.withRecentsActivityVisible()
@@ -89,17 +92,12 @@ open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) :
transitions {
tapl.overview.currentTask.open()
wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
+ .withFullScreenApp(testApp)
.waitForAndVerify()
}
}
/** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
- /** {@inheritDoc} */
@Presubmit
@Test
override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
@@ -107,17 +105,7 @@ open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@FlakyTest
@Test
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
/** {@inheritDoc} */
@Presubmit
@@ -129,41 +117,6 @@ open class OpenAppFromOverviewTest(testSpec: FlickerTestParameter) :
@Test
override fun appWindowBecomesVisible() = super.appWindowBecomesVisible_warmStart()
- /** {@inheritDoc} */
- @FlakyTest(bugId = 229735718)
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun appWindowReplacesLauncherAsTopWindow() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- super.appWindowReplacesLauncherAsTopWindow()
- }
-
- @FlakyTest(bugId = 229738092)
- @Test
- fun appWindowReplacesLauncherAsTopWindow_ShellTransit() {
- Assume.assumeTrue(isShellTransitionsEnabled)
- super.appWindowReplacesLauncherAsTopWindow()
- }
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun appWindowBecomesTopWindow() {
- Assume.assumeFalse(isShellTransitionsEnabled)
- super.appWindowBecomesTopWindow()
- }
-
- @FlakyTest(bugId = 229738092)
- @Test
- fun appWindowBecomesTopWindow_ShellTransit() {
- Assume.assumeTrue(isShellTransitionsEnabled)
- super.appWindowBecomesTopWindow()
- }
-
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index ec083509f364..c03cb56d80d3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -27,10 +27,11 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
-import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.navBarLayerPositionEnd
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import com.android.server.wm.traces.common.ComponentMatcher
+import org.junit.Assume
import org.junit.FixMethodOrder
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -65,16 +66,16 @@ open class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) :
override val testApp = NonResizeableAppHelper(instrumentation)
/**
- * Checks that the nav bar layer starts invisible, becomes visible during unlocking animation
- * and remains visible at the end
+ * Checks that the [ComponentMatcher.NAV_BAR] layer starts invisible, becomes visible during
+ * unlocking animation and remains visible at the end
*/
@FlakyTest(bugId = 227083463)
@Test
fun navBarLayerVisibilityChanges() {
testSpec.assertLayers {
- this.isInvisible(FlickerComponentName.NAV_BAR)
+ this.isInvisible(ComponentMatcher.NAV_BAR)
.then()
- .isVisible(FlickerComponentName.NAV_BAR)
+ .isVisible(ComponentMatcher.NAV_BAR)
}
}
@@ -85,63 +86,89 @@ open class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) :
@Test
fun appWindowBecomesVisibleAtEnd() {
testSpec.assertWmEnd {
- this.isAppWindowVisible(testApp.component)
+ this.isAppWindowVisible(testApp)
}
}
/**
- * Checks that the nav bar starts the transition invisible, then becomes visible during
- * the unlocking animation and remains visible at the end of the transition
+ * Checks that the [ComponentMatcher.NAV_BAR] starts the transition invisible, then becomes
+ * visible during the unlocking animation and remains visible at the end of the transition
*/
@Presubmit
@Test
fun navBarWindowsVisibilityChanges() {
+ Assume.assumeFalse(testSpec.isTablet)
testSpec.assertWm {
- this.isNonAppWindowInvisible(FlickerComponentName.NAV_BAR)
+ this.isNonAppWindowInvisible(ComponentMatcher.NAV_BAR)
.then()
- .isAboveAppWindowVisible(FlickerComponentName.NAV_BAR)
+ .isAboveAppWindowVisible(ComponentMatcher.NAV_BAR)
}
}
/**
- * Checks that the status bar layer is visible at the end of the trace
+ * Checks that the [ComponentMatcher.TASK_BAR] starts the transition invisible, then becomes
+ * visible during the unlocking animation and remains visible at the end of the transition
+ */
+ @Presubmit
+ @Test
+ fun taskBarLayerIsVisibleAtEnd() {
+ Assume.assumeTrue(testSpec.isTablet)
+ testSpec.assertLayersEnd {
+ this.isVisible(ComponentMatcher.TASK_BAR)
+ }
+ }
+
+ /**
+ * Checks that the [ComponentMatcher.STATUS_BAR] layer is visible at the end of the trace
*
* It is not possible to check at the start because the screen is off
*/
@Presubmit
@Test
- override fun statusBarLayerIsVisible() {
+ override fun statusBarLayerIsVisibleAtStartAndEnd() {
testSpec.assertLayersEnd {
- this.isVisible(FlickerComponentName.STATUS_BAR)
+ this.isVisible(ComponentMatcher.STATUS_BAR)
}
}
/** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun taskBarLayerIsVisibleAtStartAndEnd() { }
/** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun navBarLayerIsVisibleAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun taskBarWindowIsAlwaysVisible() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun navBarWindowIsAlwaysVisible() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. Display starts off and app is full screen at the end")
+ override fun statusBarWindowIsAlwaysVisible() { }
+
+ /**
+ * Checks the position of the [ComponentMatcher.STATUS_BAR] at the end of the
+ * transition
+ */
+ @Presubmit
@Test
- fun statusBarLayerPositionAtEnd() {
- testSpec.assertLayersEnd {
- val display = this.entry.displays.minByOrNull { it.id }
- ?: error("There is no display!")
- this.visibleRegion(FlickerComponentName.STATUS_BAR)
- .coversExactly(WindowUtils.getStatusBarPosition(display))
- }
- }
+ fun statusBarLayerPositionEnd() = testSpec.statusBarLayerPositionAtEnd()
/**
- * Checks the position of the navigation bar at the start and end of the transition
- *
- * Differently from the normal usage of this assertion, check only the final state of the
- * transition because the display is off at the start and the NavBar is never visible
+ * Checks the [ComponentMatcher.NAV_BAR] is visible at the end of the transition
*/
@Postsubmit
@Test
- override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
+ fun navBarLayerIsVisibleAtEnd() {
+ testSpec.assertLayersEnd {
+ this.isVisible(ComponentMatcher.NAV_BAR)
+ }
+ }
/** {@inheritDoc} */
@FlakyTest
@@ -150,6 +177,22 @@ open class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) :
super.visibleLayersShownMoreThanOneConsecutiveEntry()
/** {@inheritDoc} */
+ @Presubmit
+ @Test
+ override fun appLayerBecomesVisible() {
+ Assume.assumeFalse(testSpec.isTablet)
+ super.appLayerBecomesVisible()
+ }
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 227143265)
+ @Test
+ fun appLayerBecomesVisibleTablet() {
+ Assume.assumeTrue(testSpec.isTablet)
+ super.appLayerBecomesVisible()
+ }
+
+ /** {@inheritDoc} */
@FlakyTest
@Test
override fun entireScreenCovered() = super.entireScreenCovered()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index 9c97970b4b91..5d2b56707de9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -16,39 +16,25 @@
package com.android.server.wm.flicker.launch
-import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.Test
/**
* Base class for app launch tests
*/
-abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
- protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+abstract class OpenAppTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
- protected val tapl = LauncherInstrumentation()
- /**
- * Defines the transition used to run the test
- */
- protected open val transition: FlickerBuilder.() -> Unit = {
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
setup {
test {
tapl.setExpectedRotation(testSpec.startRotation)
@@ -64,129 +50,43 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
}
/**
- * Entry point for the test runner. It will use this method to initialize and cache
- * flicker executions
- */
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- transition()
- }
- }
-
- /**
- * Checks that the navigation bar window is visible during the whole transition
- */
- open fun navBarWindowIsVisible() {
- testSpec.navBarWindowIsVisible()
- }
-
- /**
- * Checks that the navigation bar layer is visible at the start and end of the trace
- */
- open fun navBarLayerIsVisible() {
- testSpec.navBarLayerIsVisible()
- }
-
- /**
- * Checks the position of the navigation bar at the start and end of the transition
+ * Checks that the [testApp] layer doesn't exist or is invisible at the start of the
+ * transition, but is created and/or becomes visible during the transition.
*/
@Presubmit
@Test
- open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- /**
- * Checks that the status bar window is visible during the whole transition
- */
- @Presubmit
- @Test
- open fun statusBarWindowIsVisible() {
- testSpec.statusBarWindowIsVisible()
- }
-
- /**
- * Checks that the status bar layer is visible at the start and end of the trace
- */
- @Presubmit
- @Test
- open fun statusBarLayerIsVisible() {
- testSpec.statusBarLayerIsVisible()
+ open fun appLayerBecomesVisible() {
+ appLayerBecomesVisible_coldStart()
}
- /**
- * Checks the position of the status bar at the start and end of the transition
- */
- @Presubmit
- @Test
- open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
- /**
- * Checks that all windows that are visible on the trace, are visible for at least 2
- * consecutive entries.
- */
- @Presubmit
- @Test
- open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
- }
- }
-
- /**
- * Checks that all layers that are visible on the trace, are visible for at least 2
- * consecutive entries.
- */
- @Presubmit
- @Test
- open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- testSpec.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry()
- }
- }
-
- /**
- * Checks that all parts of the screen are covered during the transition
- */
- @Presubmit
- @Test
- open fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- /**
- * Checks that the app layer doesn't exist or is invisible at the start of the transition, but
- * is created and/or becomes visible during the transition.
- */
- @Presubmit
- @Test
- open fun appLayerBecomesVisible() = appLayerBecomesVisible_coldStart()
-
protected fun appLayerBecomesVisible_coldStart() {
testSpec.assertLayers {
- this.notContains(testApp.component)
- .then()
- .isInvisible(testApp.component, isOptional = true)
- .then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
- .then()
- .isVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
- .then()
- .isVisible(testApp.component)
+ this.notContains(testApp)
+ .then()
+ .isInvisible(testApp, isOptional = true)
+ .then()
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isVisible(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isVisible(testApp)
}
}
protected fun appLayerBecomesVisible_warmStart() {
testSpec.assertLayers {
- this.isInvisible(testApp.component)
- .then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
- .then()
- .isVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
- .then()
- .isVisible(testApp.component)
+ this.isInvisible(testApp)
+ .then()
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isVisible(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isVisible(testApp)
}
}
/**
- * Checks that the app window doesn't exist at the start of the transition, that it is
+ * Checks that the [testApp] window doesn't exist at the start of the transition, that it is
* created (invisible - optional) and becomes visible during the transition
*
* The `isAppWindowInvisible` step is optional because we log once per frame, upon logging,
@@ -198,23 +98,23 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
protected fun appWindowBecomesVisible_coldStart() {
testSpec.assertWm {
- this.notContains(testApp.component)
- .then()
- .isAppWindowInvisible(testApp.component, isOptional = true)
- .then()
- .isAppWindowVisible(testApp.component)
+ this.notContains(testApp)
+ .then()
+ .isAppWindowInvisible(testApp, isOptional = true)
+ .then()
+ .isAppWindowVisible(testApp)
}
}
protected fun appWindowBecomesVisible_warmStart() {
testSpec.assertWm {
- this.isAppWindowInvisible(testApp.component)
- .then()
- .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
- .then()
- .isAppWindowVisible(FlickerComponentName.SPLASH_SCREEN, isOptional = true)
- .then()
- .isAppWindowVisible(testApp.component)
+ this.isAppWindowInvisible(testApp)
+ .then()
+ .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isAppWindowVisible(ComponentMatcher.SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isAppWindowVisible(testApp)
}
}
@@ -226,13 +126,13 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
@Test
open fun appWindowBecomesTopWindow() {
testSpec.assertWm {
- this.isAppWindowNotOnTop(testApp.component)
- .then()
- .isAppWindowOnTop(
- testApp.component
- .or(FlickerComponentName.SNAPSHOT)
- .or(FlickerComponentName.SPLASH_SCREEN)
- )
+ this.isAppWindowNotOnTop(testApp)
+ .then()
+ .isAppWindowOnTop(
+ testApp
+ .or(ComponentMatcher.SNAPSHOT)
+ .or(ComponentMatcher.SPLASH_SCREEN)
+ )
}
}
@@ -244,7 +144,7 @@ abstract class OpenAppTransition(protected val testSpec: FlickerTestParameter) {
@Test
open fun appWindowIsTopWindowAtEnd() {
testSpec.assertWmEnd {
- this.isAppWindowOnTop(testApp.component)
+ this.isAppWindowOnTop(testApp)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index 88e2b2d8e7b7..bc5ab7dfcdcf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -87,24 +87,7 @@ open class OpenAppWarmTest(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun appWindowReplacesLauncherAsTopWindow() =
- super.appWindowReplacesLauncherAsTopWindow()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @FlakyTest
- @Test
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
/** {@inheritDoc} */
@Presubmit
@@ -114,16 +97,6 @@ open class OpenAppWarmTest(testSpec: FlickerTestParameter) :
/** {@inheritDoc} */
@Presubmit
@Test
- override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
- override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
- /** {@inheritDoc} */
- @Presubmit
- @Test
override fun appLayerBecomesVisible() = super.appLayerBecomesVisible_warmStart()
/** {@inheritDoc} */
@@ -131,10 +104,6 @@ open class OpenAppWarmTest(testSpec: FlickerTestParameter) :
@Test
override fun appWindowBecomesVisible() = super.appWindowBecomesVisible_warmStart()
- @FlakyTest(bugId = 229735718)
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
-
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index 99df1f4b5798..4beb5d019957 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -20,26 +20,20 @@ import android.app.Instrumentation
import android.app.WallpaperManager
import android.platform.test.annotations.Postsubmit
import androidx.test.filters.RequiresDevice
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.NewTasksAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.flicker.testapp.ActivityOptions.LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME
import com.android.server.wm.flicker.testapp.ActivityOptions.SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.SPLASH_SCREEN
-import com.android.server.wm.traces.common.FlickerComponentName.Companion.WALLPAPER_BBQ_WRAPPER
+import com.android.server.wm.traces.common.ComponentMatcher
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.SPLASH_SCREEN
+import com.android.server.wm.traces.common.ComponentMatcher.Companion.WALLPAPER_BBQ_WRAPPER
+import com.android.server.wm.traces.common.IComponentMatcher
import com.android.server.wm.traces.parser.toFlickerComponent
import org.junit.FixMethodOrder
import org.junit.Test
@@ -62,83 +56,81 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
-class TaskTransitionTest(val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
- private val tapl = LauncherInstrumentation()
- private val mTestApp: NewTasksAppHelper = NewTasksAppHelper(instrumentation)
- private val mWallpaper by lazy {
+class TaskTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
+ private val testApp: NewTasksAppHelper = NewTasksAppHelper(instrumentation)
+ private val wallpaper by lazy {
getWallpaperPackage(instrumentation) ?: error("Unable to obtain wallpaper")
}
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- eachRun {
- mTestApp.launchViaIntent(wmHelper)
- }
- }
- teardown {
- test {
- mTestApp.exit(wmHelper)
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
}
- transitions {
- mTestApp.openNewTask(device, wmHelper)
- tapl.pressBack()
- wmHelper.StateSyncBuilder()
- .withFullScreenApp(mTestApp.component)
- .waitForAndVerify()
+ }
+ teardown {
+ test {
+ testApp.exit(wmHelper)
}
}
+ transitions {
+ testApp.openNewTask(device, wmHelper)
+ tapl.pressBack()
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp)
+ .waitForAndVerify()
+ }
}
/**
- * Checks that the wallpaper window is never visible when performing task transitions.
+ * Checks that the [wallpaper] window is never visible when performing task transitions.
* A solid color background should be shown instead.
*/
@Postsubmit
@Test
fun wallpaperWindowIsNeverVisible() {
testSpec.assertWm {
- this.isNonAppWindowInvisible(mWallpaper)
+ this.isNonAppWindowInvisible(wallpaper)
}
}
/**
- * Checks that the wallpaper layer is never visible when performing task transitions.
+ * Checks that the [wallpaper] layer is never visible when performing task transitions.
* A solid color background should be shown instead.
*/
@Postsubmit
@Test
fun wallpaperLayerIsNeverVisible() {
testSpec.assertLayers {
- this.isInvisible(mWallpaper)
+ this.isInvisible(wallpaper)
this.isInvisible(WALLPAPER_BBQ_WRAPPER)
}
}
/**
- * Check that the launcher window is never visible when performing task transitions.
+ * Check that the [ComponentMatcher.LAUNCHER] window is never visible when performing task
+ * transitions.
* A solid color background should be shown above it.
*/
@Postsubmit
@Test
fun launcherWindowIsNeverVisible() {
testSpec.assertWm {
- this.isAppWindowInvisible(FlickerComponentName.LAUNCHER)
+ this.isAppWindowInvisible(ComponentMatcher.LAUNCHER)
}
}
/**
- * Checks that the launcher layer is never visible when performing task transitions.
+ * Checks that the [ComponentMatcher.LAUNCHER] layer is never visible when performing task
+ * transitions.
* A solid color background should be shown above it.
*/
@Postsubmit
@Test
fun launcherLayerIsNeverVisible() {
testSpec.assertLayers {
- this.isInvisible(FlickerComponentName.LAUNCHER)
+ this.isInvisible(ComponentMatcher.LAUNCHER)
}
}
@@ -148,13 +140,13 @@ class TaskTransitionTest(val testSpec: FlickerTestParameter) {
@Postsubmit
@Test
fun colorLayerIsVisibleDuringTransition() {
- val bgColorLayer = FlickerComponentName("", "colorBackgroundLayer")
+ val bgColorLayer = ComponentMatcher("", "colorBackgroundLayer")
val displayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
testSpec.assertLayers {
this.invoke("LAUNCH_NEW_TASK_ACTIVITY coversExactly displayBounds") {
- it.visibleRegion(LAUNCH_NEW_TASK_ACTIVITY).coversExactly(displayBounds)
- }
+ it.visibleRegion(LAUNCH_NEW_TASK_ACTIVITY).coversExactly(displayBounds)
+ }
.isInvisible(bgColorLayer)
.then()
// Transitioning
@@ -186,58 +178,82 @@ class TaskTransitionTest(val testSpec: FlickerTestParameter) {
fun newTaskOpensOnTopAndThenCloses() {
testSpec.assertWm {
this.isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
- .then()
- .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
- .then()
- .isAppWindowOnTop(SIMPLE_ACTIVITY)
- .then()
- .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
- .then()
- .isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
+ .then()
+ .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isAppWindowOnTop(SIMPLE_ACTIVITY)
+ .then()
+ .isAppWindowOnTop(SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isAppWindowOnTop(LAUNCH_NEW_TASK_ACTIVITY)
}
}
- /**
- * Checks that all parts of the screen are covered at the start and end of the transition
- */
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun entireScreenCovered() = testSpec.entireScreenCovered()
+ override fun entireScreenCovered() = super.entireScreenCovered()
- /**
- * Checks that the navbar window is visible throughout the transition
- */
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
- /**
- * Checks that the navbar layer is visible throughout the transition
- */
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
+ override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
- /**
- * Checks that the status bar window is visible throughout the transition
- */
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
- /**
- * Checks that the status bar layer is visible throughout the transition
- */
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @Postsubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ /** {@inheritDoc} */
@Postsubmit
@Test
- fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
private val LAUNCH_NEW_TASK_ACTIVITY =
- LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
+ LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
private val SIMPLE_ACTIVITY = SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent()
- private fun getWallpaperPackage(instrumentation: Instrumentation): FlickerComponentName? {
+ private fun getWallpaperPackage(instrumentation: Instrumentation): IComponentMatcher? {
val wallpaperManager = WallpaperManager.getInstance(instrumentation.targetContext)
return wallpaperManager.wallpaperInfo?.component?.toFlickerComponent()
@@ -247,7 +263,7 @@ class TaskTransitionTest(val testSpec: FlickerTestParameter) {
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests(repetitions = 3)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index 1a712842fec0..45b7be594530 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -16,15 +16,12 @@
package com.android.server.wm.flicker.quickswitch
-import android.app.Instrumentation
-import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,12 +30,7 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.server.wm.traces.common.Rect
import org.junit.Assume
import org.junit.Before
@@ -64,10 +56,9 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
- private val tapl = LauncherInstrumentation()
-
+open class QuickSwitchBetweenTwoAppsBackTest(
+ testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
private val testApp1 = SimpleAppHelper(instrumentation)
private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -76,32 +67,31 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
Assume.assumeFalse(isShellTransitionsEnabled)
}
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- tapl.setExpectedRotation(testSpec.startRotation)
- }
- eachRun {
- testApp1.launchViaIntent(wmHelper)
- testApp2.launchViaIntent(wmHelper)
- startDisplayBounds = wmHelper.currentState.layerState
- .physicalDisplayBounds ?: error("Display not found")
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ tapl.setExpectedRotation(testSpec.startRotation)
}
- transitions {
- tapl.launchedAppState.quickSwitchToPreviousApp()
- wmHelper.StateSyncBuilder()
- .withNavBarStatusBarVisible()
- .waitForAndVerify()
+ eachRun {
+ testApp1.launchViaIntent(wmHelper)
+ testApp2.launchViaIntent(wmHelper)
+ startDisplayBounds = wmHelper.currentState.layerState
+ .physicalDisplayBounds ?: error("Display not found")
}
+ }
+ transitions {
+ tapl.launchedAppState.quickSwitchToPreviousApp()
+ wmHelper.StateSyncBuilder()
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
+ .waitForAndVerify()
+ }
- teardown {
- test {
- testApp1.exit(wmHelper)
- testApp2.exit(wmHelper)
- }
+ teardown {
+ test {
+ testApp1.exit(wmHelper)
+ testApp2.exit(wmHelper)
}
}
}
@@ -112,9 +102,9 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
*/
@Presubmit
@Test
- fun startsWithApp2WindowsCoverFullScreen() {
+ open fun startsWithApp2WindowsCoverFullScreen() {
testSpec.assertWmStart {
- this.frameRegion(testApp2.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp2).coversExactly(startDisplayBounds)
}
}
@@ -124,9 +114,9 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
*/
@Presubmit
@Test
- fun startsWithApp2LayersCoverFullScreen() {
+ open fun startsWithApp2LayersCoverFullScreen() {
testSpec.assertLayersStart {
- this.visibleRegion(testApp2.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp2).coversExactly(startDisplayBounds)
}
}
@@ -135,103 +125,103 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
*/
@Presubmit
@Test
- fun startsWithApp2WindowBeingOnTop() {
+ open fun startsWithApp2WindowBeingOnTop() {
testSpec.assertWmStart {
- this.isAppWindowOnTop(testApp2.component)
+ this.isAppWindowOnTop(testApp2)
}
}
/**
- * Checks that [testApp1] windows fill the entire screen (i.e. is "fullscreen") at the end of the
- * transition once we have fully quick switched from [testApp2] back to the [testApp1].
+ * Checks that [testApp1] windows fill the entire screen (i.e. is "fullscreen") at the end of
+ * the transition once we have fully quick switched from [testApp2] back to the [testApp1].
*/
@Presubmit
@Test
- fun endsWithApp1WindowsCoveringFullScreen() {
+ open fun endsWithApp1WindowsCoveringFullScreen() {
testSpec.assertWmEnd {
- this.frameRegion(testApp1.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp1).coversExactly(startDisplayBounds)
}
}
/**
- * Checks that [testApp1] layers fill the entire screen (i.e. is "fullscreen") at the end of the
- * transition once we have fully quick switched from [testApp2] back to the [testApp1].
+ * Checks that [testApp1] layers fill the entire screen (i.e. is "fullscreen") at the end of
+ * the transition once we have fully quick switched from [testApp2] back to the [testApp1].
*/
@Presubmit
@Test
fun endsWithApp1LayersCoveringFullScreen() {
testSpec.assertLayersEnd {
- this.visibleRegion(testApp1.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp1).coversExactly(startDisplayBounds)
}
}
/**
- * Checks that [testApp1] is the top window at the end of the transition once we have fully quick
- * switched from [testApp2] back to the [testApp1].
+ * Checks that [testApp1] is the top window at the end of the transition once we have fully
+ * quick switched from [testApp2] back to the [testApp1].
*/
@Presubmit
@Test
- fun endsWithApp1BeingOnTop() {
+ open fun endsWithApp1BeingOnTop() {
testSpec.assertWmEnd {
- this.isAppWindowOnTop(testApp1.component)
+ this.isAppWindowOnTop(testApp1)
}
}
/**
- * Checks that [testApp1]'s window starts off invisible and becomes visible at some point before
- * the end of the transition and then stays visible until the end of the transition.
+ * Checks that [testApp1]'s window starts off invisible and becomes visible at some point
+ * before the end of the transition and then stays visible until the end of the transition.
*/
@Presubmit
@Test
- fun app1WindowBecomesAndStaysVisible() {
+ open fun app1WindowBecomesAndStaysVisible() {
testSpec.assertWm {
- this.isAppWindowInvisible(testApp1.component)
- .then()
- .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
- .then()
- .isAppWindowVisible(testApp1.component)
+ this.isAppWindowInvisible(testApp1)
+ .then()
+ .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isAppWindowVisible(testApp1)
}
}
/**
- * Checks that [testApp1]'s layer starts off invisible and becomes visible at some point before
- * the end of the transition and then stays visible until the end of the transition.
+ * Checks that [testApp1]'s layer starts off invisible and becomes visible at some point
+ * before the end of the transition and then stays visible until the end of the transition.
*/
@Presubmit
@Test
- fun app1LayerBecomesAndStaysVisible() {
+ open fun app1LayerBecomesAndStaysVisible() {
testSpec.assertLayers {
- this.isInvisible(testApp1.component)
- .then()
- .isVisible(testApp1.component)
+ this.isInvisible(testApp1)
+ .then()
+ .isVisible(testApp1)
}
}
/**
- * Checks that [testApp2]'s window starts off visible and becomes invisible at some point before
- * the end of the transition and then stays invisible until the end of the transition.
+ * Checks that [testApp2]'s window starts off visible and becomes invisible at some point
+ * before the end of the transition and then stays invisible until the end of the transition.
*/
@Presubmit
@Test
- fun app2WindowBecomesAndStaysInvisible() {
+ open fun app2WindowBecomesAndStaysInvisible() {
testSpec.assertWm {
- this.isAppWindowVisible(testApp2.component)
- .then()
- .isAppWindowInvisible(testApp2.component)
+ this.isAppWindowVisible(testApp2)
+ .then()
+ .isAppWindowInvisible(testApp2)
}
}
/**
- * Checks that [testApp2]'s layer starts off visible and becomes invisible at some point before
- * the end of the transition and then stays invisible until the end of the transition.
+ * Checks that [testApp2]'s layer starts off visible and becomes invisible at some point
+ * before the end of the transition and then stays invisible until the end of the transition.
*/
@Presubmit
@Test
- fun app2LayerBecomesAndStaysInvisible() {
+ open fun app2LayerBecomesAndStaysInvisible() {
testSpec.assertLayers {
- this.isVisible(testApp2.component)
- .then()
- .isInvisible(testApp2.component)
+ this.isVisible(testApp2)
+ .then()
+ .isInvisible(testApp2)
}
}
@@ -242,16 +232,16 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
*/
@Presubmit
@Test
- fun app1WindowIsVisibleOnceApp2WindowIsInvisible() {
+ open fun app1WindowIsVisibleOnceApp2WindowIsInvisible() {
testSpec.assertWm {
- this.isAppWindowVisible(testApp2.component)
- .then()
- // TODO: Do we actually want to test this? Seems too implementation specific...
- .isAppWindowVisible(FlickerComponentName.LAUNCHER, isOptional = true)
- .then()
- .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
- .then()
- .isAppWindowVisible(testApp1.component)
+ this.isAppWindowVisible(testApp2)
+ .then()
+ // TODO: Do we actually want to test this? Seems too implementation specific...
+ .isAppWindowVisible(ComponentMatcher.LAUNCHER, isOptional = true)
+ .then()
+ .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isAppWindowVisible(testApp1)
}
}
@@ -262,54 +252,28 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
*/
@Presubmit
@Test
- fun app1LayerIsVisibleOnceApp2LayerIsInvisible() {
+ open fun app1LayerIsVisibleOnceApp2LayerIsInvisible() {
testSpec.assertLayers {
- this.isVisible(testApp2.component)
- .then()
- .isVisible(FlickerComponentName.LAUNCHER, isOptional = true)
- .then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
- .then()
- .isVisible(testApp1.component)
+ this.isVisible(testApp2)
+ .then()
+ .isVisible(ComponentMatcher.LAUNCHER, isOptional = true)
+ .then()
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isVisible(testApp1)
}
}
- /**
- * Checks that the navbar window is visible throughout the entire transition.
- */
- @Presubmit
- @Test
- fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible()
-
- /**
- * Checks that the navbar layer is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun navBarLayerAlwaysIsVisible() = testSpec.navBarLayerIsVisible()
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- /**
- * Checks that the navbar is always in the right position and covers the expected region.
- *
- * NOTE: This doesn't check that the navbar is visible or not.
- */
- @FlakyTest
- @Test
- fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
-
- /**
- * Checks that the status bar window is visible throughout the entire transition.
- */
- @Presubmit
- @Test
- fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsVisible()
-
- /**
- * Checks that the status bar layer is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsVisible()
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
companion object {
private var startDisplayBounds = Rect.EMPTY
@@ -318,13 +282,13 @@ open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestPa
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- ),
- supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
- )
+ .getConfigNonRotationTests(
+ repetitions = 3,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ ),
+ supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
index cabae505f94e..e007fe354994 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest_ShellTransit.kt
@@ -16,8 +16,8 @@
package com.android.server.wm.flicker.quickswitch
-import android.platform.test.annotations.RequiresDevice
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group1
@@ -25,6 +25,7 @@ import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume
import org.junit.Before
import org.junit.FixMethodOrder
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -45,11 +46,34 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-@FlakyTest(bugId = 228009808)
-open class QuickSwitchBetweenTwoAppsBackTest_ShellTransit(testSpec: FlickerTestParameter)
- : QuickSwitchBetweenTwoAppsBackTest(testSpec) {
+open class QuickSwitchBetweenTwoAppsBackTest_ShellTransit(
+ testSpec: FlickerTestParameter
+) : QuickSwitchBetweenTwoAppsBackTest(testSpec) {
@Before
override fun before() {
Assume.assumeTrue(isShellTransitionsEnabled)
}
+
+ @FlakyTest(bugId = 228009808)
+ @Test
+ override fun app1LayerIsVisibleOnceApp2LayerIsInvisible() =
+ super.app1LayerIsVisibleOnceApp2LayerIsInvisible()
+
+ @FlakyTest(bugId = 228009808)
+ @Test
+ override fun app1WindowBecomesAndStaysVisible() = super.app1WindowBecomesAndStaysVisible()
+
+ @FlakyTest(bugId = 228009808)
+ @Test
+ override fun endsWithApp1BeingOnTop() = super.endsWithApp1BeingOnTop()
+
+ @FlakyTest(bugId = 239147075)
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ @FlakyTest(bugId = 239147075)
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 9e43a97a6242..4ce3b15e292c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -16,15 +16,13 @@
package com.android.server.wm.flicker.quickswitch
-import android.app.Instrumentation
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -33,12 +31,7 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.server.wm.traces.common.Rect
import org.junit.Assume
import org.junit.Before
@@ -64,10 +57,9 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
- private val tapl = LauncherInstrumentation()
-
+open class QuickSwitchBetweenTwoAppsForwardTest(
+ testSpec: FlickerTestParameter
+) : BaseTest(testSpec) {
private val testApp1 = SimpleAppHelper(instrumentation)
private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -76,36 +68,36 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
Assume.assumeFalse(isShellTransitionsEnabled)
}
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- tapl.setExpectedRotation(testSpec.startRotation)
- }
- eachRun {
- testApp1.launchViaIntent(wmHelper)
- testApp2.launchViaIntent(wmHelper)
- tapl.launchedAppState.quickSwitchToPreviousApp()
- wmHelper.StateSyncBuilder()
- .withNavBarStatusBarVisible()
- .waitForAndVerify()
- startDisplayBounds = wmHelper.currentState.layerState
- .physicalDisplayBounds ?: error("Display not found")
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ tapl.setExpectedRotation(testSpec.startRotation)
}
- transitions {
- tapl.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
+ eachRun {
+ testApp1.launchViaIntent(wmHelper)
+ testApp2.launchViaIntent(wmHelper)
+ tapl.launchedAppState.quickSwitchToPreviousApp()
wmHelper.StateSyncBuilder()
- .withNavBarStatusBarVisible()
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
.waitForAndVerify()
+ startDisplayBounds = wmHelper.currentState.layerState
+ .physicalDisplayBounds ?: error("Display not found")
}
+ }
+ transitions {
+ tapl.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
+ wmHelper.StateSyncBuilder()
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
+ .waitForAndVerify()
+ }
- teardown {
- test {
- testApp1.exit(wmHelper)
- testApp2.exit(wmHelper)
- }
+ teardown {
+ test {
+ testApp1.exit(wmHelper)
+ testApp2.exit(wmHelper)
}
}
}
@@ -118,7 +110,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun startsWithApp1WindowsCoverFullScreen() {
testSpec.assertWmStart {
- this.frameRegion(testApp1.component, FlickerComponentName.LETTERBOX)
+ this.visibleRegion(testApp1.or(ComponentMatcher.LETTERBOX))
.coversExactly(startDisplayBounds)
}
}
@@ -131,7 +123,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun startsWithApp1LayersCoverFullScreen() {
testSpec.assertLayersStart {
- this.visibleRegion(testApp1.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp1).coversExactly(startDisplayBounds)
}
}
@@ -142,7 +134,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun startsWithApp1WindowBeingOnTop() {
testSpec.assertWmStart {
- this.isAppWindowOnTop(testApp1.component)
+ this.isAppWindowOnTop(testApp1)
}
}
@@ -154,7 +146,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun endsWithApp2WindowsCoveringFullScreen() {
testSpec.assertWmEnd {
- this.frameRegion(testApp2.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp2).coversExactly(startDisplayBounds)
}
}
@@ -166,7 +158,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun endsWithApp2LayersCoveringFullScreen() {
testSpec.assertLayersEnd {
- this.visibleRegion(testApp2.component, FlickerComponentName.LETTERBOX)
+ this.visibleRegion(testApp2.or(ComponentMatcher.LETTERBOX))
.coversExactly(startDisplayBounds)
}
}
@@ -179,7 +171,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun endsWithApp2BeingOnTop() {
testSpec.assertWmEnd {
- this.isAppWindowOnTop(testApp2.component)
+ this.isAppWindowOnTop(testApp2)
}
}
@@ -191,11 +183,11 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun app2WindowBecomesAndStaysVisible() {
testSpec.assertWm {
- this.isAppWindowInvisible(testApp2.component)
+ this.isAppWindowInvisible(testApp2)
.then()
- .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isAppWindowVisible(testApp2.component)
+ .isAppWindowVisible(testApp2)
}
}
@@ -207,9 +199,9 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun app2LayerBecomesAndStaysVisible() {
testSpec.assertLayers {
- this.isInvisible(testApp2.component)
+ this.isInvisible(testApp2)
.then()
- .isVisible(testApp2.component)
+ .isVisible(testApp2)
}
}
@@ -221,9 +213,9 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun app1WindowBecomesAndStaysInvisible() {
testSpec.assertWm {
- this.isAppWindowVisible(testApp1.component)
+ this.isAppWindowVisible(testApp1)
.then()
- .isAppWindowInvisible(testApp1.component)
+ .isAppWindowInvisible(testApp1)
}
}
@@ -235,9 +227,9 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun app1LayerBecomesAndStaysInvisible() {
testSpec.assertLayers {
- this.isVisible(testApp1.component)
+ this.isVisible(testApp1)
.then()
- .isInvisible(testApp1.component)
+ .isInvisible(testApp1)
}
}
@@ -250,13 +242,13 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun app2WindowIsVisibleOnceApp1WindowIsInvisible() {
testSpec.assertWm {
- this.isAppWindowVisible(testApp1.component)
+ this.isAppWindowVisible(testApp1)
.then()
- .isAppWindowVisible(FlickerComponentName.LAUNCHER, isOptional = true)
+ .isAppWindowVisible(ComponentMatcher.LAUNCHER, isOptional = true)
.then()
- .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isAppWindowVisible(testApp2.component)
+ .isAppWindowVisible(testApp2)
}
}
@@ -269,62 +261,38 @@ open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTes
@Test
open fun app2LayerIsVisibleOnceApp1LayerIsInvisible() {
testSpec.assertLayers {
- this.isVisible(testApp1.component)
+ this.isVisible(testApp1)
.then()
- .isVisible(FlickerComponentName.LAUNCHER, isOptional = true)
+ .isVisible(ComponentMatcher.LAUNCHER, isOptional = true)
.then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isVisible(testApp2.component)
+ .isVisible(testApp2)
}
}
- /**
- * Checks that the navbar window is visible throughout the entire transition.
- */
- @Presubmit
- @Test
- open fun navBarWindowIsAlwaysVisible() {
- testSpec.navBarWindowIsVisible()
- }
-
- /**
- * Checks that the navbar layer is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- open fun navBarLayerAlwaysIsVisible() {
- testSpec.navBarLayerIsVisible()
- }
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- /**
- * Checks that the navbar is always in the right position and covers the expected region.
- *
- * NOTE: This doesn't check that the navbar is visible or not.
- */
- @FlakyTest
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 239148258)
@Test
- open fun navbarIsAlwaysInRightPosition() {
- testSpec.navBarLayerRotatesAndScales()
- }
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
- /**
- * Checks that the status bar window is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- open fun statusBarWindowIsAlwaysVisible() {
- testSpec.statusBarWindowIsVisible()
- }
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
- /**
- * Checks that the status bar layer is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 239148258)
@Test
- open fun statusBarLayerIsAlwaysVisible() {
- testSpec.statusBarLayerIsVisible()
- }
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
private var startDisplayBounds = Rect.EMPTY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
index 86ba7cbc2217..6f78ba8dc0f6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt
@@ -16,8 +16,8 @@
package com.android.server.wm.flicker.quickswitch
-import android.platform.test.annotations.RequiresDevice
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group1
@@ -25,6 +25,7 @@ import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume
import org.junit.Before
import org.junit.FixMethodOrder
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
@@ -45,11 +46,24 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-@FlakyTest(bugId = 228009808)
-open class QuickSwitchBetweenTwoAppsForwardTest_ShellTransit(testSpec: FlickerTestParameter)
- : QuickSwitchBetweenTwoAppsForwardTest(testSpec) {
+open class QuickSwitchBetweenTwoAppsForwardTest_ShellTransit(
+ testSpec: FlickerTestParameter
+) : QuickSwitchBetweenTwoAppsForwardTest(testSpec) {
@Before
override fun before() {
Assume.assumeTrue(isShellTransitionsEnabled)
}
+
+ @FlakyTest(bugId = 228009808)
+ @Test
+ override fun app2LayerIsVisibleOnceApp1LayerIsInvisible() =
+ super.app2LayerIsVisibleOnceApp1LayerIsInvisible()
+
+ @FlakyTest(bugId = 228009808)
+ @Test
+ override fun app2WindowBecomesAndStaysVisible() = super.app2WindowBecomesAndStaysVisible()
+
+ @FlakyTest(bugId = 228009808)
+ @Test
+ override fun endsWithApp2BeingOnTop() = super.endsWithApp2BeingOnTop()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index 4ea1f1c18b52..2c3fce9766e4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -16,27 +16,20 @@
package com.android.server.wm.flicker.quickswitch
-import android.app.Instrumentation
+import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.Surface
import android.view.WindowManagerPolicyConstants
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group1
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import com.android.server.wm.traces.common.Rect
import org.junit.FixMethodOrder
import org.junit.Test
@@ -60,44 +53,40 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
- private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
- private val taplInstrumentation = LauncherInstrumentation()
-
+class QuickSwitchFromLauncherTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
private val testApp = SimpleAppHelper(instrumentation)
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- setup {
- test {
- taplInstrumentation.setExpectedRotation(testSpec.startRotation)
- }
-
- eachRun {
- testApp.launchViaIntent(wmHelper)
- device.pressHome()
- wmHelper.StateSyncBuilder()
- .withHomeActivityVisible()
- .withWindowSurfaceDisappeared(testApp.component)
- .waitForAndVerify()
-
- startDisplayBounds = wmHelper.currentState.layerState
- .physicalDisplayBounds ?: error("Display not found")
- }
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ test {
+ tapl.setExpectedRotation(testSpec.startRotation)
}
- transitions {
- taplInstrumentation.workspace.quickSwitchToPreviousApp()
+
+ eachRun {
+ testApp.launchViaIntent(wmHelper)
+ device.pressHome()
wmHelper.StateSyncBuilder()
- .withFullScreenApp(testApp.component)
- .withNavBarStatusBarVisible()
+ .withHomeActivityVisible()
+ .withWindowSurfaceDisappeared(testApp)
.waitForAndVerify()
+
+ startDisplayBounds = wmHelper.currentState.layerState
+ .physicalDisplayBounds ?: error("Display not found")
}
+ }
+ transitions {
+ tapl.workspace.quickSwitchToPreviousApp()
+ wmHelper.StateSyncBuilder()
+ .withFullScreenApp(testApp)
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
+ .waitForAndVerify()
+ }
- teardown {
- eachRun {
- testApp.exit(wmHelper)
- }
+ teardown {
+ eachRun {
+ testApp.exit(wmHelper)
}
}
}
@@ -110,7 +99,7 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
@Test
fun endsWithAppWindowsCoveringFullScreen() {
testSpec.assertWmEnd {
- this.frameRegion(testApp.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp).coversExactly(startDisplayBounds)
}
}
@@ -122,7 +111,7 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
@Test
fun endsWithAppLayersCoveringFullScreen() {
testSpec.assertLayersEnd {
- this.visibleRegion(testApp.component).coversExactly(startDisplayBounds)
+ this.visibleRegion(testApp).coversExactly(startDisplayBounds)
}
}
@@ -134,7 +123,7 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
@Test
fun endsWithAppBeingOnTop() {
testSpec.assertWmEnd {
- this.isAppWindowOnTop(testApp.component)
+ this.isAppWindowOnTop(testApp)
}
}
@@ -150,37 +139,37 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
}
/**
- * Checks that the transition starts with the launcher windows filling/covering exactly the
- * entirety of the display.
+ * Checks that the transition starts with the [ComponentMatcher.LAUNCHER] windows
+ * filling/covering exactly display size
*/
@Presubmit
@Test
fun startsWithLauncherWindowsCoverFullScreen() {
testSpec.assertWmStart {
- this.frameRegion(FlickerComponentName.LAUNCHER).coversExactly(startDisplayBounds)
+ this.visibleRegion(ComponentMatcher.LAUNCHER).coversExactly(startDisplayBounds)
}
}
/**
- * Checks that the transition starts with the launcher layers filling/covering exactly the
- * entirety of the display.
+ * Checks that the transition starts with the [ComponentMatcher.LAUNCHER] layers
+ * filling/covering exactly the display size.
*/
@Presubmit
@Test
fun startsWithLauncherLayersCoverFullScreen() {
testSpec.assertLayersStart {
- this.visibleRegion(FlickerComponentName.LAUNCHER).coversExactly(startDisplayBounds)
+ this.visibleRegion(ComponentMatcher.LAUNCHER).coversExactly(startDisplayBounds)
}
}
/**
- * Checks that the transition starts with the launcher being the top window.
+ * Checks that the transition starts with the [ComponentMatcher.LAUNCHER] being the top window.
*/
@Presubmit
@Test
fun startsWithLauncherBeingOnTop() {
testSpec.assertWmStart {
- this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
+ this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
}
}
@@ -204,9 +193,9 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
@Test
fun appWindowBecomesAndStaysVisible() {
testSpec.assertWm {
- this.isAppWindowInvisible(testApp.component)
+ this.isAppWindowInvisible(testApp)
.then()
- .isAppWindowVisible(testApp.component)
+ .isAppWindowVisible(testApp)
}
}
@@ -218,117 +207,94 @@ class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
@Test
fun appLayerBecomesAndStaysVisible() {
testSpec.assertLayers {
- this.isInvisible(testApp.component)
+ this.isInvisible(testApp)
.then()
- .isVisible(testApp.component)
+ .isVisible(testApp)
}
}
/**
- * Checks that the launcher window starts off visible and becomes invisible at some point before
+ * Checks that the [ComponentMatcher.LAUNCHER] window starts off visible and becomes invisible
+ * at some point before
* the end of the transition and then stays invisible until the end of the transition.
*/
@Presubmit
@Test
fun launcherWindowBecomesAndStaysInvisible() {
testSpec.assertWm {
- this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
+ this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
.then()
- .isAppWindowNotOnTop(FlickerComponentName.LAUNCHER)
+ .isAppWindowNotOnTop(ComponentMatcher.LAUNCHER)
}
}
/**
- * Checks that the launcher layer starts off visible and becomes invisible at some point before
+ * Checks that the [ComponentMatcher.LAUNCHER] layer starts off visible and becomes invisible
+ * at some point before
* the end of the transition and then stays invisible until the end of the transition.
*/
@Presubmit
@Test
fun launcherLayerBecomesAndStaysInvisible() {
testSpec.assertLayers {
- this.isVisible(FlickerComponentName.LAUNCHER)
+ this.isVisible(ComponentMatcher.LAUNCHER)
.then()
- .isInvisible(FlickerComponentName.LAUNCHER)
+ .isInvisible(ComponentMatcher.LAUNCHER)
}
}
/**
- * Checks that the launcher window is visible at least until the app window is visible. Ensures
+ * Checks that the [ComponentMatcher.LAUNCHER] window is visible at least until the app window
+ * is visible. Ensures
* that at any point, either the launcher or [testApp] windows are at least partially visible.
*/
@Presubmit
@Test
fun appWindowIsVisibleOnceLauncherWindowIsInvisible() {
testSpec.assertWm {
- this.isAppWindowOnTop(FlickerComponentName.LAUNCHER)
+ this.isAppWindowOnTop(ComponentMatcher.LAUNCHER)
.then()
- .isAppWindowVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isAppWindowVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isAppWindowVisible(testApp.component)
+ .isAppWindowVisible(testApp)
}
}
/**
- * Checks that the launcher layer is visible at least until the app layer is visible. Ensures
- * that at any point, either the launcher or [testApp] layers are at least partially visible.
+ * Checks that the [ComponentMatcher.LAUNCHER] layer is visible at least until the app layer
+ * is visible. Ensures that at any point, either the launcher or [testApp] layers are at least
+ * partially visible.
*/
@Presubmit
@Test
fun appLayerIsVisibleOnceLauncherLayerIsInvisible() {
testSpec.assertLayers {
- this.isVisible(FlickerComponentName.LAUNCHER)
+ this.isVisible(ComponentMatcher.LAUNCHER)
.then()
- .isVisible(FlickerComponentName.SNAPSHOT, isOptional = true)
+ .isVisible(ComponentMatcher.SNAPSHOT, isOptional = true)
.then()
- .isVisible(testApp.component)
+ .isVisible(testApp)
}
}
- /**
- * Checks that the navbar window is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @Postsubmit
@Test
- fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible()
+ override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
- /**
- * Checks that the navbar layer is visible throughout the entire transition.
- */
- @Presubmit
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 239148258)
@Test
- fun navBarLayerAlwaysIsVisible() = testSpec.navBarLayerIsVisible()
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
- /**
- * Checks that the navbar is always in the right position and covers the expected region.
- *
- * NOTE: This doesn't check that the navbar is visible or not.
- */
- @Presubmit
- @Test
- fun navbarIsAlwaysInRightPosition() = testSpec.navBarLayerRotatesAndScales()
-
- /**
- * Checks that the status bar window is visible throughout the entire transition.
- */
- @Presubmit
- @Test
- fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsVisible()
-
- /**
- * Checks that the status bar layer is visible throughout the entire transition.
- */
- @Presubmit
- @Test
- fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsVisible()
-
- /**
- * Checks that the screen is always fully covered by visible layers throughout the transition.
- */
- @Presubmit
+ @FlakyTest(bugId = 239148258)
@Test
- fun screenIsAlwaysFilled() = testSpec.entireScreenCovered()
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
companion object {
+ /** {@inheritDoc} */
private var startDisplayBounds = Rect.EMPTY
@Parameterized.Parameters(name = "{0}")
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index ae32520dcdc0..5e80fabcd8a4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -16,8 +16,8 @@
package com.android.server.wm.flicker.rotation
-import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.FlakyTest
+import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
@@ -25,10 +25,7 @@ import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -102,22 +99,22 @@ class ChangeAppRotationTest(
}
/**
- * Checks that the [FlickerComponentName.ROTATION] layer appears during the transition,
+ * Checks that the [ComponentMatcher.ROTATION] layer appears during the transition,
* doesn't flicker, and disappears before the transition is complete
*/
fun rotationLayerAppearsAndVanishesAssertion() {
testSpec.assertLayers {
- this.isVisible(testApp.component)
+ this.isVisible(testApp)
.then()
- .isVisible(FlickerComponentName.ROTATION)
+ .isVisible(ComponentMatcher.ROTATION)
.then()
- .isVisible(testApp.component)
- .isInvisible(FlickerComponentName.ROTATION)
+ .isVisible(testApp)
+ .isInvisible(ComponentMatcher.ROTATION)
}
}
/**
- * Checks that the [FlickerComponentName.ROTATION] layer appears during the transition,
+ * Checks that the [ComponentMatcher.ROTATION] layer appears during the transition,
* doesn't flicker, and disappears before the transition is complete
*/
@Presubmit
@@ -126,38 +123,11 @@ class ChangeAppRotationTest(
rotationLayerAppearsAndVanishesAssertion()
}
- /**
- * Checks that the status bar window is visible and above the app windows in all WM
- * trace entries
- */
- @Presubmit
- @Test
- fun statusBarWindowIsVisible() {
- testSpec.statusBarWindowIsVisible()
- }
-
- /**
- * Checks that the status bar layer is visible at the start and end of the transition
- */
- @Presubmit
- @Test
- fun statusBarLayerIsVisible() {
- testSpec.statusBarLayerIsVisible()
- }
-
- /**
- * Checks the position of the status bar at the start and end of the transition
- */
- @FlakyTest(bugId = 206753786)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
/** {@inheritDoc} */
- @FlakyTest
+ @FlakyTest(bugId = 206753786)
@Test
- override fun navBarLayerRotatesAndScales() {
- super.navBarLayerRotatesAndScales()
- }
+ override fun navBarLayerPositionAtStartAndEnd() =
+ super.navBarLayerPositionAtStartAndEnd()
/** {@inheritDoc} */
@FlakyTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index 586be06d1a29..36a152117dcc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -16,30 +16,23 @@
package com.android.server.wm.flicker.rotation
-import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.Test
/**
* Base class for app rotation tests
*/
-abstract class RotationTransition(protected val testSpec: FlickerTestParameter) {
+abstract class RotationTransition(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
protected abstract val testApp: StandardAppHelper
- protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-
- protected open val transition: FlickerBuilder.() -> Unit = {
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
setup {
eachRun {
this.setRotation(testSpec.startRotation)
@@ -55,80 +48,22 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter)
}
}
- /**
- * Entry point for the test runner. It will use this method to initialize and cache
- * flicker executions
- */
- @FlickerBuilderProvider
- fun buildFlicker(): FlickerBuilder {
- return FlickerBuilder(instrumentation).apply {
- transition()
- }
- }
-
- /**
- * Checks that the navigation bar window is visible and above the app windows in all WM
- * trace entries
- */
+ /** {@inheritDoc} */
@Presubmit
@Test
- open fun navBarWindowIsVisible() {
- testSpec.navBarWindowIsVisible()
- }
-
- /**
- * Checks that the navigation bar layer is visible at the start and end of the transition
- */
- @Presubmit
- @Test
- open fun navBarLayerIsVisible() {
- testSpec.navBarLayerIsVisible()
- }
-
- /**
- * Checks the position of the navigation bar at the start and end of the transition
- */
- @Presubmit
- @Test
- open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
- /**
- * Checks that all layers that are visible on the trace, are visible for at least 2
- * consecutive entries.
- */
- @Presubmit
- @Test
- open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
testSpec.assertLayers {
this.visibleLayersShownMoreThanOneConsecutiveEntry(
- ignoreLayers = listOf(FlickerComponentName.SPLASH_SCREEN,
- FlickerComponentName.SNAPSHOT,
- FlickerComponentName("", "SecondaryHomeHandle")
+ ignoreLayers = listOf(
+ ComponentMatcher.SPLASH_SCREEN,
+ ComponentMatcher.SNAPSHOT,
+ ComponentMatcher("", "SecondaryHomeHandle")
)
)
}
}
/**
- * Checks that all windows that are visible on the trace, are visible for at least 2
- * consecutive entries.
- */
- @Presubmit
- @Test
- open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- testSpec.assertWm {
- this.visibleWindowsShownMoreThanOneConsecutiveEntry()
- }
- }
-
- /**
- * Checks that all parts of the screen are covered during the transition
- */
- @Presubmit
- @Test
- open fun entireScreenCovered() = testSpec.entireScreenCovered()
-
- /**
* Checks that [testApp] layer covers the entire screen at the start of the transition
*/
@Presubmit
@@ -136,7 +71,7 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter)
open fun appLayerRotates_StartingPos() {
testSpec.assertLayersStart {
this.entry.displays.map { display ->
- this.visibleRegion(testApp.component).coversExactly(display.layerStackSpace)
+ this.visibleRegion(testApp).coversExactly(display.layerStackSpace)
}
}
}
@@ -149,7 +84,7 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter)
open fun appLayerRotates_EndingPos() {
testSpec.assertLayersEnd {
this.entry.displays.map { display ->
- this.visibleRegion(testApp.component).coversExactly(display.layerStackSpace)
+ this.visibleRegion(testApp).coversExactly(display.layerStackSpace)
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index a14e4bcf4cea..b2a2381c5578 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -16,10 +16,10 @@
package com.android.server.wm.flicker.rotation
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresDevice
import android.view.WindowManager
-import android.platform.test.annotations.FlakyTest
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
@@ -27,8 +27,9 @@ import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.ComponentMatcher
import org.junit.FixMethodOrder
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -81,14 +82,18 @@ open class SeamlessAppRotationTest(
) : RotationTransition(testSpec) {
override val testApp = SeamlessRotationAppHelper(instrumentation)
+ /** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
super.transition(this)
setup {
test {
- testApp.launchViaIntent(wmHelper,
- stringExtras = mapOf(ActivityOptions.EXTRA_STARVE_UI_THREAD
- to testSpec.starveUiThread.toString())
+ testApp.launchViaIntent(
+ wmHelper,
+ stringExtras = mapOf(
+ ActivityOptions.EXTRA_STARVE_UI_THREAD
+ to testSpec.starveUiThread.toString()
+ )
)
}
}
@@ -122,8 +127,10 @@ open class SeamlessAppRotationTest(
val appWindow = it.windowState(testApp.`package`)
val rotationAnimation = appWindow.windowState?.attributes?.rotationAnimation ?: 0
appWindow.verify("isRotationSeamless")
- .that(rotationAnimation
- .and(WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS))
+ .that(
+ rotationAnimation
+ .and(WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS)
+ )
.isGreaterThan(0)
}
}
@@ -136,7 +143,7 @@ open class SeamlessAppRotationTest(
@Test
fun appLayerAlwaysVisible() {
testSpec.assertLayers {
- isVisible(testApp.component)
+ isVisible(testApp)
}
}
@@ -149,33 +156,46 @@ open class SeamlessAppRotationTest(
testSpec.assertLayers {
this.invoke("entireScreenCovered") { entry ->
entry.entry.displays.map { display ->
- entry.visibleRegion(testApp.component).coversExactly(display.layerStackSpace)
+ entry.visibleRegion(testApp)
+ .coversExactly(display.layerStackSpace)
}
}
}
}
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. App is full screen")
+ override fun statusBarLayerPositionAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. App is full screen")
+ override fun statusBarLayerIsVisibleAtStartAndEnd() { }
+
+ /** {@inheritDoc} */
+ @Ignore("Not applicable to this CUJ. App is full screen")
+ override fun statusBarWindowIsAlwaysVisible() { }
+
/**
- * Checks that the [FlickerComponentName.STATUS_BAR] window is invisible during the whole
+ * Checks that the [ComponentMatcher.STATUS_BAR] window is invisible during the whole
* transition
*/
@Presubmit
@Test
fun statusBarWindowIsAlwaysInvisible() {
testSpec.assertWm {
- this.isAboveAppWindowInvisible(FlickerComponentName.STATUS_BAR)
+ this.isAboveAppWindowInvisible(ComponentMatcher.STATUS_BAR)
}
}
/**
- * Checks that the [FlickerComponentName.STATUS_BAR] layer is invisible during the whole
+ * Checks that the [ComponentMatcher.STATUS_BAR] layer is invisible during the whole
* transition
*/
@Presubmit
@Test
fun statusBarLayerIsAlwaysInvisible() {
testSpec.assertLayers {
- this.isInvisible(FlickerComponentName.STATUS_BAR)
+ this.isInvisible(ComponentMatcher.STATUS_BAR)
}
}
@@ -193,7 +213,7 @@ open class SeamlessAppRotationTest(
/** {@inheritDoc} */
@FlakyTest
@Test
- override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
companion object {
private val FlickerTestParameter.starveUiThread
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index cce0dde9e6b9..1709e1501537 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -57,6 +57,7 @@ java_test_host {
data: [
":apex.apexd_test",
":com.android.apex.apkrollback.test_v1",
+ ":com.android.apex.apkrollback.test_v2",
":StagedInstallTestApexV2",
":StagedInstallTestApexV2_WrongSha",
":TestAppAv1",
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 7b17778730eb..c4cb33da4a6d 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -31,6 +31,7 @@ import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.Log;
import com.android.tests.rollback.host.AbandonSessionsRule;
import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.PackageInfo;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.CommandResult;
@@ -203,6 +204,28 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
runPhase("testDuplicateApkInApexShouldFail_Verify");
}
+ /**
+ * Tests the cache of apk-in-apex is pruned and rebuilt correctly.
+ */
+ @Test
+ @LargeTest
+ public void testApkInApexPruneCache() throws Exception {
+ final String apkInApexPackageName = "com.android.cts.install.lib.testapp.A";
+
+ pushTestApex(APK_IN_APEX_TESTAPEX_NAME + "_v1.apex");
+ getDevice().reboot();
+ PackageInfo pi = getDevice().getAppPackageInfo(apkInApexPackageName);
+ assertThat(Integer.parseInt(pi.getVersionCode())).isEqualTo(1);
+ assertThat(pi.getCodePath()).startsWith("/apex/" + APK_IN_APEX_TESTAPEX_NAME);
+
+ installPackage(APK_IN_APEX_TESTAPEX_NAME + "_v2.apex", "--staged");
+ getDevice().reboot();
+ pi = getDevice().getAppPackageInfo(apkInApexPackageName);
+ // The version code of apk-in-apex will be stale if the cache is not rebuilt
+ assertThat(Integer.parseInt(pi.getVersionCode())).isEqualTo(2);
+ assertThat(pi.getCodePath()).startsWith("/apex/" + APK_IN_APEX_TESTAPEX_NAME);
+ }
+
@Test
public void testSystemServerRestartDoesNotAffectStagedSessions() throws Exception {
runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Commit");
diff --git a/tools/lint/Android.bp b/tools/lint/Android.bp
index 17547ef8b561..3458359273b8 100644
--- a/tools/lint/Android.bp
+++ b/tools/lint/Android.bp
@@ -29,6 +29,7 @@ java_library_host {
"auto_service_annotations",
"lint_api",
],
+ kotlincflags: ["-Xjvm-default=all"],
}
java_test_host {