summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp11
-rw-r--r--Android.bp24
-rw-r--r--apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java4
-rw-r--r--apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java19
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java20
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java12
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java53
-rw-r--r--cmds/interrupter/Android.bp20
-rw-r--r--cmds/interrupter/interrupter.c53
-rw-r--r--cmds/interrupter/interrupter.h79
-rw-r--r--core/api/current.txt208
-rw-r--r--core/api/system-current.txt189
-rw-r--r--core/api/test-current.txt15
-rw-r--r--core/api/test-lint-baseline.txt2
-rw-r--r--core/java/Android.bp42
-rw-r--r--core/java/android/accounts/AccountManager.java20
-rw-r--r--core/java/android/animation/AnimatorSet.java8
-rw-r--r--core/java/android/animation/ValueAnimator.java10
-rw-r--r--core/java/android/app/Activity.java29
-rw-r--r--core/java/android/app/ActivityManager.java87
-rw-r--r--core/java/android/app/ActivityManagerInternal.java14
-rw-r--r--core/java/android/app/ForegroundServiceTypePolicy.java45
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl4
-rw-r--r--core/java/android/app/INotificationManager.aidl2
-rw-r--r--core/java/android/app/Notification.java69
-rw-r--r--core/java/android/app/NotificationManager.java29
-rw-r--r--core/java/android/app/ResourcesManager.java10
-rw-r--r--core/java/android/app/SystemServiceRegistry.java42
-rw-r--r--core/java/android/app/TaskInfo.java16
-rw-r--r--core/java/android/app/jank/FrameOverrunHistogram.java2
-rw-r--r--core/java/android/app/jank/JankDataProcessor.java74
-rw-r--r--core/java/android/app/jank/JankTracker.java7
-rw-r--r--core/java/android/app/jank/StateTracker.java6
-rw-r--r--core/java/android/app/notification.aconfig7
-rw-r--r--core/java/android/app/ondeviceintelligence/InferenceInfo.java47
-rw-r--r--core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java7
-rw-r--r--core/java/android/app/wearable/WearableSensingManager.java40
-rw-r--r--core/java/android/appwidget/flags.aconfig5
-rw-r--r--core/java/android/content/Context.java30
-rw-r--r--core/java/android/content/ContextWrapper.java1
-rw-r--r--core/java/android/content/Intent.java4
-rw-r--r--core/java/android/content/om/OverlayManager.java5
-rw-r--r--core/java/android/content/om/OverlayManagerTransaction.java15
-rw-r--r--core/java/android/content/pm/ActivityInfo.java10
-rw-r--r--core/java/android/content/pm/IPackageInstaller.aidl6
-rw-r--r--core/java/android/content/pm/PackageInstaller.java151
-rw-r--r--core/java/android/content/pm/PackageManager.java29
-rw-r--r--core/java/android/content/pm/ServiceInfo.java10
-rw-r--r--core/java/android/content/pm/flags.aconfig10
-rw-r--r--core/java/android/content/pm/parsing/ApkLite.java21
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java17
-rw-r--r--core/java/android/content/pm/parsing/PackageLite.java17
-rw-r--r--core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl32
-rw-r--r--core/java/android/content/pm/verify/pkg/VerificationSession.java311
-rw-r--r--core/java/android/content/pm/verify/pkg/VerificationStatus.java166
-rw-r--r--core/java/android/content/pm/verify/pkg/VerifierService.java113
-rw-r--r--core/java/android/content/res/AssetManager.java5
-rw-r--r--core/java/android/content/res/flags.aconfig9
-rw-r--r--core/java/android/content/res/loader/ResourcesProvider.java2
-rw-r--r--core/java/android/hardware/contexthub/HubEndpointInfo.java2
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl2
-rw-r--r--core/java/android/hardware/input/InputManager.java17
-rw-r--r--core/java/android/hardware/input/InputSettings.java11
-rw-r--r--core/java/android/hardware/input/KeyGlyphMap.java8
-rw-r--r--core/java/android/hardware/input/input_framework.aconfig15
-rw-r--r--core/java/android/inputmethodservice/AbstractInputMethodService.java17
-rw-r--r--core/java/android/inputmethodservice/IInputMethodSessionWrapper.java43
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java60
-rw-r--r--core/java/android/net/vcn/flags.aconfig12
-rw-r--r--core/java/android/os/BinderProxy.java34
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java5
-rw-r--r--core/java/android/os/IBinder.java39
-rw-r--r--core/java/android/os/IHintManager.aidl10
-rw-r--r--core/java/android/os/PerformanceHintManager.java5
-rw-r--r--core/java/android/os/PowerManager.java10
-rw-r--r--core/java/android/os/RemoteCallbackList.java48
-rw-r--r--core/java/android/os/SessionCreationConfig.aidl39
-rw-r--r--core/java/android/os/VibrationEffect.java190
-rw-r--r--core/java/android/os/flags.aconfig18
-rw-r--r--core/java/android/os/vibrator/BasicPwleSegment.java222
-rw-r--r--core/java/android/os/vibrator/PwlePoint.java8
-rw-r--r--core/java/android/os/vibrator/PwleSegment.java8
-rw-r--r--core/java/android/os/vibrator/VibrationEffectSegment.java8
-rw-r--r--core/java/android/permission/flags.aconfig18
-rw-r--r--core/java/android/provider/ContactsContract.java2
-rw-r--r--core/java/android/provider/Settings.java31
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionManager.java4
-rw-r--r--core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl4
-rw-r--r--core/java/android/security/authenticationpolicy/AuthenticationPolicyManager.java237
-rw-r--r--core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.aidl (renamed from core/java/android/content/pm/verify/pkg/VerificationStatus.aidl)9
-rw-r--r--core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java82
-rw-r--r--core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.aidl (renamed from core/java/android/content/pm/verify/pkg/VerificationSession.aidl)9
-rw-r--r--core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java82
-rw-r--r--core/java/android/security/authenticationpolicy/IAuthenticationPolicyService.aidl (renamed from core/java/android/content/pm/verify/pkg/IVerifierService.aidl)19
-rw-r--r--core/java/android/security/authenticationpolicy/OWNERS1
-rw-r--r--core/java/android/security/forensic/IForensicService.aidl35
-rw-r--r--core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl (renamed from core/java/android/security/forensic/IForensicEventTransport.aidl)14
-rw-r--r--core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl35
-rw-r--r--core/java/android/security/intrusiondetection/IIntrusionDetectionServiceCommandCallback.aidl (renamed from core/java/android/security/forensic/IForensicServiceCommandCallback.aidl)4
-rw-r--r--core/java/android/security/intrusiondetection/IIntrusionDetectionServiceStateCallback.aidl (renamed from core/java/android/security/forensic/IForensicServiceStateCallback.aidl)4
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionEvent.aidl (renamed from core/java/android/security/forensic/ForensicEvent.aidl)4
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java (renamed from core/java/android/security/forensic/ForensicEvent.java)36
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionManager.java (renamed from core/java/android/security/forensic/ForensicManager.java)100
-rw-r--r--core/java/android/security/intrusiondetection/OWNERS (renamed from core/java/android/security/forensic/OWNERS)0
-rw-r--r--core/java/android/service/carrier/CarrierMessagingService.java450
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java2
-rw-r--r--core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java22
-rw-r--r--core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java147
-rw-r--r--core/java/android/service/settings/preferences/SettingsPreferenceValue.java24
-rw-r--r--core/java/android/service/wearable/WearableSensingService.java17
-rw-r--r--core/java/android/text/style/TtsSpan.java10
-rw-r--r--core/java/android/view/AttachedSurfaceControl.java3
-rw-r--r--core/java/android/view/IWindowSession.aidl10
-rw-r--r--core/java/android/view/SurfaceControl.java107
-rw-r--r--core/java/android/view/SurfaceControlActivePicture.java58
-rw-r--r--core/java/android/view/SurfaceControlActivePictureListener.java69
-rw-r--r--core/java/android/view/ViewRootImpl.java42
-rw-r--r--core/java/android/view/WindowlessWindowManager.java5
-rw-r--r--core/java/android/view/accessibility/flags/accessibility_flags.aconfig10
-rw-r--r--core/java/android/view/inputmethod/InputMethodSession.java18
-rw-r--r--core/java/android/view/inputmethod/flags.aconfig8
-rw-r--r--core/java/android/widget/Button.java46
-rw-r--r--core/java/android/widget/RemoteViews.java82
-rw-r--r--core/java/android/widget/flags/flags.aconfig10
-rw-r--r--core/java/android/window/BackProgressAnimator.java3
-rw-r--r--core/java/android/window/IBackAnimationHandoffHandler.aidl40
-rw-r--r--core/java/android/window/IOnBackInvokedCallback.aidl6
-rw-r--r--core/java/android/window/ImeOnBackInvokedDispatcher.java5
-rw-r--r--core/java/android/window/WindowOnBackInvokedDispatcher.java5
-rw-r--r--core/java/android/window/flags/window_surfaces.aconfig8
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig7
-rw-r--r--core/java/com/android/internal/content/om/OverlayConfig.java3
-rw-r--r--core/java/com/android/internal/content/om/OverlayManagerImpl.java20
-rw-r--r--core/java/com/android/internal/protolog/LegacyProtoLogImpl.java8
-rw-r--r--core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java93
-rw-r--r--core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java16
-rw-r--r--core/java/com/android/internal/protolog/ProtoLog.java80
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogCacheUpdater.java (renamed from media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl)16
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java35
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogDataSource.java103
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogImpl.java54
-rw-r--r--core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java87
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Operation.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Operations.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/PaintContext.java16
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Platform.java17
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java183
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java48
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java75
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java32
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java15
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java12
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java42
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java7
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java17
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java12
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java51
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Header.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java9
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java22
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java18
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java21
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java52
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java106
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java7
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java44
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java7
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java7
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java12
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java36
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java15
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java7
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java32
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java71
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java32
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java22
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java27
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java120
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java21
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java227
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java105
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java9
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java10
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java61
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java16
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java20
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java8
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/paint/TextPaint.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java73
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java3
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java12
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java20
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java16
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicSpline.java203
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/SpringStopEngine.java188
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java1
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java116
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java18
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java13
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java88
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java9
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java17
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android_os_PerformanceHintManager.cpp9
-rw-r--r--core/jni/android_view_SurfaceControl.cpp34
-rw-r--r--core/jni/android_view_SurfaceControlActivePictureListener.cpp191
-rw-r--r--core/proto/android/providers/settings/system.proto1
-rw-r--r--core/res/Android.bp2
-rw-r--r--core/res/AndroidManifest.xml88
-rw-r--r--core/res/res/drawable-watch-v36/btn_background_material_filled.xml2
-rw-r--r--core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml2
-rw-r--r--core/res/res/layout/notification_2025_template_heads_up_base.xml66
-rw-r--r--core/res/res/values-af/strings.xml78
-rw-r--r--core/res/res/values-am/strings.xml78
-rw-r--r--core/res/res/values-ar/strings.xml6
-rw-r--r--core/res/res/values-as/strings.xml6
-rw-r--r--core/res/res/values-az/strings.xml78
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml6
-rw-r--r--core/res/res/values-be/strings.xml6
-rw-r--r--core/res/res/values-bg/strings.xml78
-rw-r--r--core/res/res/values-bn/strings.xml6
-rw-r--r--core/res/res/values-bs/strings.xml6
-rw-r--r--core/res/res/values-ca/strings.xml78
-rw-r--r--core/res/res/values-cs/strings.xml78
-rw-r--r--core/res/res/values-da/strings.xml78
-rw-r--r--core/res/res/values-de/strings.xml78
-rw-r--r--core/res/res/values-el/strings.xml78
-rw-r--r--core/res/res/values-en-rAU/strings.xml6
-rw-r--r--core/res/res/values-en-rGB/strings.xml6
-rw-r--r--core/res/res/values-en-rIN/strings.xml6
-rw-r--r--core/res/res/values-es-rUS/strings.xml6
-rw-r--r--core/res/res/values-es/strings.xml80
-rw-r--r--core/res/res/values-et/strings.xml78
-rw-r--r--core/res/res/values-eu/strings.xml78
-rw-r--r--core/res/res/values-fa/strings.xml80
-rw-r--r--core/res/res/values-fi/strings.xml78
-rw-r--r--core/res/res/values-fr-rCA/strings.xml6
-rw-r--r--core/res/res/values-fr/strings.xml78
-rw-r--r--core/res/res/values-gl/strings.xml78
-rw-r--r--core/res/res/values-gu/strings.xml78
-rw-r--r--core/res/res/values-hi/strings.xml8
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml78
-rw-r--r--core/res/res/values-hy/strings.xml78
-rw-r--r--core/res/res/values-in/strings.xml82
-rw-r--r--core/res/res/values-is/strings.xml6
-rw-r--r--core/res/res/values-it/strings.xml78
-rw-r--r--core/res/res/values-iw/strings.xml8
-rw-r--r--core/res/res/values-ja/strings.xml6
-rw-r--r--core/res/res/values-ka/strings.xml6
-rw-r--r--core/res/res/values-kk/strings.xml80
-rw-r--r--core/res/res/values-km/strings.xml6
-rw-r--r--core/res/res/values-kn/strings.xml18
-rw-r--r--core/res/res/values-ko/strings.xml8
-rw-r--r--core/res/res/values-ky/strings.xml80
-rw-r--r--core/res/res/values-lo/strings.xml6
-rw-r--r--core/res/res/values-lt/strings.xml6
-rw-r--r--core/res/res/values-lv/strings.xml78
-rw-r--r--core/res/res/values-mk/strings.xml82
-rw-r--r--core/res/res/values-ml/strings.xml6
-rw-r--r--core/res/res/values-mn/strings.xml80
-rw-r--r--core/res/res/values-mr/strings.xml6
-rw-r--r--core/res/res/values-ms/strings.xml6
-rw-r--r--core/res/res/values-my/strings.xml8
-rw-r--r--core/res/res/values-nb/strings.xml78
-rw-r--r--core/res/res/values-ne/strings.xml14
-rw-r--r--core/res/res/values-nl/strings.xml6
-rw-r--r--core/res/res/values-or/strings.xml80
-rw-r--r--core/res/res/values-pa/strings.xml6
-rw-r--r--core/res/res/values-pl/strings.xml6
-rw-r--r--core/res/res/values-pt-rBR/strings.xml8
-rw-r--r--core/res/res/values-pt-rPT/strings.xml6
-rw-r--r--core/res/res/values-pt/strings.xml8
-rw-r--r--core/res/res/values-ro/strings.xml14
-rw-r--r--core/res/res/values-ru/strings.xml14
-rw-r--r--core/res/res/values-si/strings.xml80
-rw-r--r--core/res/res/values-sk/strings.xml78
-rw-r--r--core/res/res/values-sl/strings.xml6
-rw-r--r--core/res/res/values-sq/strings.xml80
-rw-r--r--core/res/res/values-sr/strings.xml6
-rw-r--r--core/res/res/values-sv/strings.xml6
-rw-r--r--core/res/res/values-sw/strings.xml78
-rw-r--r--core/res/res/values-ta/strings.xml78
-rw-r--r--core/res/res/values-te/strings.xml86
-rw-r--r--core/res/res/values-th/strings.xml6
-rw-r--r--core/res/res/values-tl/strings.xml6
-rw-r--r--core/res/res/values-tr/strings.xml78
-rw-r--r--core/res/res/values-uk/strings.xml78
-rw-r--r--core/res/res/values-ur/strings.xml8
-rw-r--r--core/res/res/values-uz/strings.xml6
-rw-r--r--core/res/res/values-vi/strings.xml78
-rw-r--r--core/res/res/values-watch-v36/config.xml3
-rw-r--r--core/res/res/values-watch-v36/styles_material.xml4
-rw-r--r--core/res/res/values-zh-rCN/strings.xml8
-rw-r--r--core/res/res/values-zh-rHK/strings.xml78
-rw-r--r--core/res/res/values-zh-rTW/strings.xml78
-rw-r--r--core/res/res/values-zu/strings.xml78
-rw-r--r--core/res/res/values/config.xml14
-rw-r--r--core/res/res/values/config_display.xml2
-rw-r--r--core/res/res/values/config_telephony.xml7
-rw-r--r--core/res/res/values/dimens.xml8
-rw-r--r--core/res/res/values/styles_device_defaults.xml1
-rw-r--r--core/res/res/values/symbols.xml99
-rw-r--r--core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java3
-rw-r--r--core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java194
-rw-r--r--core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java72
-rw-r--r--core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java96
-rw-r--r--core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java3
-rw-r--r--core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java15
-rw-r--r--core/tests/systemproperties/src/android/os/SystemPropertiesTest.java7
-rw-r--r--core/tests/vibrator/src/android/os/VibrationEffectTest.java265
-rw-r--r--data/etc/privapp-permissions-platform.xml11
-rw-r--r--libs/WindowManager/Shell/Android.bp45
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml8
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/styles.xml1
-rw-r--r--libs/WindowManager/Shell/shared/Android.bp78
-rw-r--r--libs/WindowManager/Shell/shared/AndroidManifest.xml (renamed from packages/BackupRestoreConfirmation/res/values/styles.xml)15
-rw-r--r--libs/WindowManager/Shell/shared/res/values/config.xml18
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java99
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java148
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java289
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java84
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt150
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt174
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/anim/TwoFiftyFiftyTargetAnimator.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformComponents.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java46
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java41
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java974
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt185
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java64
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt4
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS1
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt21
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenUnlimitedApps.kt47
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt3
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/Android.bp38
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidManifest.xml85
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidTestTemplate.xml97
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/trace_config/trace_config.textproto71
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionFromSplitScreenTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionInSplitScreenTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionWithExtraIntentTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionFromSplitScreenTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionInSplitScreenTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjection.kt76
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionFromSplitScreen.kt83
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionInSplitScreen.kt86
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionWithExtraIntent.kt86
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjection.kt76
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionFromSplitScreen.kt83
-rw-r--r--libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionInSplitScreen.kt86
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MediaProjectionUtils.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java53
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java86
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt53
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt17
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt155
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt22
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt157
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/SplitDragPolicyTest.java11
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java11
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java172
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java28
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java18
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt180
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt314
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt327
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt8
-rw-r--r--libs/hwui/DeviceInfo.h1
-rw-r--r--libs/hwui/RenderNode.cpp2
-rw-r--r--libs/hwui/RenderProperties.h3
-rw-r--r--libs/hwui/jni/Paint.cpp11
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp5
-rw-r--r--libs/hwui/tests/unit/RenderPropertiesTests.cpp8
-rw-r--r--libs/input/SpriteIcon.cpp2
-rw-r--r--media/java/android/media/AudioDevicePort.java5
-rw-r--r--media/java/android/media/MediaCodecInfo.java140
-rw-r--r--media/java/android/media/MediaFormat.java11
-rw-r--r--media/java/android/media/flags/projection.aconfig8
-rw-r--r--media/java/android/media/quality/AmbientBacklightEvent.java1
-rw-r--r--media/java/android/media/quality/AmbientBacklightMetadata.java15
-rw-r--r--media/java/android/media/quality/AmbientBacklightSettings.java15
-rw-r--r--media/java/android/media/quality/IMediaQualityManager.aidl3
-rw-r--r--media/java/android/media/quality/MediaQualityContract.java26
-rw-r--r--media/java/android/media/quality/MediaQualityManager.java56
-rw-r--r--media/java/android/media/quality/PictureProfileHandle.java38
-rw-r--r--media/java/android/media/quality/SoundProfile.java12
-rw-r--r--media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl36
-rw-r--r--media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl25
-rw-r--r--media/java/android/media/tv/extension/scan/ILcnConflict.aidl35
-rw-r--r--media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl35
-rw-r--r--media/java/android/media/tv/extension/scan/IOperatorDetection.aidl35
-rw-r--r--media/java/android/media/tv/extension/scan/IRegionChannelList.aidl30
-rw-r--r--media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/scan/IScanInterface.aidl30
-rw-r--r--media/java/android/media/tv/extension/scan/IScanListener.aidl33
-rw-r--r--media/java/android/media/tv/extension/scan/IScanSatSearch.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/IScanSession.aidl75
-rw-r--r--media/java/android/media/tv/extension/scan/ITargetRegion.aidl36
-rw-r--r--media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/ITkgsInfo.aidl28
-rw-r--r--media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl26
-rw-r--r--media/java/android/media/tv/tuner/frontend/FrontendStatus.java16
-rw-r--r--media/java/android/media/tv/tuner/frontend/StandardExtension.java (renamed from media/java/android/media/tv/tuner/frontend/StandardExt.java)24
-rw-r--r--media/jni/android_media_tv_Tuner.cpp6
-rw-r--r--native/android/dynamic_instrumentation_manager.cpp14
-rw-r--r--native/android/include_platform/android/dynamic_instrumentation_manager.h15
-rw-r--r--native/android/libandroid.map.txt13
-rw-r--r--native/android/performance_hint.cpp260
-rw-r--r--native/android/tests/performance_hint/PerformanceHintNativeTest.cpp87
-rw-r--r--nfc/api/current.txt12
-rw-r--r--nfc/api/system-current.txt2
-rw-r--r--nfc/java/android/nfc/INfcAdapter.aidl1
-rw-r--r--nfc/java/android/nfc/INfcEventListener.aidl5
-rw-r--r--nfc/java/android/nfc/INfcOemExtensionCallback.aidl1
-rw-r--r--nfc/java/android/nfc/NfcAdapter.java51
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java15
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java145
-rw-r--r--nfc/java/android/nfc/flags.aconfig8
-rw-r--r--packages/BackupRestoreConfirmation/Android.bp1
-rw-r--r--packages/BackupRestoreConfirmation/AndroidManifest.xml1
-rw-r--r--packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml9
-rw-r--r--packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml11
-rw-r--r--packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java34
-rw-r--r--packages/CarrierDefaultApp/res/values-ar/strings.xml2
-rw-r--r--packages/CarrierDefaultApp/res/values-ur/strings.xml2
-rw-r--r--packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java174
-rw-r--r--packages/PackageInstaller/res/values-cs/strings.xml2
-rw-r--r--packages/PrintSpooler/AndroidManifest.xml1
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java19
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-af/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-am/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-as/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-az/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-be/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-da/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-de/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-el/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-es/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-et/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-in/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-is/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-it/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-km/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-my/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-or/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-si/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-te/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-th/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml25
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml27
-rw-r--r--packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml27
-rw-r--r--packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt7
-rw-r--r--packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt7
-rw-r--r--packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml2
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-te/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml22
-rw-r--r--packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml22
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/ModifierExt.kt33
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/BaseLayout.kt17
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt21
-rw-r--r--packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml79
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml16
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml18
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml14
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml12
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml12
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java20
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java9
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/OWNERS3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java36
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java38
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java3
-rw-r--r--packages/Shell/AndroidManifest.xml17
-rw-r--r--packages/Shell/aconfig/wear.aconfig2
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig38
-rw-r--r--packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java11
-rw-r--r--packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java22
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt126
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt22
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt24
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt8
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt7
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt3
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt78
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt23
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt8
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt13
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt2
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt22
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt3
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt81
-rw-r--r--packages/SystemUI/customization/res/values-land/dimens.xml (renamed from libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/res/xml/network_security_config.xml)13
-rw-r--r--packages/SystemUI/customization/res/values-sw600dp-land/dimens.xml1
-rw-r--r--packages/SystemUI/customization/res/values/dimens.xml1
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt4
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt7
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt11
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt26
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt50
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt219
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryTest.kt167
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorTest.kt138
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt35
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt165
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt34
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java49
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt319
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt286
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt99
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt151
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt103
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt24
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt37
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskInfoTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt160
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt (renamed from packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt)26
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java15
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java305
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt42
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt92
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt24
-rw-r--r--packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java9
-rw-r--r--packages/SystemUI/res-keyguard/values-ar/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-es-rUS/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-eu/strings.xml2
-rw-r--r--packages/SystemUI/res-product/values-or/strings.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_widgets.xml26
-rw-r--r--packages/SystemUI/res/layout/bundle_notification_info.xml366
-rw-r--r--packages/SystemUI/res/layout/volume_dialog.xml4
-rw-r--r--packages/SystemUI/res/layout/volume_ringer_button.xml2
-rw-r--r--packages/SystemUI/res/layout/volume_ringer_drawer.xml55
-rw-r--r--packages/SystemUI/res/values-af/strings.xml39
-rw-r--r--packages/SystemUI/res/values-af/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-am/strings.xml39
-rw-r--r--packages/SystemUI/res/values-am/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml54
-rw-r--r--packages/SystemUI/res/values-ar/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-as/strings.xml39
-rw-r--r--packages/SystemUI/res/values-as/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-az/strings.xml39
-rw-r--r--packages/SystemUI/res/values-az/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml38
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-be/strings.xml36
-rw-r--r--packages/SystemUI/res/values-be/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml40
-rw-r--r--packages/SystemUI/res/values-bg/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml39
-rw-r--r--packages/SystemUI/res/values-bn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml54
-rw-r--r--packages/SystemUI/res/values-bs/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml45
-rw-r--r--packages/SystemUI/res/values-ca/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml39
-rw-r--r--packages/SystemUI/res/values-cs/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-da/strings.xml41
-rw-r--r--packages/SystemUI/res/values-da/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-de/strings.xml41
-rw-r--r--packages/SystemUI/res/values-de/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-el/strings.xml36
-rw-r--r--packages/SystemUI/res/values-el/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml40
-rw-r--r--packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml5
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml40
-rw-r--r--packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml40
-rw-r--r--packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml42
-rw-r--r--packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-es/strings.xml43
-rw-r--r--packages/SystemUI/res/values-es/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-et/strings.xml47
-rw-r--r--packages/SystemUI/res/values-et/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml41
-rw-r--r--packages/SystemUI/res/values-eu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml44
-rw-r--r--packages/SystemUI/res/values-fa/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml39
-rw-r--r--packages/SystemUI/res/values-fi/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml38
-rw-r--r--packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml45
-rw-r--r--packages/SystemUI/res/values-fr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml41
-rw-r--r--packages/SystemUI/res/values-gl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml40
-rw-r--r--packages/SystemUI/res/values-gu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml61
-rw-r--r--packages/SystemUI/res/values-hi/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml46
-rw-r--r--packages/SystemUI/res/values-hr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml41
-rw-r--r--packages/SystemUI/res/values-hu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml42
-rw-r--r--packages/SystemUI/res/values-hy/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml49
-rw-r--r--packages/SystemUI/res/values-in/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-is/strings.xml46
-rw-r--r--packages/SystemUI/res/values-is/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-it/strings.xml43
-rw-r--r--packages/SystemUI/res/values-it/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml47
-rw-r--r--packages/SystemUI/res/values-iw/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml48
-rw-r--r--packages/SystemUI/res/values-ja/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml36
-rw-r--r--packages/SystemUI/res/values-ka/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml39
-rw-r--r--packages/SystemUI/res/values-kk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-km/strings.xml36
-rw-r--r--packages/SystemUI/res/values-km/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml52
-rw-r--r--packages/SystemUI/res/values-kn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml43
-rw-r--r--packages/SystemUI/res/values-ko/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml53
-rw-r--r--packages/SystemUI/res/values-ky/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-land/dimens.xml1
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml36
-rw-r--r--packages/SystemUI/res/values-lo/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml36
-rw-r--r--packages/SystemUI/res/values-lt/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml39
-rw-r--r--packages/SystemUI/res/values-lv/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml39
-rw-r--r--packages/SystemUI/res/values-mk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ml/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml39
-rw-r--r--packages/SystemUI/res/values-mn/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml36
-rw-r--r--packages/SystemUI/res/values-mr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml44
-rw-r--r--packages/SystemUI/res/values-ms/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-my/strings.xml41
-rw-r--r--packages/SystemUI/res/values-my/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml39
-rw-r--r--packages/SystemUI/res/values-nb/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml44
-rw-r--r--packages/SystemUI/res/values-ne/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml36
-rw-r--r--packages/SystemUI/res/values-nl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-or/strings.xml47
-rw-r--r--packages/SystemUI/res/values-or/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml41
-rw-r--r--packages/SystemUI/res/values-pa/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml40
-rw-r--r--packages/SystemUI/res/values-pl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml47
-rw-r--r--packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml40
-rw-r--r--packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml47
-rw-r--r--packages/SystemUI/res/values-pt/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ro/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml47
-rw-r--r--packages/SystemUI/res/values-ru/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-si/strings.xml39
-rw-r--r--packages/SystemUI/res/values-si/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml57
-rw-r--r--packages/SystemUI/res/values-sk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml46
-rw-r--r--packages/SystemUI/res/values-sl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml41
-rw-r--r--packages/SystemUI/res/values-sq/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml38
-rw-r--r--packages/SystemUI/res/values-sr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml39
-rw-r--r--packages/SystemUI/res/values-sv/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml45
-rw-r--r--packages/SystemUI/res/values-sw/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/dimens.xml1
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml40
-rw-r--r--packages/SystemUI/res/values-ta/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-te/strings.xml52
-rw-r--r--packages/SystemUI/res/values-te/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-th/strings.xml38
-rw-r--r--packages/SystemUI/res/values-th/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml36
-rw-r--r--packages/SystemUI/res/values-tl/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml43
-rw-r--r--packages/SystemUI/res/values-tr/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml45
-rw-r--r--packages/SystemUI/res/values-uk/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml39
-rw-r--r--packages/SystemUI/res/values-ur/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml38
-rw-r--r--packages/SystemUI/res/values-uz/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml39
-rw-r--r--packages/SystemUI/res/values-vi/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml40
-rw-r--r--packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml39
-rw-r--r--packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml39
-rw-r--r--packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml39
-rw-r--r--packages/SystemUI/res/values-zu/tiles_states_strings.xml8
-rw-r--r--packages/SystemUI/res/values/config.xml6
-rw-r--r--packages/SystemUI/res/values/dimens.xml7
-rw-r--r--packages/SystemUI/res/values/strings.xml22
-rw-r--r--packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml49
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/data/repository/DevelopmentSettingRepository.kt79
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt89
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/shared/model/BuildNumber.kt (renamed from packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/ui/compose/BuildNumber.kt81
-rw-r--r--packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt66
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java129
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt201
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt168
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt (renamed from packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CustomShortcutCategories.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/DefaultShortcutCategories.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/KeyCombination.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt127
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt112
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt109
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl4
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.aidl3
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfo.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskLaunchMode.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt112
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddable.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt107
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/OWNERS2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt422
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java124
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt172
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepository.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractor.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractor.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/shared/model/SliderInputEvent.kt (renamed from media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl)15
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt52
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt (renamed from packages/SystemUI/src/com/android/systemui/haptics/slider/SliderQuantization.kt)22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt63
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt103
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt232
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt137
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java38
-rw-r--r--packages/SystemUI/tests/utils/src/android/content/ClipboardManagerKosmos.kt22
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryKosmos.kt (renamed from media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl)15
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt35
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModelKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepositoryKosmos.kt (renamed from media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl)13
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorKosmo.kt33
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java6
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java66
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java67
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java15
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java4
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java47
-rw-r--r--ravenwood/tests/bivalentinst/Android.bp7
-rw-r--r--ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java7
-rw-r--r--ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java9
-rw-r--r--ravenwood/tests/bivalenttest/Android.bp2
-rw-r--r--ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java10
-rw-r--r--ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt12
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java9
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java3
-rw-r--r--ravenwood/tests/runtime-test/Android.bp2
-rw-r--r--ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java12
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java37
-rw-r--r--services/autofill/java/com/android/server/autofill/Helper.java5
-rw-r--r--services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java318
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java6
-rw-r--r--services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java3
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java266
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java2
-rw-r--r--services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java6
-rw-r--r--services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java5
-rw-r--r--services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java23
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java7
-rw-r--r--services/companion/java/com/android/server/companion/securechannel/SecureChannel.java4
-rw-r--r--services/core/java/com/android/server/SystemConfig.java19
-rw-r--r--services/core/java/com/android/server/VcnManagementService.java20
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java25
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java41
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java49
-rw-r--r--services/core/java/com/android/server/am/AppStartInfoTracker.java25
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig10
-rw-r--r--services/core/java/com/android/server/audio/AudioServerPermissionProvider.java4
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java5
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java12
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java2
-rw-r--r--services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java5
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java2
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java6
-rw-r--r--services/core/java/com/android/server/display/plugin/Plugin.java44
-rw-r--r--services/core/java/com/android/server/display/plugin/PluginManager.java141
-rw-r--r--services/core/java/com/android/server/display/plugin/PluginStorage.java134
-rw-r--r--services/core/java/com/android/server/display/plugin/PluginType.java48
-rw-r--r--services/core/java/com/android/server/display/plugin/PluginsProvider.java36
-rw-r--r--services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java10
-rw-r--r--services/core/java/com/android/server/input/AppLaunchShortcutManager.java23
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java51
-rw-r--r--services/core/java/com/android/server/input/InputSettingsObserver.java9
-rw-r--r--services/core/java/com/android/server/input/InputShellCommand.java1
-rw-r--r--services/core/java/com/android/server/input/KeyGestureController.java5
-rw-r--r--services/core/java/com/android/server/input/NativeInputManagerService.java5
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java2
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java7
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java17
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java16
-rw-r--r--services/core/java/com/android/server/media/quality/MediaQualityService.java11
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java130
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java112
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java13
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java12
-rw-r--r--services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java12
-rw-r--r--services/core/java/com/android/server/pm/OWNERS28
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java85
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java300
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java99
-rw-r--r--services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java91
-rw-r--r--services/core/java/com/android/server/pm/verify/pkg/VerifierController.java721
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java5
-rw-r--r--services/core/java/com/android/server/power/hint/Android.bp9
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java279
-rw-r--r--services/core/java/com/android/server/power/hint/adpf_flags.aconfig7
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java4
-rw-r--r--services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java49
-rw-r--r--services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceService.java120
-rw-r--r--services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceServiceInternal.java55
-rw-r--r--services/core/java/com/android/server/security/forensic/OWNERS1
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java (renamed from services/core/java/com/android/server/security/forensic/DataAggregator.java)30
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/DataSource.java (renamed from services/core/java/com/android/server/security/forensic/DataSource.java)2
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java (renamed from services/core/java/com/android/server/security/forensic/ForensicEventTransportConnection.java)42
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionService.java (renamed from services/core/java/com/android/server/security/forensic/ForensicService.java)135
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/OWNERS1
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java (renamed from services/core/java/com/android/server/security/forensic/SecurityLogSource.java)12
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java96
-rw-r--r--services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java327
-rw-r--r--services/core/java/com/android/server/vibrator/DeviceAdapter.java2
-rw-r--r--services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java41
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperDataParser.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java9
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java27
-rw-r--r--services/core/java/com/android/server/wm/AppCompatCameraOverrides.java24
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java46
-rw-r--r--services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java31
-rw-r--r--services/core/java/com/android/server/wm/MirrorActiveUids.java47
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java13
-rw-r--r--services/core/java/com/android/server/wm/RefreshRatePolicy.java10
-rw-r--r--services/core/java/com/android/server/wm/Session.java11
-rw-r--r--services/core/java/com/android/server/wm/Task.java77
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java48
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java7
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp7
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java59
-rw-r--r--services/java/com/android/server/SystemServer.java50
-rw-r--r--services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java10
-rw-r--r--services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java33
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java8
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt20
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java69
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java113
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java535
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java6
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java9
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java3
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt97
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt100
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java381
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java216
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/fullbackup/PerformFullTransportBackupTaskTest.java11
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java8
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java104
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java5
-rw-r--r--services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java15
-rw-r--r--services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java196
-rw-r--r--services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java10
-rw-r--r--services/tests/security/forensic/OWNERS3
-rw-r--r--services/tests/security/forensic/TEST_MAPPING7
-rw-r--r--services/tests/security/intrusiondetection/Android.bp (renamed from services/tests/security/forensic/Android.bp)2
-rw-r--r--services/tests/security/intrusiondetection/AndroidManifest.xml (renamed from services/tests/security/forensic/AndroidManifest.xml)6
-rw-r--r--services/tests/security/intrusiondetection/AndroidTest.xml (renamed from services/tests/security/forensic/AndroidTest.xml)8
-rw-r--r--services/tests/security/intrusiondetection/OWNERS3
-rw-r--r--services/tests/security/intrusiondetection/TEST_MAPPING7
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java (renamed from services/tests/security/forensic/src/com/android/server/security/forensic/ForensicServiceTest.java)176
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java34
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java168
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java77
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java68
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java154
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java10
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java14
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java58
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java51
-rw-r--r--services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java1
-rw-r--r--services/tests/wmtests/AndroidManifest.xml4
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java24
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java100
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java58
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java40
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java8
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java32
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java18
-rw-r--r--telephony/java/android/telephony/satellite/EarfcnRange.java22
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java52
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteInfo.java73
-rw-r--r--telephony/java/android/telephony/satellite/SatellitePosition.java22
-rw-r--r--tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java92
-rw-r--r--tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml8
-rw-r--r--tests/CtsSurfaceControlTestsStaging/AndroidTest.xml3
-rw-r--r--tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java260
-rw-r--r--tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java43
-rw-r--r--tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml32
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt2
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt2
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt2
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt2
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt2
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt2
-rw-r--r--tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt19
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt2
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/StartMediaProjectionAppHelper.kt44
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml18
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/StartMediaProjectionActivity.java18
-rw-r--r--tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt2
-rw-r--r--tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java3
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java3
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java3
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java3
-rw-r--r--tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java2
-rw-r--r--tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java32
-rw-r--r--tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java6
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java3
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt3
1419 files changed, 30548 insertions, 15653 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 6393fdb910e3..a2994088cfb2 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -56,7 +56,7 @@ aconfig_declarations_group {
"android.media.tv.flags-aconfig-java",
"android.multiuser.flags-aconfig-java",
"android.net.platform.flags-aconfig-java",
- "android.net.vcn.flags-aconfig-java",
+ "android.net.vcn.flags-aconfig-java-export",
"android.net.wifi.flags-aconfig-java",
"android.nfc.flags-aconfig-java",
"android.os.flags-aconfig-java",
@@ -1170,16 +1170,21 @@ java_aconfig_library {
}
// VCN
+// TODO:376339506 Move the VCN code, the flag declaration and
+// java_aconfig_library to framework-connectivity-b
aconfig_declarations {
name: "android.net.vcn.flags-aconfig",
package: "android.net.vcn",
- container: "system",
+ container: "com.android.tethering",
+ exportable: true,
srcs: ["core/java/android/net/vcn/*.aconfig"],
}
java_aconfig_library {
- name: "android.net.vcn.flags-aconfig-java",
+ name: "android.net.vcn.flags-aconfig-java-export",
aconfig_declarations: "android.net.vcn.flags-aconfig",
+ mode: "exported",
+ min_sdk_version: "35",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
diff --git a/Android.bp b/Android.bp
index 54cb2684068d..424a4a71ce40 100644
--- a/Android.bp
+++ b/Android.bp
@@ -103,10 +103,10 @@ filegroup {
":android.hardware.gnss-V2-java-source",
":android.hardware.graphics.common-V3-java-source",
":android.hardware.keymaster-V4-java-source",
- ":android.hardware.radio-V3-java-source",
- ":android.hardware.radio.data-V3-java-source",
- ":android.hardware.radio.network-V3-java-source",
- ":android.hardware.radio.voice-V3-java-source",
+ ":android.hardware.radio-V4-java-source",
+ ":android.hardware.radio.data-V4-java-source",
+ ":android.hardware.radio.network-V4-java-source",
+ ":android.hardware.radio.voice-V4-java-source",
":android.hardware.security.secureclock-V1-java-source",
":android.hardware.thermal-V3-java-source",
":android.hardware.tv.tuner-V3-java-source",
@@ -232,13 +232,13 @@ java_library {
"android.hardware.gnss-V2.1-java",
"android.hardware.health-V1.0-java-constants",
"android.hardware.radio-V1.6-java",
- "android.hardware.radio.data-V3-java",
- "android.hardware.radio.ims-V2-java",
- "android.hardware.radio.messaging-V3-java",
- "android.hardware.radio.modem-V3-java",
- "android.hardware.radio.network-V3-java",
- "android.hardware.radio.sim-V3-java",
- "android.hardware.radio.voice-V3-java",
+ "android.hardware.radio.data-V4-java",
+ "android.hardware.radio.ims-V3-java",
+ "android.hardware.radio.messaging-V4-java",
+ "android.hardware.radio.modem-V4-java",
+ "android.hardware.radio.network-V4-java",
+ "android.hardware.radio.sim-V4-java",
+ "android.hardware.radio.voice-V4-java",
"android.hardware.thermal-V1.0-java-constants",
"android.hardware.thermal-V1.0-java",
"android.hardware.thermal-V1.1-java",
@@ -397,6 +397,8 @@ java_defaults {
"ext",
"framework-updatable-stubs-module_libs_api",
"unsupportedappusage",
+ // TODO(b/379770939): remove prod version of flags from other containers in framework
+ "aconfig_storage_stub",
],
sdk_version: "core_platform",
static_libs: [
diff --git a/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
index 46250d74a4e3..d950b708dcc6 100644
--- a/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
+++ b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java
@@ -34,6 +34,8 @@ import org.junit.Test;
public class TextClassificationManagerPerfTest {
private static final String WRITE_DEVICE_CONFIG_PERMISSION =
"android.permission.WRITE_DEVICE_CONFIG";
+ private static final String WRITE_ALLOWLISTED_DEVICE_CONFIG_PERMISSION =
+ "android.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG";
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@@ -44,7 +46,7 @@ public class TextClassificationManagerPerfTest {
public static void setUpClass() {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.adoptShellPermissionIdentity(
- WRITE_DEVICE_CONFIG_PERMISSION);
+ WRITE_DEVICE_CONFIG_PERMISSION, WRITE_ALLOWLISTED_DEVICE_CONFIG_PERMISSION);
}
@AfterClass
diff --git a/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java b/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java
index 7ef8c53d1d62..7168fbec07bc 100644
--- a/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java
+++ b/apct-tests/perftests/tracing/src/com/android/internal/protolog/ProtoLogPerfTest.java
@@ -19,6 +19,9 @@ import android.app.Activity;
import android.os.Bundle;
import android.os.ServiceManager.ServiceNotFoundException;
import android.perftests.utils.Stats;
+import android.tracing.perfetto.DataSourceParams;
+import android.tracing.perfetto.InitArguments;
+import android.tracing.perfetto.Producer;
import androidx.test.InstrumentationRegistry;
@@ -70,6 +73,8 @@ public class ProtoLogPerfTest {
}
private IProtoLog mProcessedProtoLogger;
+ private static ProtoLogDataSource sTestDataSource;
+ private static final String TEST_PROTOLOG_DATASOURCE_NAME = "test.android.protolog";
private static final String MOCK_TEST_FILE_PATH = "mock/file/path";
private static final perfetto.protos.Protolog.ProtoLogViewerConfig VIEWER_CONFIG =
perfetto.protos.Protolog.ProtoLogViewerConfig.newBuilder()
@@ -89,6 +94,17 @@ public class ProtoLogPerfTest {
@BeforeClass
public static void init() {
+ Producer.init(InitArguments.DEFAULTS);
+
+ sTestDataSource = new ProtoLogDataSource(TEST_PROTOLOG_DATASOURCE_NAME);
+ DataSourceParams params =
+ new DataSourceParams.Builder()
+ .setBufferExhaustedPolicy(
+ DataSourceParams
+ .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
+ .build();
+ sTestDataSource.register(params);
+
ProtoLog.init(TestProtoLogGroup.values());
}
@@ -98,9 +114,10 @@ public class ProtoLogPerfTest {
TestProtoLogGroup.TEST_GROUP.setLogToLogcat(mLogToLogcat);
mProcessedProtoLogger = new ProcessedPerfettoProtoLogImpl(
+ sTestDataSource,
MOCK_TEST_FILE_PATH,
() -> new AutoClosableProtoInputStream(VIEWER_CONFIG.toByteArray()),
- () -> {},
+ (instance) -> {},
TestProtoLogGroup.values()
);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 1c6e40e25a92..963307b110cf 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -2085,8 +2085,12 @@ public class JobSchedulerService extends com.android.server.SystemService
if (DEBUG) {
Slog.v(TAG, debugPrefix + " ready=" + jobReady);
}
- if (!jobReady) {
- return job.getPendingJobReasons();
+ final JobRestriction restriction = checkIfRestricted(job);
+ if (DEBUG) {
+ Slog.v(TAG, debugPrefix + " restriction=" + restriction);
+ }
+ if (!jobReady || restriction != null) {
+ return job.getPendingJobReasons(restriction);
}
final boolean userStarted = areUsersStartedLocked(job);
@@ -2106,18 +2110,6 @@ public class JobSchedulerService extends com.android.server.SystemService
return new int[] { JobScheduler.PENDING_JOB_REASON_APP };
}
- final JobRestriction restriction = checkIfRestricted(job);
- if (DEBUG) {
- Slog.v(TAG, debugPrefix + " restriction=" + restriction);
- }
- if (restriction != null) {
- // Currently this will return _DEVICE_STATE because of thermal reasons.
- // TODO (b/372031023): does it make sense to move this along with the
- // pendingJobReasons() call above and also get the pending reasons from
- // all of the restriction controllers?
- return new int[] { restriction.getPendingReason() };
- }
-
// The following can be a little more expensive, so we are doing it later,
// but still before checking with the package manager!
final boolean jobPending = mPendingJobQueue.contains(job);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index b0784f1c69fd..a3eaefd5f057 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -66,6 +66,7 @@ import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobServerProtoEnums;
import com.android.server.job.JobStatusDumpProto;
import com.android.server.job.JobStatusShortInfoProto;
+import com.android.server.job.restrictions.JobRestriction;
import dalvik.annotation.optimization.NeverCompile;
@@ -2179,11 +2180,20 @@ public final class JobStatus {
* This will return all potential reasons why the job is pending.
*/
@NonNull
- public int[] getPendingJobReasons() {
+ public int[] getPendingJobReasons(@Nullable JobRestriction restriction) {
final int unsatisfiedConstraints = ~satisfiedConstraints
& (requiredConstraints | mDynamicConstraints | IMPLICIT_CONSTRAINTS);
final ArrayList<Integer> reasons = constraintsToPendingJobReasons(unsatisfiedConstraints);
+ if (restriction != null) {
+ // Currently only ThermalStatusRestriction extends the JobRestriction class and
+ // returns PENDING_JOB_REASON_DEVICE_STATE if the job is restricted because of thermal.
+ @JobScheduler.PendingJobReason final int reason = restriction.getPendingReason();
+ if (!reasons.contains(reason)) {
+ reasons.addLast(reason);
+ }
+ }
+
if (reasons.isEmpty()) {
if (getEffectiveStandbyBucket() == NEVER_INDEX) {
Slog.wtf(TAG, "App in NEVER bucket querying pending job reason");
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 8bd3ef4f4d1a..637c726a9bd1 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -36,10 +36,14 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.UidObserver;
+import android.app.compat.CompatChanges;
import android.app.job.JobInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
import android.app.usage.UsageStatsManagerInternal.UsageEventListener;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
+import android.compat.annotation.Overridable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -132,6 +136,27 @@ public final class QuotaController extends StateController {
return (int) (val ^ (val >>> 32));
}
+ /**
+ * When enabled this change id overrides the default quota policy enforcement to the jobs
+ * running in the foreground process state.
+ */
+ // TODO: b/379681266 - Might need some refactoring for a better app-compat strategy.
+ @VisibleForTesting
+ @ChangeId
+ @Disabled // Disabled by default
+ @Overridable // The change can be overridden in user build
+ static final long OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS = 341201311L;
+
+ /**
+ * When enabled this change id overrides the default quota policy enforcement policy
+ * the jobs started when app was in the TOP state.
+ */
+ @VisibleForTesting
+ @ChangeId
+ @Disabled // Disabled by default
+ @Overridable // The change can be overridden in user build.
+ static final long OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS = 374323858L;
+
@VisibleForTesting
static class ExecutionStats {
/**
@@ -622,7 +647,9 @@ public final class QuotaController extends StateController {
}
final int uid = jobStatus.getSourceUid();
- if (!Flags.enforceQuotaPolicyToTopStartedJobs() && mTopAppCache.get(uid)) {
+ if ((!Flags.enforceQuotaPolicyToTopStartedJobs()
+ || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
+ uid)) && mTopAppCache.get(uid)) {
if (DEBUG) {
Slog.d(TAG, jobStatus.toShortString() + " is top started job");
}
@@ -659,7 +686,9 @@ public final class QuotaController extends StateController {
timer.stopTrackingJob(jobStatus);
}
}
- if (!Flags.enforceQuotaPolicyToTopStartedJobs()) {
+ if (!Flags.enforceQuotaPolicyToTopStartedJobs()
+ || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
+ jobStatus.getSourceUid())) {
mTopStartedJobs.remove(jobStatus);
}
}
@@ -772,7 +801,13 @@ public final class QuotaController extends StateController {
/** @return true if the job was started while the app was in the TOP state. */
private boolean isTopStartedJobLocked(@NonNull final JobStatus jobStatus) {
- return !Flags.enforceQuotaPolicyToTopStartedJobs() && mTopStartedJobs.contains(jobStatus);
+ if (!Flags.enforceQuotaPolicyToTopStartedJobs()
+ || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
+ jobStatus.getSourceUid())) {
+ return mTopStartedJobs.contains(jobStatus);
+ }
+
+ return false;
}
/** Returns the maximum amount of time this job could run for. */
@@ -2634,9 +2669,13 @@ public final class QuotaController extends StateController {
}
@VisibleForTesting
- int getProcessStateQuotaFreeThreshold() {
- return Flags.enforceQuotaPolicyToFgsJobs() ? ActivityManager.PROCESS_STATE_BOUND_TOP :
- ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+ int getProcessStateQuotaFreeThreshold(int uid) {
+ if (Flags.enforceQuotaPolicyToFgsJobs()
+ && !CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS, uid)) {
+ return ActivityManager.PROCESS_STATE_BOUND_TOP;
+ }
+
+ return ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
}
private class QcHandler extends Handler {
@@ -2776,7 +2815,7 @@ public final class QuotaController extends StateController {
isQuotaFree = true;
} else {
final boolean reprocess;
- if (procState <= getProcessStateQuotaFreeThreshold()) {
+ if (procState <= getProcessStateQuotaFreeThreshold(uid)) {
reprocess = !mForegroundUids.get(uid);
mForegroundUids.put(uid, true);
isQuotaFree = true;
diff --git a/cmds/interrupter/Android.bp b/cmds/interrupter/Android.bp
deleted file mode 100644
index d7f744d0834e..000000000000
--- a/cmds/interrupter/Android.bp
+++ /dev/null
@@ -1,20 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-cc_library_shared {
- name: "interrupter",
- host_supported: true,
- srcs: ["interrupter.c"],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wunused",
- "-Wunreachable-code",
- ],
-}
diff --git a/cmds/interrupter/interrupter.c b/cmds/interrupter/interrupter.c
deleted file mode 100644
index ae555150c969..000000000000
--- a/cmds/interrupter/interrupter.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * The probability of a syscall failing from 0.0 to 1.0
- */
-#define PROBABILITY 0.9
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* for various intercepted calls */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-/* For builds on glibc */
-#define __USE_GNU
-#include <dlfcn.h>
-
-#include "interrupter.h"
-
-static int probability = PROBABILITY * RAND_MAX;
-
-static int maybe_interrupt() {
- if (rand() < probability) {
- return 1;
- }
- return 0;
-}
-
-DEFINE_INTERCEPT(read, ssize_t, int, void*, size_t);
-DEFINE_INTERCEPT(write, ssize_t, int, const void*, size_t);
-DEFINE_INTERCEPT(accept, int, int, struct sockaddr*, socklen_t*);
-DEFINE_INTERCEPT(creat, int, const char*, mode_t);
diff --git a/cmds/interrupter/interrupter.h b/cmds/interrupter/interrupter.h
deleted file mode 100644
index 9ad0277eebbe..000000000000
--- a/cmds/interrupter/interrupter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2)
-#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
-#define CONCATENATE2(arg1, arg2) arg1##arg2
-
-#define INTERRUPTER(sym) \
- if (real_##sym == NULL) \
- __init_##sym(); \
- if (maybe_interrupt()) { \
- errno = EINTR; \
- return -1; \
- }
-
-#define CALL_FUNCTION_1(sym, ret, type1) \
-ret (*real_##sym)(type1) = NULL; \
-ret sym(type1 arg1) { \
- INTERRUPTER(sym) \
- return real_##sym(arg1); \
-}
-
-#define CALL_FUNCTION_2(sym, ret, type1, type2) \
-ret (*real_##sym)(type1, type2) = NULL; \
-ret sym(type1 arg1, type2 arg2) { \
- INTERRUPTER(sym) \
- return real_##sym(arg1, arg2); \
-}
-
-#define CALL_FUNCTION_3(sym, ret, type1, type2, type3) \
-ret (*real_##sym)(type1, type2, type3) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3) { \
- INTERRUPTER(sym) \
- return real_##sym(arg1, arg2, arg3); \
-}
-
-#define CALL_FUNCTION_4(sym, ret, type1, type2, type3, type4) \
-ret (*real_##sym)(type1, type2, type3, type4) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
- INTERRUPTER(sym) \
- return real_##sym(arg1, arg2, arg3, arg4); \
-}
-
-#define CALL_FUNCTION_5(sym, ret, type1, type2, type3, type4, type5) \
-ret (*real_##sym)(type1, type2, type3, type4, type5) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
- INTERRUPTER(sym) \
- return real_##sym(arg1, arg2, arg3, arg4, arg5); \
-}
-
-#define DEFINE_INTERCEPT_N(N, sym, ret, ...) \
-static void __init_##sym(void); \
-CONCATENATE(CALL_FUNCTION_, N)(sym, ret, __VA_ARGS__) \
-static void __init_##sym(void) { \
- real_##sym = dlsym(RTLD_NEXT, #sym); \
- if (real_##sym == NULL) { \
- fprintf(stderr, "Error hooking " #sym ": %s\n", dlerror()); \
- } \
-}
-
-#define INTERCEPT_NARG(...) INTERCEPT_NARG_N(__VA_ARGS__, INTERCEPT_RSEQ_N())
-#define INTERCEPT_NARG_N(...) INTERCEPT_ARG_N(__VA_ARGS__)
-#define INTERCEPT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
-#define INTERCEPT_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
-
-#define DEFINE_INTERCEPT(sym, ret, ...) DEFINE_INTERCEPT_N(INTERCEPT_NARG(__VA_ARGS__), sym, ret, __VA_ARGS__)
diff --git a/core/api/current.txt b/core/api/current.txt
index 81c85a9dc8c0..45f6a3fbe0cb 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -3830,7 +3830,7 @@ package android.accounts {
method @RequiresPermission(value="android.permission.AUTHENTICATE_ACCOUNTS", apis="..22") public boolean notifyAccountAuthenticated(android.accounts.Account);
method @RequiresPermission(value="android.permission.AUTHENTICATE_ACCOUNTS", apis="..22") public String peekAuthToken(android.accounts.Account, String);
method @Deprecated @RequiresPermission(value="android.permission.MANAGE_ACCOUNTS", apis="..22") public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
- method @RequiresPermission(value="android.permission.MANAGE_ACCOUNTS", apis="..22") public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+ method @FlaggedApi("android.app.admin.flags.split_create_managed_profile_enabled") @RequiresPermission(value="android.permission.REMOVE_ACCOUNTS", conditional=true) public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method @RequiresPermission(value="android.permission.AUTHENTICATE_ACCOUNTS", apis="..22") public boolean removeAccountExplicitly(android.accounts.Account);
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
method @RequiresPermission(value="android.permission.AUTHENTICATE_ACCOUNTS", apis="..22") public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, @Size(min=1) String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
@@ -4614,6 +4614,7 @@ package android.app {
method public void reportFullyDrawn();
method public android.view.DragAndDropPermissions requestDragAndDropPermissions(android.view.DragEvent);
method public void requestFullscreenMode(int, @Nullable android.os.OutcomeReceiver<java.lang.Void,java.lang.Throwable>);
+ method @FlaggedApi("com.android.window.flags.enable_desktop_windowing_app_to_web_education") public final void requestOpenInBrowserEducation();
method public final void requestPermissions(@NonNull String[], int);
method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") public final void requestPermissions(@NonNull String[], int, int);
method public final void requestShowKeyboardShortcuts();
@@ -4639,7 +4640,6 @@ package android.app {
method public void setInheritShowWhenLocked(boolean);
method public void setIntent(android.content.Intent);
method @FlaggedApi("android.security.content_uri_permission_apis") public void setIntent(@Nullable android.content.Intent, @Nullable android.app.ComponentCaller);
- method @FlaggedApi("com.android.window.flags.enable_desktop_windowing_app_to_web_education") public final void setLimitSystemEducationDialogs(boolean);
method public void setLocusContext(@Nullable android.content.LocusId, @Nullable android.os.Bundle);
method public final void setMediaController(android.media.session.MediaController);
method public void setPictureInPictureParams(@NonNull android.app.PictureInPictureParams);
@@ -13146,9 +13146,9 @@ package android.content.pm {
method public void setAppLabel(@Nullable CharSequence);
method public void setAppPackageName(@Nullable String);
method public void setApplicationEnabledSettingPersistent();
+ method @FlaggedApi("android.content.pm.sdk_dependency_installer") public void setAutoInstallDependenciesEnabled(boolean);
method @Deprecated public void setAutoRevokePermissionsMode(boolean);
method public void setDontKillApp(boolean);
- method @FlaggedApi("android.content.pm.sdk_dependency_installer") public void setEnableAutoInstallDependencies(boolean);
method public void setInstallLocation(int);
method public void setInstallReason(int);
method public void setInstallScenario(int);
@@ -13399,6 +13399,7 @@ package android.content.pm {
field public static final String FEATURE_BACKUP = "android.software.backup";
field public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
field public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
+ field @FlaggedApi("com.android.ranging.flags.ranging_cs_enabled") public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING = "android.hardware.bluetooth_le.channel_sounding";
field public static final String FEATURE_CAMERA = "android.hardware.camera";
field public static final String FEATURE_CAMERA_ANY = "android.hardware.camera.any";
field public static final String FEATURE_CAMERA_AR = "android.hardware.camera.ar";
@@ -13808,7 +13809,7 @@ package android.content.pm {
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CAMERA}, anyOf={android.Manifest.permission.CAMERA}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR, android.Manifest.permission.UWB_RANGING, android.Manifest.permission.RANGING}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
- field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_HEALTH}, anyOf={android.Manifest.permission.ACTIVITY_RECOGNITION, android.Manifest.permission.BODY_SENSORS, android.Manifest.permission.HIGH_SAMPLING_RATE_SENSORS}) public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 256; // 0x100
+ field @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_HEALTH}, anyOf={android.Manifest.permission.ACTIVITY_RECOGNITION, android.Manifest.permission.HIGH_SAMPLING_RATE_SENSORS, android.health.connect.HealthPermissions.READ_HEART_RATE, android.health.connect.HealthPermissions.READ_SKIN_TEMPERATURE, android.health.connect.HealthPermissions.READ_OXYGEN_SATURATION}) public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 256; // 0x100
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_LOCATION}, anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
field public static final int FOREGROUND_SERVICE_TYPE_MANIFEST = -1; // 0xffffffff
field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 2; // 0x2
@@ -21097,6 +21098,7 @@ package android.inputmethodservice {
method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface();
method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
method public boolean onGenericMotionEvent(android.view.MotionEvent);
+ method @FlaggedApi("android.view.inputmethod.verify_key_event") public boolean onShouldVerifyKeyEvent(@NonNull android.view.KeyEvent);
method public boolean onTrackballEvent(android.view.MotionEvent);
}
@@ -21114,6 +21116,7 @@ package android.inputmethodservice {
method public void dispatchTrackballEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback);
method public boolean isEnabled();
method public boolean isRevoked();
+ method @FlaggedApi("android.view.inputmethod.verify_key_event") public boolean onShouldVerifyKeyEvent(@NonNull android.view.KeyEvent);
method public void revokeSelf();
method public void setEnabled(boolean);
}
@@ -21213,6 +21216,7 @@ package android.inputmethodservice {
method public void setExtractView(android.view.View);
method public void setExtractViewShown(boolean);
method public void setInputView(android.view.View);
+ method @FlaggedApi("android.view.inputmethod.adaptive_handwriting_bounds") public final void setStylusHandwritingRegion(@NonNull android.graphics.Region);
method public final void setStylusHandwritingSessionTimeout(@NonNull java.time.Duration);
method public final boolean shouldOfferSwitchingToNextInputMethod();
method public void showStatusIcon(@DrawableRes int);
@@ -23189,7 +23193,6 @@ package android.media {
method public boolean isVendor();
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_MEMORY_SAFE = 1; // 0x1
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_SANDBOXED = 0; // 0x0
- field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; // 0x2
}
public static final class MediaCodecInfo.AudioCapabilities {
@@ -23506,6 +23509,18 @@ package android.media {
field public static final int HEVCProfileMain10HDR10 = 4096; // 0x1000
field public static final int HEVCProfileMain10HDR10Plus = 8192; // 0x2000
field public static final int HEVCProfileMainStill = 4; // 0x4
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseAac = 16908290; // 0x1020002
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedAac = 17039362; // 0x1040002
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedFlac = 17039364; // 0x1040004
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedOpus = 17039361; // 0x1040001
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseEnhancedPcm = 17039368; // 0x1040008
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseFlac = 16908292; // 0x1020004
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBaseOpus = 16908289; // 0x1020001
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileBasePcm = 16908296; // 0x1020008
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimpleAac = 16842754; // 0x1010002
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimpleFlac = 16842756; // 0x1010004
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimpleOpus = 16842753; // 0x1010001
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int IAMFProfileSimplePcm = 16842760; // 0x1010008
field public static final int MPEG2LevelH14 = 2; // 0x2
field public static final int MPEG2LevelHL = 3; // 0x3
field public static final int MPEG2LevelHP = 4; // 0x4
@@ -24080,7 +24095,6 @@ package android.media {
field public static final int COLOR_TRANSFER_ST2084 = 6; // 0x6
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_MEMORY_SAFE = 2; // 0x2
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_SANDBOXED = 1; // 0x1
- field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 4; // 0x4
field public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode";
field public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
field public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
@@ -24204,6 +24218,7 @@ package android.media {
field public static final String MIMETYPE_AUDIO_FLAC = "audio/flac";
field public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
field public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final String MIMETYPE_AUDIO_IAMF = "audio/iamf";
field public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937";
field public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
field public static final String MIMETYPE_AUDIO_MPEGH_BL_L3 = "audio/mhm1.03";
@@ -27060,6 +27075,53 @@ package android.media.projection {
package android.media.quality {
+ @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightEvent implements android.os.Parcelable {
+ ctor public AmbientBacklightEvent(int, @Nullable android.media.quality.AmbientBacklightMetadata);
+ method public int describeContents();
+ method public int getEventType();
+ method @Nullable public android.media.quality.AmbientBacklightMetadata getMetadata();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int AMBIENT_BACKLIGHT_EVENT_DISABLED = 2; // 0x2
+ field public static final int AMBIENT_BACKLIGHT_EVENT_ENABLED = 1; // 0x1
+ field public static final int AMBIENT_BACKLIGHT_EVENT_INTERRUPTED = 4; // 0x4
+ field public static final int AMBIENT_BACKLIGHT_EVENT_METADATA = 3; // 0x3
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.AmbientBacklightEvent> CREATOR;
+ }
+
+ @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightMetadata implements android.os.Parcelable {
+ ctor public AmbientBacklightMetadata(@NonNull String, int, int, int, int, int, @NonNull int[]);
+ method public int describeContents();
+ method public int getColorFormat();
+ method public int getCompressAlgorithm();
+ method @IntRange(from=0) public int getHorizontalZonesNumber();
+ method @NonNull public String getPackageName();
+ method public int getSource();
+ method @IntRange(from=0) public int getVerticalZonesNumber();
+ method @NonNull public int[] getZonesColors();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.AmbientBacklightMetadata> CREATOR;
+ }
+
+ @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightSettings implements android.os.Parcelable {
+ ctor public AmbientBacklightSettings(int, int, int, int, int, boolean, int);
+ method public int describeContents();
+ method public int getColorFormat();
+ method @IntRange(from=0) public int getHorizontalZonesNumber();
+ method @IntRange(from=1) public int getMaxFps();
+ method public int getSource();
+ method public int getThreshold();
+ method @IntRange(from=0) public int getVerticalZonesNumber();
+ method public boolean isLetterboxOmitted();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int ALGORITHM_NONE = 0; // 0x0
+ field public static final int ALGORITHM_RLE = 1; // 0x1
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.AmbientBacklightSettings> CREATOR;
+ field public static final int SOURCE_AUDIO = 1; // 0x1
+ field public static final int SOURCE_AUDIO_VIDEO = 3; // 0x3
+ field public static final int SOURCE_NONE = 0; // 0x0
+ field public static final int SOURCE_VIDEO = 2; // 0x2
+ }
+
@FlaggedApi("android.media.tv.flags.media_quality_fw") public class MediaQualityContract {
}
@@ -27070,17 +27132,41 @@ package android.media.quality {
field public static final String PARAMETER_SHARPNESS = "sharpness";
}
+ public static final class MediaQualityContract.SoundQuality {
+ field public static final String PARAMETER_BALANCE = "balance";
+ field public static final String PARAMETER_BASS = "bass";
+ field public static final String PARAMETER_TREBLE = "treble";
+ }
+
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class MediaQualityManager {
method public void createPictureProfile(@NonNull android.media.quality.PictureProfile);
+ method public void createSoundProfile(@NonNull android.media.quality.SoundProfile);
method @NonNull public java.util.List<android.media.quality.PictureProfile> getAvailablePictureProfiles();
+ method @NonNull public java.util.List<android.media.quality.SoundProfile> getAvailableSoundProfiles();
method @NonNull public java.util.List<android.media.quality.ParamCapability> getParamCapabilities(@NonNull java.util.List<java.lang.String>);
method @Nullable public android.media.quality.PictureProfile getPictureProfile(int, @NonNull String);
+ method @Nullable public android.media.quality.SoundProfile getSoundProfile(int, @NonNull String);
+ method public boolean isAmbientBacklightEnabled();
method public boolean isAutoPictureQualityEnabled();
+ method public boolean isAutoSoundQualityEnabled();
method public boolean isSuperResolutionEnabled();
+ method public void registerAmbientBacklightCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.AmbientBacklightCallback);
method public void registerPictureProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.PictureProfileCallback);
+ method public void registerSoundProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.SoundProfileCallback);
method public void removePictureProfile(@NonNull String);
+ method public void removeSoundProfile(@NonNull String);
+ method public void setAmbientBacklightEnabled(boolean);
+ method public void setAmbientBacklightSettings(@NonNull android.media.quality.AmbientBacklightSettings);
+ method public void unregisterAmbientBacklightCallback(@NonNull android.media.quality.MediaQualityManager.AmbientBacklightCallback);
method public void unregisterPictureProfileCallback(@NonNull android.media.quality.MediaQualityManager.PictureProfileCallback);
+ method public void unregisterSoundProfileCallback(@NonNull android.media.quality.MediaQualityManager.SoundProfileCallback);
method public void updatePictureProfile(@NonNull String, @NonNull android.media.quality.PictureProfile);
+ method public void updateSoundProfile(@NonNull String, @NonNull android.media.quality.SoundProfile);
+ }
+
+ public abstract static class MediaQualityManager.AmbientBacklightCallback {
+ ctor public MediaQualityManager.AmbientBacklightCallback();
+ method public void onAmbientBacklightEvent(@NonNull android.media.quality.AmbientBacklightEvent);
}
public abstract static class MediaQualityManager.PictureProfileCallback {
@@ -27092,6 +27178,15 @@ package android.media.quality {
method public void onPictureProfileUpdated(@NonNull String, @NonNull android.media.quality.PictureProfile);
}
+ public abstract static class MediaQualityManager.SoundProfileCallback {
+ ctor public MediaQualityManager.SoundProfileCallback();
+ method public void onError(int);
+ method public void onParamCapabilitiesChanged(@Nullable String, @NonNull java.util.List<android.media.quality.ParamCapability>);
+ method public void onSoundProfileAdded(@NonNull String, @NonNull android.media.quality.SoundProfile);
+ method public void onSoundProfileRemoved(@NonNull String, @NonNull android.media.quality.SoundProfile);
+ method public void onSoundProfileUpdated(@NonNull String, @NonNull android.media.quality.SoundProfile);
+ }
+
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class ParamCapability implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.os.Bundle getCapabilities();
@@ -27136,6 +27231,32 @@ package android.media.quality {
method @NonNull public android.media.quality.PictureProfile.Builder setParameters(@NonNull android.os.PersistableBundle);
}
+ @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class SoundProfile implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getInputId();
+ method @NonNull public String getName();
+ method @Nullable public String getPackageName();
+ method @NonNull public android.os.PersistableBundle getParameters();
+ method @Nullable public String getProfileId();
+ method public int getProfileType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.SoundProfile> CREATOR;
+ field public static final int ERROR_DUPLICATE = 2; // 0x2
+ field public static final int ERROR_INVALID_ARGUMENT = 3; // 0x3
+ field public static final int ERROR_NOT_ALLOWLISTED = 4; // 0x4
+ field public static final int ERROR_NO_PERMISSION = 1; // 0x1
+ field public static final int ERROR_UNKNOWN = 0; // 0x0
+ field public static final int TYPE_APPLICATION = 2; // 0x2
+ field public static final int TYPE_SYSTEM = 1; // 0x1
+ }
+
+ public static final class SoundProfile.Builder {
+ ctor public SoundProfile.Builder(@NonNull String);
+ ctor public SoundProfile.Builder(@NonNull android.media.quality.SoundProfile);
+ method @NonNull public android.media.quality.SoundProfile build();
+ method @NonNull public android.media.quality.SoundProfile.Builder setParameters(@NonNull android.os.PersistableBundle);
+ }
+
}
package android.media.session {
@@ -33809,7 +33930,7 @@ package android.os {
}
public interface IBinder {
- method @FlaggedApi("android.os.binder_frozen_state_change_callback") public default void addFrozenStateChangeCallback(@NonNull android.os.IBinder.FrozenStateChangeCallback) throws android.os.RemoteException;
+ method @FlaggedApi("android.os.binder_frozen_state_change_callback") public default void addFrozenStateChangeCallback(@NonNull java.util.concurrent.Executor, @NonNull android.os.IBinder.FrozenStateChangeCallback) throws android.os.RemoteException;
method public void dump(@NonNull java.io.FileDescriptor, @Nullable String[]) throws android.os.RemoteException;
method public void dumpAsync(@NonNull java.io.FileDescriptor, @Nullable String[]) throws android.os.RemoteException;
method @Nullable public String getInterfaceDescriptor() throws android.os.RemoteException;
@@ -34440,6 +34561,7 @@ package android.os {
method public void finishBroadcast();
method public Object getBroadcastCookie(int);
method public E getBroadcastItem(int);
+ method @FlaggedApi("android.os.binder_frozen_state_change_callback") @Nullable public java.util.concurrent.Executor getExecutor();
method @FlaggedApi("android.os.binder_frozen_state_change_callback") public int getFrozenCalleePolicy();
method @FlaggedApi("android.os.binder_frozen_state_change_callback") public int getMaxQueueSize();
method public Object getRegisteredCallbackCookie(int);
@@ -34460,6 +34582,7 @@ package android.os {
@FlaggedApi("android.os.binder_frozen_state_change_callback") public static final class RemoteCallbackList.Builder<E extends android.os.IInterface> {
ctor public RemoteCallbackList.Builder(int);
method @NonNull public android.os.RemoteCallbackList<E> build();
+ method @NonNull public android.os.RemoteCallbackList.Builder setExecutor(@NonNull java.util.concurrent.Executor);
method @NonNull public android.os.RemoteCallbackList.Builder setInterfaceDiedCallback(@NonNull android.os.RemoteCallbackList.Builder.InterfaceDiedCallback<E>);
method @NonNull public android.os.RemoteCallbackList.Builder setMaxQueueSize(int);
}
@@ -34847,6 +34970,13 @@ package android.os {
field public static final int EFFECT_TICK = 2; // 0x2
}
+ @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public static final class VibrationEffect.BasicEnvelopeBuilder {
+ ctor public VibrationEffect.BasicEnvelopeBuilder();
+ method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.BasicEnvelopeBuilder addControlPoint(@FloatRange(from=0, to=1) float, @FloatRange(from=0, to=1) float, long);
+ method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect build();
+ method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.BasicEnvelopeBuilder setInitialSharpness(@FloatRange(from=0, to=1) float);
+ }
+
public static final class VibrationEffect.Composition {
method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int);
method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float);
@@ -34867,7 +34997,7 @@ package android.os {
@FlaggedApi("android.os.vibrator.normalized_pwle_effects") public static final class VibrationEffect.WaveformEnvelopeBuilder {
ctor public VibrationEffect.WaveformEnvelopeBuilder();
- method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.WaveformEnvelopeBuilder addControlPoint(@FloatRange(from=0, to=1) float, @FloatRange(from=0) float, int);
+ method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.WaveformEnvelopeBuilder addControlPoint(@FloatRange(from=0, to=1) float, @FloatRange(from=0) float, long);
method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect build();
method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.VibrationEffect.WaveformEnvelopeBuilder setInitialFrequencyHz(@FloatRange(from=0) float);
}
@@ -37571,7 +37701,6 @@ package android.provider {
}
@FlaggedApi("android.provider.new_default_account_api_enabled") public static final class ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState {
- ctor public ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState(int, @Nullable android.accounts.Account);
method @Nullable public android.accounts.Account getAccount();
method public int getState();
method @NonNull public static android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState ofCloud(@NonNull android.accounts.Account);
@@ -41179,6 +41308,18 @@ package android.service.carrier {
method @Deprecated public void onSendTextSms(@NonNull String, int, @NonNull String, @NonNull android.service.carrier.CarrierMessagingService.ResultCallback<android.service.carrier.CarrierMessagingService.SendSmsResult>);
method public void onSendTextSms(@NonNull String, int, @NonNull String, int, @NonNull android.service.carrier.CarrierMessagingService.ResultCallback<android.service.carrier.CarrierMessagingService.SendSmsResult>);
field public static final int DOWNLOAD_STATUS_ERROR = 2; // 0x2
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_CONFIGURATION_ERROR = 606; // 0x25e
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_DATA_DISABLED = 610; // 0x262
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_HTTP_FAILURE = 603; // 0x25b
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_INACTIVE_SUBSCRIPTION = 609; // 0x261
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_INVALID_APN = 601; // 0x259
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_INVALID_SUBSCRIPTION_ID = 608; // 0x260
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_IO_ERROR = 604; // 0x25c
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_MMS_DISABLED_BY_CARRIER = 611; // 0x263
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_NO_DATA_NETWORK = 607; // 0x25f
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_RETRY = 605; // 0x25d
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS = 602; // 0x25a
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int DOWNLOAD_STATUS_MMS_ERROR_UNSPECIFIED = 600; // 0x258
field public static final int DOWNLOAD_STATUS_OK = 0; // 0x0
field public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
field public static final int RECEIVE_OPTIONS_DEFAULT = 0; // 0x0
@@ -41186,7 +41327,38 @@ package android.service.carrier {
field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 2; // 0x2
field public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1; // 0x1
field public static final int SEND_STATUS_ERROR = 2; // 0x2
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_CONFIGURATION_ERROR = 406; // 0x196
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_DATA_DISABLED = 410; // 0x19a
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_HTTP_FAILURE = 403; // 0x193
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_INACTIVE_SUBSCRIPTION = 409; // 0x199
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_INVALID_APN = 401; // 0x191
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_INVALID_SUBSCRIPTION_ID = 408; // 0x198
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_IO_ERROR = 404; // 0x194
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_MMS_DISABLED_BY_CARRIER = 411; // 0x19b
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_NO_DATA_NETWORK = 407; // 0x197
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_RETRY = 405; // 0x195
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS = 402; // 0x192
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_MMS_ERROR_UNSPECIFIED = 400; // 0x190
field public static final int SEND_STATUS_OK = 0; // 0x0
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_CANCELLED = 215; // 0xd7
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ENCODING_ERROR = 212; // 0xd4
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE = 204; // 0xcc
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE = 200; // 0xc8
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED = 203; // 0xcb
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_NO_SERVICE = 202; // 0xca
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_NULL_PDU = 201; // 0xc9
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 206; // 0xce
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 205; // 0xcd
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_INVALID_ARGUMENTS = 208; // 0xd0
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS = 213; // 0xd5
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_INVALID_SMS_FORMAT = 210; // 0xd2
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_INVALID_STATE = 209; // 0xd1
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_NETWORK_ERROR = 211; // 0xd3
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_NETWORK_REJECT = 207; // 0xcf
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED = 214; // 0xd6
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED = 216; // 0xd8
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY = 217; // 0xd9
+ field @FlaggedApi("com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service") public static final int SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED = 218; // 0xda
field public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
field public static final String SERVICE_INTERFACE = "android.service.carrier.CarrierMessagingService";
}
@@ -42410,7 +42582,7 @@ package android.service.settings.preferences {
method @NonNull public java.util.List<java.lang.String> getBreadcrumbs();
method @NonNull public android.os.Bundle getExtras();
method @NonNull public String getKey();
- method @Nullable public android.app.PendingIntent getLaunchIntent();
+ method @Nullable public android.content.Intent getLaunchIntent();
method @NonNull public java.util.List<java.lang.String> getReadPermissions();
method @NonNull public String getScreenKey();
method @Nullable public String getSummary();
@@ -42435,7 +42607,7 @@ package android.service.settings.preferences {
method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setBreadcrumbs(@NonNull java.util.List<java.lang.String>);
method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setEnabled(boolean);
method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setExtras(@NonNull android.os.Bundle);
- method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setLaunchIntent(@Nullable android.app.PendingIntent);
+ method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setLaunchIntent(@Nullable android.content.Intent);
method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setReadPermissions(@NonNull java.util.List<java.lang.String>);
method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setRestricted(boolean);
method @NonNull public android.service.settings.preferences.SettingsPreferenceMetadata.Builder setSummary(@Nullable String);
@@ -42455,19 +42627,18 @@ package android.service.settings.preferences {
}
@FlaggedApi("com.android.settingslib.flags.settings_catalyst") public class SettingsPreferenceServiceClient implements java.lang.AutoCloseable {
- ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String);
+ ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.SettingsPreferenceServiceClient,java.lang.Exception>);
method public void close();
method public void getAllPreferenceMetadata(@NonNull android.service.settings.preferences.MetadataRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.MetadataResult,java.lang.Exception>);
method public void getPreferenceValue(@NonNull android.service.settings.preferences.GetValueRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.GetValueResult,java.lang.Exception>);
method public void setPreferenceValue(@NonNull android.service.settings.preferences.SetValueRequest, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.SetValueResult,java.lang.Exception>);
- method public void start();
- method public void stop();
}
@FlaggedApi("com.android.settingslib.flags.settings_catalyst") public final class SettingsPreferenceValue implements android.os.Parcelable {
method public int describeContents();
method public boolean getBooleanValue();
method public double getDoubleValue();
+ method public int getIntValue();
method public long getLongValue();
method @Nullable public String getStringValue();
method public int getType();
@@ -42475,6 +42646,7 @@ package android.service.settings.preferences {
field @NonNull public static final android.os.Parcelable.Creator<android.service.settings.preferences.SettingsPreferenceValue> CREATOR;
field public static final int TYPE_BOOLEAN = 0; // 0x0
field public static final int TYPE_DOUBLE = 2; // 0x2
+ field public static final int TYPE_INT = 4; // 0x4
field public static final int TYPE_LONG = 1; // 0x1
field public static final int TYPE_STRING = 3; // 0x3
}
@@ -42484,6 +42656,7 @@ package android.service.settings.preferences {
method @NonNull public android.service.settings.preferences.SettingsPreferenceValue build();
method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setBooleanValue(boolean);
method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setDoubleValue(double);
+ method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setIntValue(int);
method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setLongValue(long);
method @NonNull public android.service.settings.preferences.SettingsPreferenceValue.Builder setStringValue(@Nullable String);
}
@@ -50267,9 +50440,9 @@ package android.text.style {
public static class TtsSpan.TimeBuilder extends android.text.style.TtsSpan.SemioticClassBuilder<android.text.style.TtsSpan.TimeBuilder> {
ctor public TtsSpan.TimeBuilder();
ctor public TtsSpan.TimeBuilder(int, int);
- method public android.text.style.TtsSpan.TimeBuilder setHours(int);
- method public android.text.style.TtsSpan.TimeBuilder setMinutes(int);
- method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.TimeBuilder setSeconds(int);
+ method public android.text.style.TtsSpan.TimeBuilder setHours(@IntRange(from=0, to=24) int);
+ method public android.text.style.TtsSpan.TimeBuilder setMinutes(@IntRange(from=0, to=59) int);
+ method @FlaggedApi("com.android.text.flags.tts_span_duration") @NonNull public android.text.style.TtsSpan.TimeBuilder setSeconds(@IntRange(from=0, to=59) int);
}
public static class TtsSpan.VerbatimBuilder extends android.text.style.TtsSpan.SemioticClassBuilder<android.text.style.TtsSpan.VerbatimBuilder> {
@@ -53361,6 +53534,7 @@ package android.view {
method @NonNull public android.view.SurfaceControl.Transaction setBuffer(@NonNull android.view.SurfaceControl, @Nullable android.hardware.HardwareBuffer, @Nullable android.hardware.SyncFence, @Nullable java.util.function.Consumer<android.hardware.SyncFence>);
method @NonNull public android.view.SurfaceControl.Transaction setBufferSize(@NonNull android.view.SurfaceControl, @IntRange(from=0) int, @IntRange(from=0) int);
method @NonNull public android.view.SurfaceControl.Transaction setBufferTransform(@NonNull android.view.SurfaceControl, int);
+ method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") @NonNull public android.view.SurfaceControl.Transaction setContentPriority(@NonNull android.view.SurfaceControl, int);
method @NonNull public android.view.SurfaceControl.Transaction setCrop(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect);
method @NonNull public android.view.SurfaceControl.Transaction setDamageRegion(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Region);
method @NonNull public android.view.SurfaceControl.Transaction setDataSpace(@NonNull android.view.SurfaceControl, int);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index bc0037d9318f..e225bb4199e3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -66,10 +66,10 @@ package android {
field @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") public static final String BIND_EXPLICIT_HEALTH_CHECK_SERVICE = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
field public static final String BIND_EXTERNAL_STORAGE_SERVICE = "android.permission.BIND_EXTERNAL_STORAGE_SERVICE";
field public static final String BIND_FIELD_CLASSIFICATION_SERVICE = "android.permission.BIND_FIELD_CLASSIFICATION_SERVICE";
- field @FlaggedApi("android.security.afl_api") public static final String BIND_FORENSIC_EVENT_TRANSPORT_SERVICE = "android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE";
field public static final String BIND_GBA_SERVICE = "android.permission.BIND_GBA_SERVICE";
field public static final String BIND_HOTWORD_DETECTION_SERVICE = "android.permission.BIND_HOTWORD_DETECTION_SERVICE";
field public static final String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
+ field @FlaggedApi("android.security.afl_api") public static final String BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE = "android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE";
field public static final String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final String BIND_MUSIC_RECOGNITION_SERVICE = "android.permission.BIND_MUSIC_RECOGNITION_SERVICE";
field public static final String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
@@ -94,7 +94,6 @@ package android {
field public static final String BIND_TRANSLATION_SERVICE = "android.permission.BIND_TRANSLATION_SERVICE";
field public static final String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
- field @FlaggedApi("android.content.pm.verification_service") public static final String BIND_VERIFICATION_AGENT = "android.permission.BIND_VERIFICATION_AGENT";
field public static final String BIND_VISUAL_QUERY_DETECTION_SERVICE = "android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE";
field public static final String BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE = "android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE";
field public static final String BIND_WEARABLE_SENSING_SERVICE = "android.permission.BIND_WEARABLE_SENSING_SERVICE";
@@ -103,6 +102,7 @@ package android {
field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
field public static final String BROADCAST_CLOSE_SYSTEM_DIALOGS = "android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS";
field @Deprecated public static final String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
+ field @FlaggedApi("android.media.audio.concurrent_audio_record_bypass_permission") public static final String BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION = "android.permission.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION";
field public static final String BYPASS_ROLE_QUALIFICATION = "android.permission.BYPASS_ROLE_QUALIFICATION";
field public static final String CALL_AUDIO_INTERCEPTION = "android.permission.CALL_AUDIO_INTERCEPTION";
field public static final String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
@@ -134,6 +134,7 @@ package android {
field public static final String CONTROL_KEYGUARD_SECURE_NOTIFICATIONS = "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS";
field public static final String CONTROL_OEM_PAID_NETWORK_PREFERENCE = "android.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE";
field public static final String CONTROL_VPN = "android.permission.CONTROL_VPN";
+ field @FlaggedApi("android.app.admin.flags.split_create_managed_profile_enabled") public static final String COPY_ACCOUNTS = "android.permission.COPY_ACCOUNTS";
field public static final String CREATE_USERS = "android.permission.CREATE_USERS";
field public static final String CREATE_VIRTUAL_DEVICE = "android.permission.CREATE_VIRTUAL_DEVICE";
field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
@@ -192,6 +193,7 @@ package android {
field public static final String MANAGE_ACCESSIBILITY = "android.permission.MANAGE_ACCESSIBILITY";
field @Deprecated public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
field public static final String MANAGE_ACTIVITY_TASKS = "android.permission.MANAGE_ACTIVITY_TASKS";
+ field @FlaggedApi("android.security.aapm_api") public static final String MANAGE_ADVANCED_PROTECTION_MODE = "android.permission.MANAGE_ADVANCED_PROTECTION_MODE";
field public static final String MANAGE_APP_HIBERNATION = "android.permission.MANAGE_APP_HIBERNATION";
field public static final String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS";
field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS";
@@ -212,12 +214,12 @@ package android {
field @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public static final String MANAGE_ENHANCED_CONFIRMATION_STATES = "android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES";
field public static final String MANAGE_ETHERNET_NETWORKS = "android.permission.MANAGE_ETHERNET_NETWORKS";
field public static final String MANAGE_FACTORY_RESET_PROTECTION = "android.permission.MANAGE_FACTORY_RESET_PROTECTION";
- field @FlaggedApi("android.security.afl_api") public static final String MANAGE_FORENSIC_STATE = "android.permission.MANAGE_FORENSIC_STATE";
field public static final String MANAGE_GAME_ACTIVITY = "android.permission.MANAGE_GAME_ACTIVITY";
field public static final String MANAGE_GAME_MODE = "android.permission.MANAGE_GAME_MODE";
field @FlaggedApi("android.media.tv.flags.media_quality_fw") public static final String MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE = "android.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE";
field @FlaggedApi("android.media.tv.flags.media_quality_fw") public static final String MANAGE_GLOBAL_SOUND_QUALITY_SERVICE = "android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE";
field public static final String MANAGE_HOTWORD_DETECTION = "android.permission.MANAGE_HOTWORD_DETECTION";
+ field @FlaggedApi("android.security.afl_api") public static final String MANAGE_INTRUSION_DETECTION_STATE = "android.permission.MANAGE_INTRUSION_DETECTION_STATE";
field public static final String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS";
field public static final String MANAGE_LOW_POWER_STANDBY = "android.permission.MANAGE_LOW_POWER_STANDBY";
field public static final String MANAGE_MUSIC_RECOGNITION = "android.permission.MANAGE_MUSIC_RECOGNITION";
@@ -229,6 +231,7 @@ package android {
field public static final String MANAGE_ROTATION_RESOLVER = "android.permission.MANAGE_ROTATION_RESOLVER";
field public static final String MANAGE_SAFETY_CENTER = "android.permission.MANAGE_SAFETY_CENTER";
field public static final String MANAGE_SEARCH_UI = "android.permission.MANAGE_SEARCH_UI";
+ field @FlaggedApi("android.security.secure_lockdown") public static final String MANAGE_SECURE_LOCK_DEVICE = "android.permission.MANAGE_SECURE_LOCK_DEVICE";
field public static final String MANAGE_SENSOR_PRIVACY = "android.permission.MANAGE_SENSOR_PRIVACY";
field public static final String MANAGE_SMARTSPACE = "android.permission.MANAGE_SMARTSPACE";
field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
@@ -308,10 +311,10 @@ package android {
field public static final String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
field public static final String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG";
field public static final String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
- field @FlaggedApi("android.security.afl_api") public static final String READ_FORENSIC_STATE = "android.permission.READ_FORENSIC_STATE";
field public static final String READ_GLOBAL_APP_SEARCH_DATA = "android.permission.READ_GLOBAL_APP_SEARCH_DATA";
field @FlaggedApi("android.content.pm.get_resolved_apk_path") public static final String READ_INSTALLED_SESSION_PATHS = "android.permission.READ_INSTALLED_SESSION_PATHS";
field public static final String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS";
+ field @FlaggedApi("android.security.afl_api") public static final String READ_INTRUSION_DETECTION_STATE = "android.permission.READ_INTRUSION_DETECTION_STATE";
field public static final String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
field public static final String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
field public static final String READ_PEOPLE_DATA = "android.permission.READ_PEOPLE_DATA";
@@ -345,6 +348,7 @@ package android {
field public static final String REGISTER_SIM_SUBSCRIPTION = "android.permission.REGISTER_SIM_SUBSCRIPTION";
field public static final String REGISTER_STATS_PULL_ATOM = "android.permission.REGISTER_STATS_PULL_ATOM";
field public static final String REMOTE_DISPLAY_PROVIDER = "android.permission.REMOTE_DISPLAY_PROVIDER";
+ field @FlaggedApi("android.app.admin.flags.split_create_managed_profile_enabled") public static final String REMOVE_ACCOUNTS = "android.permission.REMOVE_ACCOUNTS";
field public static final String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES";
field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
field public static final String RENOUNCE_PERMISSIONS = "android.permission.RENOUNCE_PERMISSIONS";
@@ -372,7 +376,6 @@ package android {
field public static final String SERIAL_PORT = "android.permission.SERIAL_PORT";
field @FlaggedApi("android.security.fsverity_api") public static final String SETUP_FSVERITY = "android.permission.SETUP_FSVERITY";
field public static final String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";
- field @FlaggedApi("android.security.aapm_api") public static final String SET_ADVANCED_PROTECTION_MODE = "android.permission.SET_ADVANCED_PROTECTION_MODE";
field public static final String SET_CLIP_SOURCE = "android.permission.SET_CLIP_SOURCE";
field public static final String SET_DEFAULT_ACCOUNT_FOR_CONTACTS = "android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS";
field public static final String SET_HARMFUL_APP_WARNINGS = "android.permission.SET_HARMFUL_APP_WARNINGS";
@@ -426,7 +429,6 @@ package android {
field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public static final String USE_ON_DEVICE_INTELLIGENCE = "android.permission.USE_ON_DEVICE_INTELLIGENCE";
field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
field public static final String UWB_PRIVILEGED = "android.permission.UWB_PRIVILEGED";
- field @FlaggedApi("android.content.pm.verification_service") public static final String VERIFICATION_AGENT = "android.permission.VERIFICATION_AGENT";
field @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public static final String VIBRATE_VENDOR_EFFECTS = "android.permission.VIBRATE_VENDOR_EFFECTS";
field public static final String WHITELIST_AUTO_REVOKE_PERMISSIONS = "android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS";
field public static final String WHITELIST_RESTRICTED_PERMISSIONS = "android.permission.WHITELIST_RESTRICTED_PERMISSIONS";
@@ -570,6 +572,7 @@ package android.accessibilityservice {
package android.accounts {
public class AccountManager {
+ method @FlaggedApi("android.app.admin.flags.split_create_managed_profile_enabled") @NonNull @RequiresPermission(anyOf={android.Manifest.permission.COPY_ACCOUNTS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public android.accounts.AccountManagerFuture<java.lang.Boolean> copyAccountToUser(@NonNull android.accounts.Account, @NonNull android.os.UserHandle, @NonNull android.os.UserHandle, @Nullable android.accounts.AccountManagerCallback<java.lang.Boolean>, @Nullable android.os.Handler);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
}
@@ -2319,6 +2322,24 @@ package android.app.ondeviceintelligence {
field public static final int FEATURE_STATUS_UNAVAILABLE = 0; // 0x0
}
+ @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") public final class InferenceInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getEndTimeMillis();
+ method public long getStartTimeMillis();
+ method public long getSuspendedTimeMillis();
+ method public int getUid();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.ondeviceintelligence.InferenceInfo> CREATOR;
+ }
+
+ public static final class InferenceInfo.Builder {
+ ctor public InferenceInfo.Builder(int);
+ method @NonNull public android.app.ondeviceintelligence.InferenceInfo build();
+ method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setEndTimeMillis(long);
+ method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setStartTimeMillis(long);
+ method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setSuspendedTimeMillis(long);
+ }
+
@FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public class OnDeviceIntelligenceException extends java.lang.Exception {
ctor public OnDeviceIntelligenceException(int, @NonNull String, @NonNull android.os.PersistableBundle);
ctor public OnDeviceIntelligenceException(int, @NonNull android.os.PersistableBundle);
@@ -2348,6 +2369,7 @@ package android.app.ondeviceintelligence {
@FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class OnDeviceIntelligenceManager {
method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getFeature(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.app.ondeviceintelligence.Feature,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getFeatureDetails(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.app.ondeviceintelligence.FeatureDetails,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
+ method @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") @NonNull @RequiresPermission(android.Manifest.permission.DUMP) public java.util.List<android.app.ondeviceintelligence.InferenceInfo> getLatestInferenceInfo(long);
method @Nullable @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public String getRemoteServicePackageName();
method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getVersion(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.LongConsumer);
method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void listFeatures(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.util.List<android.app.ondeviceintelligence.Feature>,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
@@ -3413,14 +3435,14 @@ package android.app.wearable {
public class WearableSensingManager {
method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public int getAvailableConnectionCount();
method @Nullable public static android.app.wearable.WearableSensingDataRequest getDataRequestFromIntent(@NonNull android.content.Intent);
- method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideConnection(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @Deprecated @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideConnection(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideConnection(@NonNull android.app.wearable.WearableConnection, @NonNull java.util.concurrent.Executor);
method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideData(@NonNull android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideDataStream(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("android.app.wearable.enable_provide_read_only_pfd") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void provideReadOnlyParcelFileDescriptor(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void registerDataRequestObserver(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void removeAllConnections();
- method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public boolean removeConnection(@NonNull android.app.wearable.WearableConnection);
+ method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void removeConnection(@NonNull android.app.wearable.WearableConnection);
method @FlaggedApi("android.app.wearable.enable_hotword_wearable_sensing_api") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void startHotwordRecognition(@Nullable android.content.ComponentName, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("android.app.wearable.enable_hotword_wearable_sensing_api") @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void stopHotwordRecognition(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE) public void unregisterDataRequestObserver(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -3869,6 +3891,7 @@ package android.content {
field public static final String APP_INTEGRITY_SERVICE = "app_integrity";
field public static final String APP_PREDICTION_SERVICE = "app_prediction";
field public static final String AUDIO_DEVICE_VOLUME_SERVICE = "audio_device_volume";
+ field @FlaggedApi("android.security.secure_lockdown") public static final String AUTHENTICATION_POLICY_SERVICE = "authentication_policy";
field public static final String BACKUP_SERVICE = "backup";
field public static final String BATTERY_STATS_SERVICE = "batterystats";
field public static final int BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS = 1048576; // 0x100000
@@ -4221,11 +4244,9 @@ package android.content.pm {
}
public class PackageInstaller {
- method @FlaggedApi("android.content.pm.verification_service") @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public final int getVerificationPolicy();
method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
method @FlaggedApi("android.content.pm.read_install_info") @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
- method @FlaggedApi("android.content.pm.verification_service") @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT) public final boolean setVerificationPolicy(int);
field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
@@ -4236,20 +4257,12 @@ package android.content.pm {
field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_DELETE_FLAGS = "android.content.pm.extra.DELETE_FLAGS";
field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
- field @FlaggedApi("android.content.pm.verification_service") public static final String EXTRA_VERIFICATION_FAILURE_REASON = "android.content.pm.extra.VERIFICATION_FAILURE_REASON";
field public static final int LOCATION_DATA_APP = 0; // 0x0
field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
field public static final int REASON_CONFIRM_PACKAGE_CHANGE = 0; // 0x0
field public static final int REASON_OWNERSHIP_CHANGED = 1; // 0x1
field public static final int REASON_REMIND_OWNERSHIP = 2; // 0x2
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE = 1; // 0x1
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED = 2; // 0x2
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_FAILED_REASON_UNKNOWN = 0; // 0x0
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_BLOCK_FAIL_CLOSED = 3; // 0x3
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_BLOCK_FAIL_OPEN = 1; // 0x1
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_BLOCK_FAIL_WARN = 2; // 0x2
- field @FlaggedApi("android.content.pm.verification_service") public static final int VERIFICATION_POLICY_NONE = 0; // 0x0
}
public static class PackageInstaller.InstallInfo {
@@ -4369,7 +4382,6 @@ package android.content.pm {
method @Deprecated @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>);
field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
field public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER";
- field @FlaggedApi("android.content.pm.verification_service") public static final String ACTION_VERIFY_PACKAGE = "android.content.pm.action.VERIFY_PACKAGE";
field @FlaggedApi("android.content.pm.asl_in_apk_app_metadata_source") public static final int APP_METADATA_SOURCE_APK = 1; // 0x1
field @FlaggedApi("android.content.pm.asl_in_apk_app_metadata_source") public static final int APP_METADATA_SOURCE_INSTALLER = 2; // 0x2
field @FlaggedApi("android.content.pm.asl_in_apk_app_metadata_source") public static final int APP_METADATA_SOURCE_SYSTEM_IMAGE = 3; // 0x3
@@ -4701,62 +4713,6 @@ package android.content.pm.verify.domain {
}
-package android.content.pm.verify.pkg {
-
- @FlaggedApi("android.content.pm.verification_service") public final class VerificationSession implements android.os.Parcelable {
- method public int describeContents();
- method public long extendTimeRemaining(long);
- method @NonNull public java.util.List<android.content.pm.SharedLibraryInfo> getDeclaredLibraries();
- method @NonNull public android.os.PersistableBundle getExtensionParams();
- method public int getId();
- method public int getInstallSessionId();
- method @NonNull public String getPackageName();
- method @NonNull public android.content.pm.SigningInfo getSigningInfo();
- method @NonNull public android.net.Uri getStagedPackageUri();
- method public long getTimeoutTime();
- method public int getVerificationPolicy();
- method public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus);
- method public void reportVerificationComplete(@NonNull android.content.pm.verify.pkg.VerificationStatus, @NonNull android.os.PersistableBundle);
- method public void reportVerificationIncomplete(int);
- method public boolean setVerificationPolicy(int);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.pkg.VerificationSession> CREATOR;
- field public static final int VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE = 1; // 0x1
- field public static final int VERIFICATION_INCOMPLETE_UNKNOWN = 0; // 0x0
- }
-
- @FlaggedApi("android.content.pm.verification_service") public final class VerificationStatus implements android.os.Parcelable {
- method public int describeContents();
- method public int getAslStatus();
- method @NonNull public String getFailureMessage();
- method public boolean isVerified();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.pkg.VerificationStatus> CREATOR;
- field public static final int VERIFIER_STATUS_ASL_BAD = 2; // 0x2
- field public static final int VERIFIER_STATUS_ASL_GOOD = 1; // 0x1
- field public static final int VERIFIER_STATUS_ASL_UNDEFINED = 0; // 0x0
- }
-
- public static final class VerificationStatus.Builder {
- ctor public VerificationStatus.Builder();
- method @NonNull public android.content.pm.verify.pkg.VerificationStatus build();
- method @NonNull public android.content.pm.verify.pkg.VerificationStatus.Builder setAslStatus(int);
- method @NonNull public android.content.pm.verify.pkg.VerificationStatus.Builder setFailureMessage(@NonNull String);
- method @NonNull public android.content.pm.verify.pkg.VerificationStatus.Builder setVerified(boolean);
- }
-
- @FlaggedApi("android.content.pm.verification_service") public abstract class VerifierService extends android.app.Service {
- ctor public VerifierService();
- method @Nullable public android.os.IBinder onBind(@Nullable android.content.Intent);
- method public abstract void onPackageNameAvailable(@NonNull String);
- method public abstract void onVerificationCancelled(@NonNull String);
- method public abstract void onVerificationRequired(@NonNull android.content.pm.verify.pkg.VerificationSession);
- method public abstract void onVerificationRetry(@NonNull android.content.pm.verify.pkg.VerificationSession);
- method public abstract void onVerificationTimeout(int);
- }
-
-}
-
package android.content.rollback {
public final class PackageRollbackInfo implements android.os.Parcelable {
@@ -8154,8 +8110,13 @@ package android.media.quality {
method @NonNull public java.util.List<java.lang.String> getPictureProfileAllowList();
method @NonNull public java.util.List<java.lang.String> getPictureProfilePackageNames();
method @NonNull public java.util.List<android.media.quality.PictureProfile> getPictureProfilesByPackage(@NonNull String);
+ method @NonNull public java.util.List<java.lang.String> getSoundProfileAllowList();
+ method @NonNull public java.util.List<java.lang.String> getSoundProfilePackageNames();
+ method @NonNull public java.util.List<android.media.quality.SoundProfile> getSoundProfilesByPackage(@NonNull String);
method public void setAutoPictureQualityEnabled(boolean);
+ method public void setAutoSoundQualityEnabled(boolean);
method public void setPictureProfileAllowList(@NonNull java.util.List<java.lang.String>);
+ method public void setSoundProfileAllowList(@NonNull java.util.List<java.lang.String>);
method public void setSuperResolutionEnabled(boolean);
}
@@ -8165,6 +8126,20 @@ package android.media.quality {
method @NonNull public android.media.quality.PictureProfile.Builder setProfileType(int);
}
+ @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public final class PictureProfileHandle implements android.os.Parcelable {
+ method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public int describeContents();
+ method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public long getId();
+ method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") @NonNull public static final android.os.Parcelable.Creator<android.media.quality.PictureProfileHandle> CREATOR;
+ field @NonNull public static final android.media.quality.PictureProfileHandle NONE;
+ }
+
+ public static final class SoundProfile.Builder {
+ method @NonNull public android.media.quality.SoundProfile.Builder setInputId(@NonNull String);
+ method @NonNull public android.media.quality.SoundProfile.Builder setPackageName(@NonNull String);
+ method @NonNull public android.media.quality.SoundProfile.Builder setProfileType(int);
+ }
+
}
package android.media.session {
@@ -9893,7 +9868,7 @@ package android.media.tv.tuner.frontend {
method public int getSignalStrength();
method public int getSnr();
method public int getSpectralInversion();
- method @FlaggedApi("android.media.tv.flags.tuner_w_apis") @NonNull public android.media.tv.tuner.frontend.StandardExt getStandardExt();
+ method @FlaggedApi("android.media.tv.flags.tuner_w_apis") @NonNull public android.media.tv.tuner.frontend.StandardExtension getStandardExtension();
method @NonNull public int[] getStreamIds();
method public int getSymbolRate();
method @IntRange(from=0, to=65535) public int getSystemId();
@@ -9948,7 +9923,7 @@ package android.media.tv.tuner.frontend {
field public static final int FRONTEND_STATUS_TYPE_SIGNAL_STRENGTH = 6; // 0x6
field public static final int FRONTEND_STATUS_TYPE_SNR = 1; // 0x1
field public static final int FRONTEND_STATUS_TYPE_SPECTRAL = 10; // 0xa
- field @FlaggedApi("android.media.tv.flags.tuner_w_apis") public static final int FRONTEND_STATUS_TYPE_STANDARD_EXT = 47; // 0x2f
+ field @FlaggedApi("android.media.tv.flags.tuner_w_apis") public static final int FRONTEND_STATUS_TYPE_STANDARD_EXTENSION = 47; // 0x2f
field public static final int FRONTEND_STATUS_TYPE_STREAM_IDS = 39; // 0x27
field public static final int FRONTEND_STATUS_TYPE_SYMBOL_RATE = 7; // 0x7
field public static final int FRONTEND_STATUS_TYPE_T2_SYSTEM_ID = 29; // 0x1d
@@ -10240,9 +10215,9 @@ package android.media.tv.tuner.frontend {
method public default void onUnlocked();
}
- @FlaggedApi("android.media.tv.flags.tuner_w_apis") public final class StandardExt {
- method public int getDvbsStandardExt();
- method public int getDvbtStandardExt();
+ @FlaggedApi("android.media.tv.flags.tuner_w_apis") public final class StandardExtension {
+ method public int getDvbsStandardExtension();
+ method public int getDvbtStandardExtension();
}
}
@@ -12842,8 +12817,8 @@ package android.security.advancedprotection {
@FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionManager {
method @NonNull public android.content.Intent createSupportIntent(@NonNull String, @Nullable String);
- method @NonNull @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures();
- method @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures();
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean);
field @FlaggedApi("android.security.aapm_api") public static final String ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG = "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG";
field public static final String EXTRA_SUPPORT_DIALOG_FEATURE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE";
field public static final String EXTRA_SUPPORT_DIALOG_TYPE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_TYPE";
@@ -12858,13 +12833,43 @@ package android.security.advancedprotection {
}
-package android.security.forensic {
+package android.security.authenticationpolicy {
+
+ @FlaggedApi("android.security.secure_lockdown") public final class AuthenticationPolicyManager {
+ method @FlaggedApi("android.security.secure_lockdown") @RequiresPermission(android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE) public int disableSecureLockDevice(@NonNull android.security.authenticationpolicy.DisableSecureLockDeviceParams);
+ method @FlaggedApi("android.security.secure_lockdown") @RequiresPermission(android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE) public int enableSecureLockDevice(@NonNull android.security.authenticationpolicy.EnableSecureLockDeviceParams);
+ field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_ALREADY_ENABLED = 6; // 0x6
+ field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_INSUFFICIENT_BIOMETRICS = 5; // 0x5
+ field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_INVALID_PARAMS = 3; // 0x3
+ field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_NO_BIOMETRICS_ENROLLED = 4; // 0x4
+ field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_UNKNOWN = 0; // 0x0
+ field @FlaggedApi("android.security.secure_lockdown") public static final int ERROR_UNSUPPORTED = 2; // 0x2
+ field @FlaggedApi("android.security.secure_lockdown") public static final int SUCCESS = 1; // 0x1
+ }
- @FlaggedApi("android.security.afl_api") public class ForensicManager {
- method @RequiresPermission(android.Manifest.permission.READ_FORENSIC_STATE) public void addStateCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @RequiresPermission(android.Manifest.permission.MANAGE_FORENSIC_STATE) public void disable(@NonNull java.util.concurrent.Executor, @NonNull android.security.forensic.ForensicManager.CommandCallback);
- method @RequiresPermission(android.Manifest.permission.MANAGE_FORENSIC_STATE) public void enable(@NonNull java.util.concurrent.Executor, @NonNull android.security.forensic.ForensicManager.CommandCallback);
- method @RequiresPermission(android.Manifest.permission.READ_FORENSIC_STATE) public void removeStateCallback(@NonNull java.util.function.Consumer<java.lang.Integer>);
+ @FlaggedApi("android.security.secure_lockdown") public final class DisableSecureLockDeviceParams implements android.os.Parcelable {
+ ctor public DisableSecureLockDeviceParams(@NonNull String);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.DisableSecureLockDeviceParams> CREATOR;
+ }
+
+ @FlaggedApi("android.security.secure_lockdown") public final class EnableSecureLockDeviceParams implements android.os.Parcelable {
+ ctor public EnableSecureLockDeviceParams(@NonNull String);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.EnableSecureLockDeviceParams> CREATOR;
+ }
+
+}
+
+package android.security.intrusiondetection {
+
+ @FlaggedApi("android.security.afl_api") public class IntrusionDetectionManager {
+ method @RequiresPermission(android.Manifest.permission.READ_INTRUSION_DETECTION_STATE) public void addStateCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE) public void disable(@NonNull java.util.concurrent.Executor, @NonNull android.security.intrusiondetection.IntrusionDetectionManager.CommandCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE) public void enable(@NonNull java.util.concurrent.Executor, @NonNull android.security.intrusiondetection.IntrusionDetectionManager.CommandCallback);
+ method @RequiresPermission(android.Manifest.permission.READ_INTRUSION_DETECTION_STATE) public void removeStateCallback(@NonNull java.util.function.Consumer<java.lang.Integer>);
field public static final int ERROR_DATA_SOURCE_UNAVAILABLE = 4; // 0x4
field public static final int ERROR_PERMISSION_DENIED = 1; // 0x1
field public static final int ERROR_TRANSPORT_UNAVAILABLE = 3; // 0x3
@@ -12874,7 +12879,7 @@ package android.security.forensic {
field public static final int STATE_UNKNOWN = 0; // 0x0
}
- public static interface ForensicManager.CommandCallback {
+ public static interface IntrusionDetectionManager.CommandCallback {
method public void onFailure(int);
method public void onSuccess();
}
@@ -14546,7 +14551,7 @@ package android.service.wearable {
method @BinderThread public abstract void onDataStreamProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @BinderThread public abstract void onQueryServiceStatus(@NonNull java.util.Set<java.lang.Integer>, @NonNull String, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionServiceStatus>);
method @FlaggedApi("android.app.wearable.enable_provide_read_only_pfd") @BinderThread public void onReadOnlyParcelFileDescriptorProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.PersistableBundle, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @BinderThread public void onSecureConnectionProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @Deprecated @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @BinderThread public void onSecureConnectionProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @FlaggedApi("android.app.wearable.enable_concurrent_wearable_connections") @BinderThread public void onSecureConnectionProvided(@NonNull android.os.ParcelFileDescriptor, @NonNull android.os.PersistableBundle, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @BinderThread public abstract void onStartDetection(@NonNull android.app.ambientcontext.AmbientContextEventRequest, @NonNull String, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionServiceStatus>, @NonNull java.util.function.Consumer<android.service.ambientcontext.AmbientContextDetectionResult>);
method @FlaggedApi("android.app.wearable.enable_hotword_wearable_sensing_api") @BinderThread public void onStartHotwordRecognition(@NonNull java.util.function.Consumer<android.service.voice.HotwordAudioStream>, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -18963,6 +18968,10 @@ package android.util {
package android.view {
+ public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable {
+ method @FlaggedApi("android.media.tv.flags.apply_picture_profiles") @NonNull public android.view.SurfaceControl.Transaction setPictureProfileHandle(@NonNull android.view.SurfaceControl, @NonNull android.media.quality.PictureProfileHandle);
+ }
+
@UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
method @NonNull public final java.util.List<android.graphics.Rect> getUnrestrictedPreferKeepClearRects();
method @RequiresPermission(android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS) public final void setUnrestrictedPreferKeepClearRects(@NonNull java.util.List<android.graphics.Rect>);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 44bcc2a737b9..1a97f7beb7fa 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1805,6 +1805,7 @@ package android.hardware.input {
method @RequiresPermission(android.Manifest.permission.REMAP_MODIFIER_KEYS) public void remapModifierKey(int, int);
method @FlaggedApi("com.android.input.flags.device_associations") @RequiresPermission("android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY") public void removeUniqueIdAssociationByDescriptor(@NonNull String);
method @RequiresPermission("android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY") public void removeUniqueIdAssociationByPort(@NonNull String);
+ method public void resetLockedModifierState();
field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL
}
@@ -2492,6 +2493,7 @@ package android.os {
method public boolean areAutoPowerSaveModesEnabled();
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public void forceLowPowerStandbyActive(boolean);
method @FlaggedApi("android.os.battery_saver_supported_check_api") public boolean isBatterySaverSupported();
+ method public boolean isInteractive(int);
field public static final String ACTION_ENHANCED_DISCHARGE_PREDICTION_CHANGED = "android.os.action.ENHANCED_DISCHARGE_PREDICTION_CHANGED";
field @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public static final int SYSTEM_WAKELOCK = -2147483648; // 0x80000000
}
@@ -2781,6 +2783,17 @@ package android.os.storage {
package android.os.vibrator {
+ @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public final class BasicPwleSegment extends android.os.vibrator.VibrationEffectSegment {
+ method public int describeContents();
+ method public long getDuration();
+ method public float getEndIntensity();
+ method public float getEndSharpness();
+ method public float getStartIntensity();
+ method public float getStartSharpness();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.BasicPwleSegment> CREATOR;
+ }
+
public final class PrebakedSegment extends android.os.vibrator.VibrationEffectSegment {
method public int describeContents();
method public long getDuration();
@@ -3282,7 +3295,7 @@ package android.service.quicksettings {
package android.service.settings.preferences {
@FlaggedApi("com.android.settingslib.flags.settings_catalyst") public class SettingsPreferenceServiceClient implements java.lang.AutoCloseable {
- ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String, boolean, @Nullable android.content.ServiceConnection);
+ ctor public SettingsPreferenceServiceClient(@NonNull android.content.Context, @NonNull String, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.service.settings.preferences.SettingsPreferenceServiceClient,java.lang.Exception>);
}
}
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index c2fac70d1f68..9140bdf4fba7 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -2139,6 +2139,8 @@ UnflaggedApi: android.os.BugreportParams#BUGREPORT_MODE_MAX_VALUE:
New API must be flagged with @FlaggedApi: field android.os.BugreportParams.BUGREPORT_MODE_MAX_VALUE
UnflaggedApi: android.os.PowerManager#isBatterySaverSupported():
New API must be flagged with @FlaggedApi: method android.os.PowerManager.isBatterySaverSupported()
+UnflaggedApi: android.os.PowerManager#isInteractive(int):
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.isInteractive(int)
UnflaggedApi: android.os.UserHandle#USER_CURRENT:
New API must be flagged with @FlaggedApi: field android.os.UserHandle.USER_CURRENT
UnflaggedApi: android.os.UserManager#getAliveUsers():
diff --git a/core/java/Android.bp b/core/java/Android.bp
index bc38294279a8..ce767f46dd50 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -236,6 +236,7 @@ aidl_interface {
"android/os/GpuHeadroomParamsInternal.aidl",
"android/os/IHintManager.aidl",
"android/os/IHintSession.aidl",
+ "android/os/SessionCreationConfig.aidl",
],
unstable: true,
backend: {
@@ -689,43 +690,8 @@ java_library {
// protolog end
-// Whether to enable read-only system feature codegen.
-gen_readonly_feature_apis = select(release_flag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS"), {
- true: "true",
- false: "false",
- default: "false",
-})
-
-// Generates com.android.internal.pm.RoSystemFeatures, optionally compiling in
-// details about fixed system features defined by build flags. When disabled,
-// the APIs are simply passthrough stubs with no meaningful side effects.
-// TODO(b/203143243): Implement the `--feature=` aggregation directly with a native soong module.
-genrule {
+java_system_features_srcs {
name: "systemfeatures-gen-srcs",
- cmd: "$(location systemfeatures-gen-tool) com.android.internal.pm.RoSystemFeatures " +
- // --readonly=false (default) makes the codegen an effective no-op passthrough API.
- " --readonly=" + gen_readonly_feature_apis +
- " --feature=AUTOMOTIVE:" + select(release_flag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE"), {
- any @ value: value,
- default: "",
- }) + " --feature=EMBEDDED:" + select(release_flag("RELEASE_SYSTEM_FEATURE_EMBEDDED"), {
- any @ value: value,
- default: "",
- }) + " --feature=LEANBACK:" + select(release_flag("RELEASE_SYSTEM_FEATURE_LEANBACK"), {
- any @ value: value,
- default: "",
- }) + " --feature=PC:" + select(release_flag("RELEASE_SYSTEM_FEATURE_PC"), {
- any @ value: value,
- default: "",
- }) + " --feature=TELEVISION:" + select(release_flag("RELEASE_SYSTEM_FEATURE_TELEVISION"), {
- any @ value: value,
- default: "",
- }) + " --feature=WATCH:" + select(release_flag("RELEASE_SYSTEM_FEATURE_WATCH"), {
- any @ value: value,
- default: "",
- }) + " > $(out)",
- out: [
- "RoSystemFeatures.java",
- ],
- tools: ["systemfeatures-gen-tool"],
+ full_class_name: "com.android.internal.pm.RoSystemFeatures",
+ visibility: ["//visibility:private"],
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 87acbbf65b2f..72450999993d 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -16,9 +16,13 @@
package android.accounts;
+import static android.Manifest.permission.COPY_ACCOUNTS;
+import static android.Manifest.permission.REMOVE_ACCOUNTS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.app.admin.flags.Flags.FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED;
import android.annotation.BroadcastBehavior;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -26,6 +30,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.Size;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.UserHandleAware;
@@ -1312,7 +1317,8 @@ public class AccountManager {
* {@link AccountManagerFuture} must not be used on the main thread.
*
* <p>This method requires the caller to have a signature match with the
- * authenticator that manages the specified account.
+ * authenticator that manages the specified account, be a profile owner or have the
+ * {@link android.Manifest.permission#REMOVE_ACCOUNTS} permission.
*
* <p><b>NOTE:</b> If targeting your app to work on API level 22 and before,
* MANAGE_ACCOUNTS permission is needed for those platforms. See docs for
@@ -1344,6 +1350,8 @@ public class AccountManager {
* </ul>
*/
@UserHandleAware
+ @RequiresPermission(value = REMOVE_ACCOUNTS, conditional = true)
+ @FlaggedApi(FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED)
public AccountManagerFuture<Bundle> removeAccount(final Account account,
final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
return removeAccountAsUser(account, activity, callback, handler, mContext.getUser());
@@ -2019,9 +2027,15 @@ public class AccountManager {
* succeeded.
* @hide
*/
+ @SuppressLint("SamShouldBeLast")
+ @NonNull
+ @SystemApi
+ @RequiresPermission(anyOf = {COPY_ACCOUNTS, INTERACT_ACROSS_USERS_FULL})
+ @FlaggedApi(FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED)
public AccountManagerFuture<Boolean> copyAccountToUser(
- final Account account, final UserHandle fromUser, final UserHandle toUser,
- AccountManagerCallback<Boolean> callback, Handler handler) {
+ @NonNull final Account account, @NonNull final UserHandle fromUser,
+ @NonNull final UserHandle toUser, @Nullable AccountManagerCallback<Boolean> callback,
+ @Nullable Handler handler) {
if (account == null) throw new IllegalArgumentException("account is null");
if (toUser == null || fromUser == null) {
throw new IllegalArgumentException("fromUser and toUser cannot be null");
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 76098db2dc5b..78566d2fe98d 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1227,7 +1227,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
}
if (finished) {
- endAnimation();
+ endAnimation(true /* fromLastFrame */);
return true;
}
return false;
@@ -1442,8 +1442,12 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
}
private void endAnimation() {
+ endAnimation(false /* fromLastFrame */);
+ }
+
+ private void endAnimation(boolean fromLastFrame) {
final boolean postNotifyEndListener = sPostNotifyEndListenerEnabled && mListeners != null
- && mLastFrameTime > 0;
+ && fromLastFrame && mTotalDuration > 0;
mStarted = false;
mLastFrameTime = -1;
mFirstFrame = -1;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index e849abaf4aec..492c2ffc561f 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1281,16 +1281,20 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
return true;
}
+ private void endAnimation() {
+ endAnimation(false /* fromLastFrame */);
+ }
+
/**
* Called internally to end an animation by removing it from the animations list. Must be
* called on the UI thread.
*/
- private void endAnimation() {
+ private void endAnimation(boolean fromLastFrame) {
if (mAnimationEndRequested) {
return;
}
final boolean postNotifyEndListener = sPostNotifyEndListenerEnabled && mListeners != null
- && mLastFrameTime > 0;
+ && fromLastFrame && getScaledDuration() > 0;
removeAnimationCallback();
mAnimationEndRequested = true;
@@ -1570,7 +1574,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
boolean finished = animateBasedOnTime(currentTime);
if (finished) {
- endAnimation();
+ endAnimation(true /* fromLastFrame */);
}
return finished;
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 419eb7dac5f0..38aea64386a0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1270,27 +1270,22 @@ public class Activity extends ContextThemeWrapper
}
/**
- * To make users aware of system features such as the app header menu and its various
- * functionalities, educational dialogs are shown to demonstrate how to find and utilize these
- * features. Using this method, an activity can specify if it wants these educational dialogs to
- * be shown. When set to {@code true}, these dialogs are not completely blocked; however, the
- * system will be notified that they should not be shown unless necessary. If this API is not
- * called, the system's educational dialogs are not limited by default.
- *
- * <p>This method can be utilized when activities have states where showing an
- * educational dialog would be disruptive to the user. For example, if a game application is
- * expecting prompt user input, this method can be used to limit educational dialogs such as the
- * dialogs that showcase the app header's features which, in this instance, would disrupt the
- * user's experience if shown.</p>
- *
- * <p>Note that educational dialogs may be shown soon after this activity is launched, so
- * this method must be called early if the intent is to limit the dialogs from the start.</p>
+ * Requests to show the “Open in browser” education. “Open in browser” is a feature
+ * within the app header that allows users to switch from an app to the web. The feature
+ * is made available when an application is opened by a user clicking a link or when a
+ * link is provided by an application. Links can be provided by utilizing
+ * {@link AssistContent#EXTRA_AUTHENTICATING_USER_WEB_URI} or
+ * {@link AssistContent#setWebUri}.
+ *
+ * <p>This method should be utilized when an activity wants to nudge the user to switch
+ * to the web application in cases where the web may provide the user with a better
+ * experience. Note that this method does not guarantee that the education will be shown.</p>
*/
@FlaggedApi(com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION)
- public final void setLimitSystemEducationDialogs(boolean limitSystemEducationDialogs) {
+ public final void requestOpenInBrowserEducation() {
try {
ActivityTaskManager
- .getService().setLimitSystemEducationDialogs(mToken, limitSystemEducationDialogs);
+ .getService().requestOpenInBrowserEducation(mToken);
} catch (RemoteException e) {
// Empty
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index ab75069cc5d8..33ba05865042 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2679,62 +2679,6 @@ public class ActivityManager {
*/
public static class RecentTaskInfo extends TaskInfo implements Parcelable {
/**
- * @hide
- */
- public static class PersistedTaskSnapshotData {
- /**
- * The bounds of the task when the last snapshot was taken, may be null if the task is
- * not yet attached to the hierarchy.
- * @see {@link android.window.TaskSnapshot#mTaskSize}.
- * @hide
- */
- public @Nullable Point taskSize;
-
- /**
- * The content insets of the task when the task snapshot was taken.
- * @see {@link android.window.TaskSnapshot#mContentInsets}.
- * @hide
- */
- public @Nullable Rect contentInsets;
-
- /**
- * The size of the last snapshot taken, may be null if there is no associated snapshot.
- * @see {@link android.window.TaskSnapshot#mSnapshot}.
- * @hide
- */
- public @Nullable Point bufferSize;
-
- /**
- * Sets the data from the other data.
- * @hide
- */
- public void set(PersistedTaskSnapshotData other) {
- taskSize = other.taskSize;
- contentInsets = other.contentInsets;
- bufferSize = other.bufferSize;
- }
-
- /**
- * Sets the data from the provided {@param snapshot}.
- * @hide
- */
- public void set(TaskSnapshot snapshot) {
- if (snapshot == null) {
- taskSize = null;
- contentInsets = null;
- bufferSize = null;
- return;
- }
- final HardwareBuffer buffer = snapshot.getHardwareBuffer();
- taskSize = new Point(snapshot.getTaskSize());
- contentInsets = new Rect(snapshot.getContentInsets());
- bufferSize = buffer != null
- ? new Point(buffer.getWidth(), buffer.getHeight())
- : null;
- }
- }
-
- /**
* If this task is currently running, this is the identifier for it.
* If it is not running, this will be -1.
*
@@ -2770,24 +2714,6 @@ public class ActivityManager {
@Deprecated
public int affiliatedTaskId;
- /**
- * Information of organized child tasks.
- *
- * @deprecated No longer used
- * @hide
- */
- @Deprecated
- public ArrayList<RecentTaskInfo> childrenTaskInfos = new ArrayList<>();
-
- /**
- * Information about the last snapshot taken for this task.
- *
- * @deprecated No longer used
- * @hide
- */
- @Deprecated
- public PersistedTaskSnapshotData lastSnapshotData = new PersistedTaskSnapshotData();
-
public RecentTaskInfo() {
}
@@ -2803,10 +2729,6 @@ public class ActivityManager {
public void readFromParcel(Parcel source) {
id = source.readInt();
persistentId = source.readInt();
- childrenTaskInfos = source.readArrayList(RecentTaskInfo.class.getClassLoader(), android.app.ActivityManager.RecentTaskInfo.class);
- lastSnapshotData.taskSize = source.readTypedObject(Point.CREATOR);
- lastSnapshotData.contentInsets = source.readTypedObject(Rect.CREATOR);
- lastSnapshotData.bufferSize = source.readTypedObject(Point.CREATOR);
super.readTaskFromParcel(source);
}
@@ -2814,10 +2736,6 @@ public class ActivityManager {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(persistentId);
- dest.writeList(childrenTaskInfos);
- dest.writeTypedObject(lastSnapshotData.taskSize, flags);
- dest.writeTypedObject(lastSnapshotData.contentInsets, flags);
- dest.writeTypedObject(lastSnapshotData.bufferSize, flags);
super.writeTaskToParcel(dest, flags);
}
@@ -2884,11 +2802,6 @@ public class ActivityManager {
pw.println(" }");
}
pw.print(" ");
- pw.print(" lastSnapshotData {");
- pw.print(" taskSize=" + lastSnapshotData.taskSize);
- pw.print(" contentInsets=" + lastSnapshotData.contentInsets);
- pw.print(" bufferSize=" + lastSnapshotData.bufferSize);
- pw.println(" }");
}
}
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f80121d0c9b6..d9f8d33f0545 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1150,6 +1150,20 @@ public abstract class ActivityManagerInternal {
public abstract void stopForegroundServiceDelegate(@NonNull ServiceConnection connection);
/**
+ * Notifies that a media foreground service associated with a media session has
+ * transitioned to a "user-disengaged" state.
+ * Upon receiving this notification, service may be removed from the foreground state. It
+ * should only be called by {@link com.android.server.media.MediaSessionService}
+ *
+ * @param packageName The package name of the app running the media foreground service.
+ * @param userId The user ID associated with the foreground service.
+ * @param notificationId The ID of the media notification associated with the foreground
+ * service.
+ */
+ public abstract void notifyInactiveMediaForegroundService(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId);
+
+ /**
* Same as {@link android.app.IActivityManager#startProfile(int userId)}, but it would succeed
* even if the profile is disabled - it should only be called by
* {@link com.android.server.devicepolicy.DevicePolicyManagerService} when starting a profile
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index 16444dc5adde..6efc4ef55180 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -62,6 +62,7 @@ import android.content.pm.ServiceInfo.ForegroundServiceType;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
+import android.health.connect.HealthPermissions;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -484,21 +485,35 @@ public abstract class ForegroundServiceTypePolicy {
*/
public static final @NonNull ForegroundServiceTypePolicyInfo FGS_TYPE_POLICY_HEALTH =
new ForegroundServiceTypePolicyInfo(
- FOREGROUND_SERVICE_TYPE_HEALTH,
- ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
- ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
- new ForegroundServiceTypePermissions(new ForegroundServiceTypePermission[] {
- new RegularPermission(Manifest.permission.FOREGROUND_SERVICE_HEALTH)
- }, true),
- new ForegroundServiceTypePermissions(new ForegroundServiceTypePermission[] {
- new RegularPermission(Manifest.permission.ACTIVITY_RECOGNITION),
- new RegularPermission(Manifest.permission.BODY_SENSORS),
- new RegularPermission(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS),
- }, false),
- FGS_TYPE_PERM_ENFORCEMENT_FLAG_HEALTH /* permissionEnforcementFlag */,
- true /* permissionEnforcementFlagDefaultValue */,
- false /* foregroundOnlyPermission */
- );
+ FOREGROUND_SERVICE_TYPE_HEALTH,
+ ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
+ ForegroundServiceTypePolicyInfo.INVALID_CHANGE_ID,
+ new ForegroundServiceTypePermissions(
+ new ForegroundServiceTypePermission[] {
+ new RegularPermission(Manifest.permission.FOREGROUND_SERVICE_HEALTH)
+ },
+ true),
+ new ForegroundServiceTypePermissions(getAllowedHealthPermissions(), false),
+ FGS_TYPE_PERM_ENFORCEMENT_FLAG_HEALTH /* permissionEnforcementFlag */,
+ true /* permissionEnforcementFlagDefaultValue */,
+ false /* foregroundOnlyPermission */);
+
+ /** Returns the permissions needed for the policy of the health foreground service type. */
+ private static ForegroundServiceTypePermission[] getAllowedHealthPermissions() {
+ final ArrayList<ForegroundServiceTypePermission> permissions = new ArrayList<>();
+ permissions.add(new RegularPermission(Manifest.permission.ACTIVITY_RECOGNITION));
+ permissions.add(new RegularPermission(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS));
+
+ if (android.permission.flags.Flags.replaceBodySensorPermissionEnabled()) {
+ permissions.add(new RegularPermission(HealthPermissions.READ_HEART_RATE));
+ permissions.add(new RegularPermission(HealthPermissions.READ_SKIN_TEMPERATURE));
+ permissions.add(new RegularPermission(HealthPermissions.READ_OXYGEN_SATURATION));
+ } else {
+ permissions.add(new RegularPermission(Manifest.permission.BODY_SENSORS));
+ }
+
+ return permissions.toArray(new ForegroundServiceTypePermission[permissions.size()]);
+ }
/**
* The policy for the {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING}.
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index ec7b72ec677e..c6f62a21641d 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -242,8 +242,8 @@ interface IActivityTaskManager {
boolean supportsLocalVoiceInteraction();
- // Sets whether system educational dialogs should be limited
- void setLimitSystemEducationDialogs(IBinder appToken, boolean limitSystemEducationDialogs);
+ // Requests the "Open in browser" education to be shown
+ void requestOpenInBrowserEducation(IBinder appToken);
// Get device configuration
ConfigurationInfo getDeviceConfigurationInfo();
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 9bb16ae7fa02..a6c1a57a8131 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -270,4 +270,6 @@ interface INotificationManager
int[] getAllowedAdjustmentKeyTypes();
void setAssistantAdjustmentKeyTypeState(int type, boolean enabled);
+ String[] getTypeAdjustmentDeniedPackages();
+ void setTypeAdjustmentForPackageState(String pkg, boolean enabled);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index eb161ea198e8..b84c91b8276b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -814,8 +814,8 @@ public class Notification implements Parcelable
if (Flags.notificationsRedesignTemplates()) {
return switch (layoutId) {
case R.layout.notification_2025_template_collapsed_base,
+ R.layout.notification_2025_template_heads_up_base,
R.layout.notification_2025_template_header,
- R.layout.notification_template_material_heads_up_base,
R.layout.notification_template_material_big_base,
R.layout.notification_template_material_big_picture,
R.layout.notification_template_material_big_text,
@@ -3160,12 +3160,16 @@ public class Notification implements Parcelable
callPerson.visitUris(visitor);
}
visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class));
- }
- if (Flags.apiRichOngoing()) {
- visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_TRACKER_ICON, Icon.class));
- visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_START_ICON, Icon.class));
- visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_END_ICON, Icon.class));
+
+ if (Flags.apiRichOngoing()) {
+ visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_TRACKER_ICON,
+ Icon.class));
+ visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_START_ICON,
+ Icon.class));
+ visitIconUri(visitor, extras.getParcelable(EXTRA_PROGRESS_END_ICON,
+ Icon.class));
+ }
}
if (mBubbleMetadata != null) {
@@ -3257,7 +3261,7 @@ public class Notification implements Parcelable
*/
@FlaggedApi(Flags.FLAG_UI_RICH_ONGOING)
public boolean hasPromotableCharacteristics() {
- return isColorized()
+ return isColorizedRequested()
&& hasTitle()
&& !containsCustomViews()
&& hasPromotableStyle();
@@ -4083,6 +4087,12 @@ public class Notification implements Parcelable
flags &= ~FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
}
}
+ if (Flags.apiRichOngoing()) {
+ if ((flags & FLAG_PROMOTED_ONGOING) != 0) {
+ flagStrings.add("PROMOTED_ONGOING");
+ flags &= ~FLAG_PROMOTED_ONGOING;
+ }
+ }
if (android.service.notification.Flags.notificationSilentFlag()) {
if ((flags & FLAG_SILENT) != 0) {
@@ -7128,7 +7138,9 @@ public class Notification implements Parcelable
*/
public CharSequence ensureColorSpanContrastOrStripStyling(CharSequence cs,
int buttonFillColor) {
- if (Flags.cleanUpSpansAndNewLines()) {
+ // Ongoing promoted notifications are allowed to have styling.
+ final boolean isPromotedOngoing = mN.isPromotedOngoing();
+ if (!isPromotedOngoing && Flags.cleanUpSpansAndNewLines()) {
return stripStyling(cs);
}
@@ -7517,7 +7529,11 @@ public class Notification implements Parcelable
}
private int getHeadsUpBaseLayoutResource() {
- return R.layout.notification_template_material_heads_up_base;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_heads_up_base;
+ } else {
+ return R.layout.notification_template_material_heads_up_base;
+ }
}
private int getCompactHeadsUpBaseLayoutResource() {
@@ -7788,8 +7804,16 @@ public class Notification implements Parcelable
* @hide
*/
public boolean isColorized() {
- return extras.getBoolean(EXTRA_COLORIZED)
- && (hasColorizedPermission() || isFgsOrUij());
+ return isColorizedRequested()
+ && (hasColorizedPermission() || isFgsOrUij() || isPromotedOngoing());
+ }
+
+ /**
+ * @return true if this notification has requested to be colorized, regardless of whether it
+ * meets the requirements to be displayed that way.
+ */
+ private boolean isColorizedRequested() {
+ return extras.getBoolean(EXTRA_COLORIZED);
}
/**
@@ -7803,6 +7827,19 @@ public class Notification implements Parcelable
}
/**
+ * Returns whether this notification is a promoted ongoing notification.
+ *
+ * This requires the Notification.FLAG_PROMOTED_ONGOING flag to be set
+ * (which may be true once the api_rich_ongoing feature flag is enabled),
+ * and requires that the ui_rich_ongoing feature flag is enabled.
+ *
+ * @hide
+ */
+ public boolean isPromotedOngoing() {
+ return Flags.uiRichOngoing() && (flags & Notification.FLAG_PROMOTED_ONGOING) != 0;
+ }
+
+ /**
* @return true if this is a media style notification with a media session
*
* @hide
@@ -8655,7 +8692,9 @@ public class Notification implements Parcelable
// Replace the text with the big text, but only if the big text is not empty.
CharSequence bigTextText = mBuilder.processLegacyText(mBigText);
- if (Flags.cleanUpSpansAndNewLines()) {
+ // Ongoing promoted notifications are allowed to have styling.
+ final boolean isPromotedOngoing = mBuilder.mN.isPromotedOngoing();
+ if (!isPromotedOngoing && Flags.cleanUpSpansAndNewLines()) {
bigTextText = normalizeBigText(stripStyling(bigTextText));
}
if (!TextUtils.isEmpty(bigTextText)) {
@@ -11667,8 +11706,10 @@ public class Notification implements Parcelable
return points;
}
- @NonNull
- private NotificationProgressModel createProgressModel(int defaultProgressColor,
+ /**
+ * @hide
+ */
+ public @NonNull NotificationProgressModel createProgressModel(int defaultProgressColor,
int backgroundColor) {
final NotificationProgressModel model;
if (mIndeterminate) {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index c49b02210dd4..87c861912036 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -16,6 +16,8 @@
package android.app;
+import static android.Manifest.permission.POST_NOTIFICATIONS;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.service.notification.Flags.notificationClassification;
import android.annotation.CallbackExecutor;
@@ -1597,11 +1599,15 @@ public class NotificationManager {
* Returns whether notifications from the calling package are enabled.
*/
public boolean areNotificationsEnabled() {
- INotificationManager service = getService();
- try {
- return service.areNotificationsEnabled(mContext.getPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ if (Flags.nmBinderPerfPermissionCheck()) {
+ return mContext.checkSelfPermission(POST_NOTIFICATIONS) == PERMISSION_GRANTED;
+ } else {
+ INotificationManager service = getService();
+ try {
+ return service.areNotificationsEnabled(mContext.getPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
}
@@ -1862,6 +1868,19 @@ public class NotificationManager {
/**
* @hide
*/
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) {
+ INotificationManager service = getService();
+ try {
+ service.setTypeAdjustmentForPackageState(pkg, enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ */
public List<String> getEnabledNotificationListenerPackages() {
INotificationManager service = getService();
try {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 087e246e8841..3cffca796680 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -206,11 +206,15 @@ public class ResourcesManager {
assets.addPresetApkKeys(extractApkKeys(collector.collectedKey()));
return new Pair<>(assets, size);
}
- final var newAssetsBuilder = new AssetManager.Builder();
+ final var newAssetsBuilder = new AssetManager.Builder().setNoInit();
for (final var asset : assets.getApkAssets()) {
- if (!asset.isForLoader()) {
- newAssetsBuilder.addApkAssets(asset);
+ // Skip everything that's either default, or will get added by the collector (builder
+ // doesn't check for duplicates at all).
+ if (asset.isSystem() || asset.isForLoader() || asset.isOverlay()
+ || asset.isSharedLib()) {
+ continue;
}
+ newAssetsBuilder.addApkAssets(asset);
}
for (final var key : extractApkKeys(collector.collectedKey())) {
try {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 53a7dad76788..2bd2d34d54a2 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -241,8 +241,10 @@ import android.security.advancedprotection.AdvancedProtectionManager;
import android.security.advancedprotection.IAdvancedProtectionService;
import android.security.attestationverification.AttestationVerificationManager;
import android.security.attestationverification.IAttestationVerificationManagerService;
-import android.security.forensic.ForensicManager;
-import android.security.forensic.IForensicService;
+import android.security.authenticationpolicy.AuthenticationPolicyManager;
+import android.security.authenticationpolicy.IAuthenticationPolicyService;
+import android.security.intrusiondetection.IIntrusionDetectionService;
+import android.security.intrusiondetection.IntrusionDetectionManager;
import android.security.keystore.KeyStoreManager;
import android.service.oemlock.IOemLockService;
import android.service.oemlock.OemLockManager;
@@ -1025,6 +1027,25 @@ public final class SystemServiceRegistry {
}
});
+ registerService(Context.AUTHENTICATION_POLICY_SERVICE,
+ AuthenticationPolicyManager.class,
+ new CachedServiceFetcher<AuthenticationPolicyManager>() {
+ @Override
+ public AuthenticationPolicyManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ if (!android.security.Flags.secureLockdown()) {
+ throw new ServiceNotFoundException(
+ Context.AUTHENTICATION_POLICY_SERVICE);
+ }
+
+ final IBinder binder = ServiceManager.getServiceOrThrow(
+ Context.AUTHENTICATION_POLICY_SERVICE);
+ final IAuthenticationPolicyService service =
+ IAuthenticationPolicyService.Stub.asInterface(binder);
+ return new AuthenticationPolicyManager(ctx.getOuterContext(), service);
+ }
+ });
+
registerService(Context.TV_INTERACTIVE_APP_SERVICE, TvInteractiveAppManager.class,
new CachedServiceFetcher<TvInteractiveAppManager>() {
@Override
@@ -1797,15 +1818,20 @@ public final class SystemServiceRegistry {
}
});
- registerService(Context.FORENSIC_SERVICE, ForensicManager.class,
- new CachedServiceFetcher<ForensicManager>() {
+ registerService(Context.INTRUSION_DETECTION_SERVICE, IntrusionDetectionManager.class,
+ new CachedServiceFetcher<IntrusionDetectionManager>() {
@Override
- public ForensicManager createService(ContextImpl ctx)
+ public IntrusionDetectionManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
+ if (!android.security.Flags.aflApi()) {
+ throw new ServiceNotFoundException(
+ "Intrusion Detection is not supported");
+ }
IBinder b = ServiceManager.getServiceOrThrow(
- Context.FORENSIC_SERVICE);
- IForensicService service = IForensicService.Stub.asInterface(b);
- return new ForensicManager(service);
+ Context.INTRUSION_DETECTION_SERVICE);
+ IIntrusionDetectionService service =
+ IIntrusionDetectionService.Stub.asInterface(b);
+ return new IntrusionDetectionManager(service);
}
});
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index aac963ade726..01cc9d82d56d 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -340,10 +340,10 @@ public class TaskInfo {
public int requestedVisibleTypes;
/**
- * Whether the top activity has requested to limit educational dialogs shown by the system.
+ * The timestamp of the top activity's last request to show the "Open in Browser" education.
* @hide
*/
- public boolean isTopActivityLimitSystemEducationDialogs;
+ public long topActivityRequestOpenInBrowserEducationTimestamp;
/**
* Encapsulate specific App Compat information.
@@ -493,8 +493,8 @@ public class TaskInfo {
&& Objects.equals(capturedLink, that.capturedLink)
&& capturedLinkTimestamp == that.capturedLinkTimestamp
&& requestedVisibleTypes == that.requestedVisibleTypes
- && isTopActivityLimitSystemEducationDialogs
- == that.isTopActivityLimitSystemEducationDialogs
+ && topActivityRequestOpenInBrowserEducationTimestamp
+ == that.topActivityRequestOpenInBrowserEducationTimestamp
&& appCompatTaskInfo.equalsForTaskOrganizer(that.appCompatTaskInfo)
&& Objects.equals(topActivityMainWindowFrame, that.topActivityMainWindowFrame);
}
@@ -571,7 +571,7 @@ public class TaskInfo {
capturedLink = source.readTypedObject(Uri.CREATOR);
capturedLinkTimestamp = source.readLong();
requestedVisibleTypes = source.readInt();
- isTopActivityLimitSystemEducationDialogs = source.readBoolean();
+ topActivityRequestOpenInBrowserEducationTimestamp = source.readLong();
appCompatTaskInfo = source.readTypedObject(AppCompatTaskInfo.CREATOR);
topActivityMainWindowFrame = source.readTypedObject(Rect.CREATOR);
}
@@ -627,7 +627,7 @@ public class TaskInfo {
dest.writeTypedObject(capturedLink, flags);
dest.writeLong(capturedLinkTimestamp);
dest.writeInt(requestedVisibleTypes);
- dest.writeBoolean(isTopActivityLimitSystemEducationDialogs);
+ dest.writeLong(topActivityRequestOpenInBrowserEducationTimestamp);
dest.writeTypedObject(appCompatTaskInfo, flags);
dest.writeTypedObject(topActivityMainWindowFrame, flags);
}
@@ -672,8 +672,8 @@ public class TaskInfo {
+ " capturedLink=" + capturedLink
+ " capturedLinkTimestamp=" + capturedLinkTimestamp
+ " requestedVisibleTypes=" + requestedVisibleTypes
- + " isTopActivityLimitSystemEducationDialogs="
- + isTopActivityLimitSystemEducationDialogs
+ + " topActivityRequestOpenInBrowserEducationTimestamp="
+ + topActivityRequestOpenInBrowserEducationTimestamp
+ " appCompatTaskInfo=" + appCompatTaskInfo
+ " topActivityMainWindowFrame=" + topActivityMainWindowFrame
+ "}";
diff --git a/core/java/android/app/jank/FrameOverrunHistogram.java b/core/java/android/app/jank/FrameOverrunHistogram.java
index e28ac126a90a..3ad6531a46bf 100644
--- a/core/java/android/app/jank/FrameOverrunHistogram.java
+++ b/core/java/android/app/jank/FrameOverrunHistogram.java
@@ -39,7 +39,7 @@ public class FrameOverrunHistogram {
* Create a new instance of FrameOverrunHistogram.
*/
public FrameOverrunHistogram() {
- mBucketCounts = new int[sBucketEndpoints.length - 1];
+ mBucketCounts = new int[sBucketEndpoints.length];
}
/**
diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java
index 7525d0402ee4..7ceaeb3fb070 100644
--- a/core/java/android/app/jank/JankDataProcessor.java
+++ b/core/java/android/app/jank/JankDataProcessor.java
@@ -59,7 +59,6 @@ public class JankDataProcessor {
* @param appUid the uid of the app.
*/
public void processJankData(List<JankData> jankData, String activityName, int appUid) {
- mCurrentBatchCount++;
// add all the previous and active states to the pending states list.
mStateTracker.retrieveAllStates(mPendingStates);
@@ -79,9 +78,8 @@ public class JankDataProcessor {
}
}
// At this point we have attributed all frames to a state.
- if (mCurrentBatchCount >= LOG_BATCH_FREQUENCY) {
- logMetricCounts();
- }
+ incrementBatchCountAndMaybeLogStats();
+
// return the StatData object back to the pool to be reused.
jankDataProcessingComplete();
}
@@ -91,7 +89,73 @@ public class JankDataProcessor {
* stats
*/
public void mergeJankStats(AppJankStats jankStats, String activityName) {
- // TODO b/377572463 Add Merging Logic
+ // Each state has a key which is a combination of widget category, widget id and widget
+ // state, this key is also used to identify pending stats, a pending stat is essentially a
+ // state with frames associated with it.
+ String stateKey = mStateTracker.getStateKey(jankStats.getWidgetCategory(),
+ jankStats.getWidgetId(), jankStats.getWidgetState());
+
+ if (mPendingJankStats.containsKey(stateKey)) {
+ mergeExistingStat(stateKey, jankStats);
+ } else {
+ mergeNewStat(stateKey, activityName, jankStats);
+ }
+
+ incrementBatchCountAndMaybeLogStats();
+ }
+
+ private void mergeExistingStat(String stateKey, AppJankStats jankStat) {
+ PendingJankStat pendingStat = mPendingJankStats.get(stateKey);
+
+ pendingStat.mJankyFrames += jankStat.getJankyFrameCount();
+ pendingStat.mTotalFrames += jankStat.getTotalFrameCount();
+
+ mergeOverrunHistograms(pendingStat.mFrameOverrunBuckets,
+ jankStat.getFrameOverrunHistogram().getBucketCounters());
+ }
+
+ private void mergeNewStat(String stateKey, String activityName, AppJankStats jankStats) {
+ // Check if we have space for a new stat
+ if (mPendingJankStats.size() > MAX_IN_MEMORY_STATS) {
+ return;
+ }
+
+ PendingJankStat pendingStat = mPendingJankStatsPool.acquire();
+ if (pendingStat == null) {
+ pendingStat = new PendingJankStat();
+
+ }
+ pendingStat.clearStats();
+
+ pendingStat.mActivityName = activityName;
+ pendingStat.mUid = jankStats.getUid();
+ pendingStat.mWidgetId = jankStats.getWidgetId();
+ pendingStat.mWidgetCategory = jankStats.getWidgetCategory();
+ pendingStat.mWidgetState = jankStats.getWidgetState();
+ pendingStat.mTotalFrames = jankStats.getTotalFrameCount();
+ pendingStat.mJankyFrames = jankStats.getJankyFrameCount();
+
+ mergeOverrunHistograms(pendingStat.mFrameOverrunBuckets,
+ jankStats.getFrameOverrunHistogram().getBucketCounters());
+
+ mPendingJankStats.put(stateKey, pendingStat);
+ }
+
+ private void mergeOverrunHistograms(int[] mergeTarget, int[] mergeSource) {
+ // The length of each histogram should be identical, if they are not then its possible the
+ // buckets are not in sync, these records should not be recorded.
+ if (mergeTarget.length != mergeSource.length) return;
+
+ for (int i = 0; i < mergeTarget.length; i++) {
+ mergeTarget[i] += mergeSource[i];
+ }
+ }
+
+ private void incrementBatchCountAndMaybeLogStats() {
+ mCurrentBatchCount++;
+ if (mCurrentBatchCount >= LOG_BATCH_FREQUENCY) {
+ logMetricCounts();
+ }
}
/**
diff --git a/core/java/android/app/jank/JankTracker.java b/core/java/android/app/jank/JankTracker.java
index 202281f98c97..469521668d25 100644
--- a/core/java/android/app/jank/JankTracker.java
+++ b/core/java/android/app/jank/JankTracker.java
@@ -89,7 +89,12 @@ public class JankTracker {
* stats
*/
public void mergeAppJankStats(AppJankStats appJankStats) {
- mJankDataProcessor.mergeJankStats(appJankStats, mActivityName);
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ mJankDataProcessor.mergeJankStats(appJankStats, mActivityName);
+ }
+ });
}
public void setActivityName(@NonNull String activityName) {
diff --git a/core/java/android/app/jank/StateTracker.java b/core/java/android/app/jank/StateTracker.java
index c86d5a5cff20..21bb5e8280ee 100644
--- a/core/java/android/app/jank/StateTracker.java
+++ b/core/java/android/app/jank/StateTracker.java
@@ -180,7 +180,11 @@ public class StateTracker {
}
}
- private String getStateKey(String widgetCategory, String widgetId, String widgetState) {
+ /**
+ * Returns a concatenated string of the inputs. This key can be used to retrieve both pending
+ * stats and the state that was used to create the pending stat.
+ */
+ public String getStateKey(String widgetCategory, String widgetId, String widgetState) {
return widgetCategory + widgetId + widgetState;
}
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 2e3d5e15e037..8b6840c1b552 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -277,6 +277,13 @@ flag {
}
flag {
+ name: "nm_binder_perf_permission_check"
+ namespace: "systemui"
+ description: "Use PermissionManager for areNotificationsEnabled() instead of NMS"
+ bug: "362981561"
+}
+
+flag {
name: "no_sbnholder"
namespace: "systemui"
description: "removes sbnholder from NLS"
diff --git a/core/java/android/app/ondeviceintelligence/InferenceInfo.java b/core/java/android/app/ondeviceintelligence/InferenceInfo.java
index 5557a81cbe40..cae8db27a435 100644
--- a/core/java/android/app/ondeviceintelligence/InferenceInfo.java
+++ b/core/java/android/app/ondeviceintelligence/InferenceInfo.java
@@ -16,6 +16,12 @@
package android.app.ondeviceintelligence;
+import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE;
+
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -25,7 +31,9 @@ import android.os.Parcelable;
*
* @hide
*/
-public class InferenceInfo implements Parcelable {
+@SystemApi
+@FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+public final class InferenceInfo implements Parcelable {
/**
* Uid for the caller app.
@@ -55,7 +63,7 @@ public class InferenceInfo implements Parcelable {
* @param endTimeMs Inference end time (milliseconds from the epoch time).
* @param suspendedTimeMs Suspended time in milliseconds.
*/
- public InferenceInfo(int uid, long startTimeMs, long endTimeMs,
+ InferenceInfo(int uid, long startTimeMs, long endTimeMs,
long suspendedTimeMs) {
this.uid = uid;
this.startTimeMs = startTimeMs;
@@ -68,7 +76,7 @@ public class InferenceInfo implements Parcelable {
*
* @param in The Parcel to read the object's data from.
*/
- protected InferenceInfo(Parcel in) {
+ private InferenceInfo(@NonNull Parcel in) {
uid = in.readInt();
startTimeMs = in.readLong();
endTimeMs = in.readLong();
@@ -79,11 +87,11 @@ public class InferenceInfo implements Parcelable {
/**
* Writes the object's data to the provided Parcel.
*
- * @param dest The Parcel to write the object's data to.
+ * @param dest The Parcel to write the object's data to.
* @param flags Additional flags about how the object should be written.
*/
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(uid);
dest.writeLong(startTimeMs);
dest.writeLong(endTimeMs);
@@ -104,7 +112,8 @@ public class InferenceInfo implements Parcelable {
*
* @return the inference start time in milliseconds from the epoch time.
*/
- public long getStartTimeMs() {
+ @CurrentTimeMillisLong
+ public long getStartTimeMillis() {
return startTimeMs;
}
@@ -113,7 +122,8 @@ public class InferenceInfo implements Parcelable {
*
* @return the inference end time in milliseconds from the epoch time.
*/
- public long getEndTimeMs() {
+ @CurrentTimeMillisLong
+ public long getEndTimeMillis() {
return endTimeMs;
}
@@ -122,7 +132,8 @@ public class InferenceInfo implements Parcelable {
*
* @return the suspended time in milliseconds.
*/
- public long getSuspendedTimeMs() {
+ @CurrentTimeMillisLong
+ public long getSuspendedTimeMillis() {
return suspendedTimeMs;
}
@@ -148,21 +159,19 @@ public class InferenceInfo implements Parcelable {
/**
* Builder class for creating instances of {@link InferenceInfo}.
*/
- public static class Builder {
- private int uid;
+ public static final class Builder {
+ private final int uid;
private long startTimeMs;
private long endTimeMs;
private long suspendedTimeMs;
/**
- * Sets the UID for the caller app.
+ * Provides a builder instance to create a InferenceInfo for given caller uid.
*
- * @param uid the UID for the caller app.
- * @return the Builder instance.
+ * @param uid the caller uid associated with the inference info.
*/
- public Builder setUid(int uid) {
+ public Builder(int uid) {
this.uid = uid;
- return this;
}
/**
@@ -171,7 +180,7 @@ public class InferenceInfo implements Parcelable {
* @param startTimeMs the inference start time in milliseconds from the epoch time.
* @return the Builder instance.
*/
- public Builder setStartTimeMs(long startTimeMs) {
+ public @NonNull Builder setStartTimeMillis(@CurrentTimeMillisLong long startTimeMs) {
this.startTimeMs = startTimeMs;
return this;
}
@@ -182,7 +191,7 @@ public class InferenceInfo implements Parcelable {
* @param endTimeMs the inference end time in milliseconds from the epoch time.
* @return the Builder instance.
*/
- public Builder setEndTimeMs(long endTimeMs) {
+ public @NonNull Builder setEndTimeMillis(@CurrentTimeMillisLong long endTimeMs) {
this.endTimeMs = endTimeMs;
return this;
}
@@ -193,7 +202,7 @@ public class InferenceInfo implements Parcelable {
* @param suspendedTimeMs the suspended time in milliseconds.
* @return the Builder instance.
*/
- public Builder setSuspendedTimeMs(long suspendedTimeMs) {
+ public @NonNull Builder setSuspendedTimeMillis(@CurrentTimeMillisLong long suspendedTimeMs) {
this.suspendedTimeMs = suspendedTimeMs;
return this;
}
@@ -203,7 +212,7 @@ public class InferenceInfo implements Parcelable {
*
* @return an instance of {@link InferenceInfo}.
*/
- public InferenceInfo build() {
+ public @NonNull InferenceInfo build() {
return new InferenceInfo(uid, startTimeMs, endTimeMs,
suspendedTimeMs);
}
diff --git a/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java b/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
index 937a9cde1097..91651e317b18 100644
--- a/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
+++ b/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
@@ -17,9 +17,11 @@
package android.app.ondeviceintelligence;
import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE;
+import static android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -502,11 +504,10 @@ public final class OnDeviceIntelligenceManager {
*
* @param startTimeEpochMillis epoch millis used to filter the InferenceInfo events.
* @return InferenceInfo events since the passed in startTimeEpochMillis.
- *
- * @hide
*/
@RequiresPermission(Manifest.permission.DUMP)
- public List<InferenceInfo> getLatestInferenceInfo(long startTimeEpochMillis) {
+ @FlaggedApi(FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE)
+ public @NonNull List<InferenceInfo> getLatestInferenceInfo(@CurrentTimeMillisLong long startTimeEpochMillis) {
try {
return mService.getLatestInferenceInfo(startTimeEpochMillis);
} catch (RemoteException e) {
diff --git a/core/java/android/app/wearable/WearableSensingManager.java b/core/java/android/app/wearable/WearableSensingManager.java
index f0763752e054..5b14b038f130 100644
--- a/core/java/android/app/wearable/WearableSensingManager.java
+++ b/core/java/android/app/wearable/WearableSensingManager.java
@@ -55,6 +55,7 @@ import java.io.OutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -248,7 +249,11 @@ public class WearableSensingManager {
* @param executor Executor on which to run the consumer callback
* @param statusConsumer A consumer that handles the status codes for providing the connection
* and errors in the encrypted channel.
+ * @deprecated Use {@link #provideConnection(WearableConnection, Executor)} instead to provide a
+ * remote wearable device connection to the WearableSensingService
*/
+ @FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
+ @Deprecated
@RequiresPermission(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)
public void provideConnection(
@NonNull ParcelFileDescriptor wearableConnection,
@@ -348,9 +353,7 @@ public class WearableSensingManager {
wearableConnection.getMetadata(),
createWearableSensingCallback(executor),
statusCallback);
- if (connectionId != CONNECTION_ID_INVALID) {
- mWearableConnectionIdMap.put(wearableConnection, connectionId);
- }
+ mWearableConnectionIdMap.put(wearableConnection, connectionId);
// For invalid connection IDs, the status callback will remove the connection from
// mWearableConnectionIdMap
} catch (RemoteException e) {
@@ -367,36 +370,37 @@ public class WearableSensingManager {
* <p>After this method returns, there will be no new invocation to callback methods in the
* removed {@link WearableConnection}. Ongoing invocations will continue to run.
*
- * <p>This method does nothing if the provided {@code wearableConnection} does not match any
- * open connection.
+ * <p>This method throws a {@link NoSuchElementException} if the provided {@code
+ * wearableConnection} does not match any open connection.
*
* <p>This method should not be called before the corresponding {@link
* #provideConnection(WearableConnection, Executor)} invocation returns. Otherwise, the
- * connection may not be removed.
+ * connection may not be removed, and an {@link IllegalStateException} may be thrown.
*
* @param wearableConnection The WearableConnection instance previously provided to {@link
* #provideConnection(WearableConnection, Executor)}.
- * @return true if a concurrent connection quota has been freed due to this method invocation.
- * Returns false otherwise.
+ * @throws NoSuchElementException if the connection was never provided or was already removed.
+ * @throws IllegalStateException if the {@link #provideConnection(WearableConnection, Executor)}
+ * invocation for the given connection has not returned.
*/
@RequiresPermission(Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)
@FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
- public boolean removeConnection(@NonNull WearableConnection wearableConnection) {
- int connectionId =
- mWearableConnectionIdMap.getOrDefault(wearableConnection, CONNECTION_ID_INVALID);
- if (connectionId == CONNECTION_ID_INVALID) {
- return false;
+ public void removeConnection(@NonNull WearableConnection wearableConnection) {
+ Integer connectionId = mWearableConnectionIdMap.remove(wearableConnection);
+ if (connectionId == null || connectionId == CONNECTION_ID_INVALID) {
+ throw new NoSuchElementException(
+ "The provided connection was never provided or was already removed.");
}
if (connectionId == CONNECTION_ID_PLACEHOLDER) {
- Slog.w(
- TAG,
+ throw new IllegalStateException(
"Attempt to remove connection before provideConnection returns. The connection"
+ " will not be removed.");
- return false;
}
- mWearableConnectionIdMap.remove(wearableConnection);
try {
- return mService.removeConnection(connectionId);
+ if (!mService.removeConnection(connectionId)) {
+ throw new NoSuchElementException(
+ "The provided connection was never provided or was already removed.");
+ }
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index fb33348d9c26..4499a723cfb8 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -76,12 +76,15 @@ flag {
}
flag {
- name: "use_smaller_app_widget_radius"
+ name: "use_smaller_app_widget_system_radius"
namespace: "app_widgets"
description: "Updates system corner radius for app widgets to 24.dp instead of 28.dp"
bug: "373351337"
is_exported: true
is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6086f2455a31..acad92c90c59 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -18,6 +18,7 @@ package android.content;
import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS;
+import static android.security.Flags.FLAG_SECURE_LOCKDOWN;
import android.annotation.AttrRes;
import android.annotation.CallbackExecutor;
@@ -4256,6 +4257,7 @@ public abstract class Context {
FINGERPRINT_SERVICE,
//@hide: FACE_SERVICE,
BIOMETRIC_SERVICE,
+ AUTHENTICATION_POLICY_SERVICE,
MEDIA_ROUTER_SERVICE,
TELEPHONY_SERVICE,
TELEPHONY_SUBSCRIPTION_SERVICE,
@@ -4437,6 +4439,9 @@ public abstract class Context {
* web domain approval state.
* <dt> {@link #DISPLAY_HASH_SERVICE} ("display_hash")
* <dd> A {@link android.view.displayhash.DisplayHashManager} for management of display hashes.
+ * <dt> {@link #AUTHENTICATION_POLICY_SERVICE} ("authentication_policy")
+ * <dd> A {@link android.security.authenticationpolicy.AuthenticationPolicyManager}
+ * for managing authentication related policies on the device.
* </dl>
*
* <p>Note: System services obtained via this API may be closely associated with
@@ -4521,8 +4526,9 @@ public abstract class Context {
* @see android.content.pm.verify.domain.DomainVerificationManager
* @see #DISPLAY_HASH_SERVICE
* @see android.view.displayhash.DisplayHashManager
+ * @see #AUTHENTICATION_POLICY_SERVICE
+ * @see android.security.authenticationpolicy.AuthenticationPolicyManager
*/
- // TODO(b/347269120): Re-add @Nullable
public abstract Object getSystemService(@ServiceName @NonNull String name);
/**
@@ -4543,7 +4549,8 @@ public abstract class Context {
* {@link android.os.BatteryManager}, {@link android.app.job.JobScheduler},
* {@link android.app.usage.NetworkStatsManager},
* {@link android.content.pm.verify.domain.DomainVerificationManager},
- * {@link android.view.displayhash.DisplayHashManager}.
+ * {@link android.view.displayhash.DisplayHashManager}
+ * {@link android.security.authenticationpolicy.AuthenticationPolicyManager}.
* </p>
*
* <p>
@@ -4568,7 +4575,6 @@ public abstract class Context {
*/
@SuppressWarnings("unchecked")
@RavenwoodKeep
- // TODO(b/347269120): Re-add @Nullable
public final <T> T getSystemService(@NonNull Class<T> serviceClass) {
// Because subclasses may override getSystemService(String) we cannot
// perform a lookup by class alone. We must first map the class to its
@@ -5183,6 +5189,18 @@ public abstract class Context {
public static final String AUTH_SERVICE = "auth";
/**
+ * Use with {@link #getSystemService(String)} to retrieve an {@link
+ * android.security.authenticationpolicy.AuthenticationPolicyManager}.
+ * @see #getSystemService
+ * @see android.security.authenticationpolicy.AuthenticationPolicyManager
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final String AUTHENTICATION_POLICY_SERVICE = "authentication_policy";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.hardware.fingerprint.FingerprintManager} for handling management
* of fingerprints.
@@ -5695,12 +5713,12 @@ public abstract class Context {
public static final String BINARY_TRANSPARENCY_SERVICE = "transparency";
/**
- * System service name for ForensicService.
- * The service manages the forensic info on device.
+ * System service name for IntrusionDetectionService.
+ * The service manages the intrusion detection info on device.
* @hide
*/
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
- public static final String FORENSIC_SERVICE = "forensic";
+ public static final String INTRUSION_DETECTION_SERVICE = "intrusion_detection";
/**
* System service name for the DeviceIdleManager.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 23d17cb5ce50..413eb9886392 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -960,7 +960,6 @@ public class ContextWrapper extends Context {
}
@Override
- // TODO(b/347269120): Re-add @Nullable
public Object getSystemService(String name) {
return mBase.getSystemService(name);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 88533049f970..3d2d487b9d06 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1211,8 +1211,8 @@ public class Intent implements Parcelable, Cloneable {
* {@link android.telecom.TelecomManager#placeCall(Uri, Bundle)} to place calls rather than
* relying on this intent.
*
- * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M}
- * and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
+ * <p>Note: If your app targets {@link android.os.Build.VERSION_CODES#M M}
+ * or higher and declares as using the {@link android.Manifest.permission#CALL_PHONE}
* permission which is not granted, then attempting to use this action will
* result in a {@link java.lang.SecurityException}.
*/
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index ed965b3d1777..6db7dfe4f705 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -78,7 +78,8 @@ public class OverlayManager {
/**
* Applications can use OverlayManager to create overlays to overlay on itself resources. The
- * overlay target is itself and the work range is only in caller application.
+ * overlay target is itself, or the Android package, and the work range is only in caller
+ * application.
*
* <p>In {@link android.content.Context#getSystemService(String)}, it crashes because of {@link
* java.lang.NullPointerException} if the parameter is OverlayManager. if the self-targeting is
@@ -401,7 +402,7 @@ public class OverlayManager {
}
/**
- * Get the related information of overlays for {@code targetPackageName}.
+ * Get the related information of self-targeting overlays for {@code targetPackageName}.
*
* @param targetPackageName the target package name
* @return a list of overlay information
diff --git a/core/java/android/content/om/OverlayManagerTransaction.java b/core/java/android/content/om/OverlayManagerTransaction.java
index becd0ea285af..87b2e9350aa1 100644
--- a/core/java/android/content/om/OverlayManagerTransaction.java
+++ b/core/java/android/content/om/OverlayManagerTransaction.java
@@ -209,6 +209,7 @@ public final class OverlayManagerTransaction implements Parcelable {
*/
public static final class Builder {
private final List<Request> mRequests = new ArrayList<>();
+ private boolean mSelfTargeting = false;
/**
* Request that an overlay package be enabled and change its loading
@@ -246,6 +247,18 @@ public final class OverlayManagerTransaction implements Parcelable {
}
/**
+ * Request that an overlay package be self-targeting. Self-targeting overlays enable
+ * applications to overlay on itself resources. The overlay target is itself, or the Android
+ * package, and the work range is only in caller application.
+ * @param selfTargeting whether the overlay is self-targeting, the default is false.
+ * @hide
+ */
+ public Builder setSelfTargeting(boolean selfTargeting) {
+ mSelfTargeting = selfTargeting;
+ return this;
+ }
+
+ /**
* Registers the fabricated overlay with the overlay manager so it can be enabled and
* disabled for any user.
*
@@ -286,7 +299,7 @@ public final class OverlayManagerTransaction implements Parcelable {
*/
@NonNull
public OverlayManagerTransaction build() {
- return new OverlayManagerTransaction(mRequests, false /* selfTargeting */);
+ return new OverlayManagerTransaction(mRequests, mSelfTargeting);
}
}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index ce52825ddb73..b10f5e4fe66c 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1320,23 +1320,23 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
264301586L; // buganizer id
/**
- * Excludes the packages the override is applied to from the camera compatibility treatment
- * in free-form windowing mode for fixed-orientation apps.
+ * Includes the packages the override is applied to in the camera compatibility treatment in
+ * free-form windowing mode for fixed-orientation apps.
*
* <p>In free-form windowing mode, the compatibility treatment emulates running on a portrait
* device by letterboxing the app window and changing the camera characteristics to what apps
* commonly expect in a portrait device: 90 and 270 degree sensor rotation for back and front
* cameras, respectively, and setting display rotation to 0.
*
- * <p>Use this flag to disable the compatibility treatment for apps that do not respond well to
- * the treatment.
+ * <p>Use this flag to enable the compatibility treatment for apps in which camera doesn't work
+ * well in freeform windowing.
*
* @hide
*/
@ChangeId
@Overridable
@Disabled
- public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT =
+ public static final long OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT =
314961188L;
/**
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 4fdbf1e9e622..451c0e5e079a 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -93,10 +93,4 @@ interface IPackageInstaller {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES,android.Manifest.permission.REQUEST_INSTALL_PACKAGES})")
void reportUnarchivalStatus(int unarchiveId, int status, long requiredStorageBytes, in PendingIntent userActionIntent, in UserHandle userHandle);
-
- @EnforcePermission("VERIFICATION_AGENT")
- int getVerificationPolicy(int userId);
-
- @EnforcePermission("VERIFICATION_AGENT")
- boolean setVerificationPolicy(int policy, int userId);
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 63279af8480d..cb665cd2053c 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -62,8 +62,6 @@ import android.content.pm.parsing.PackageLite;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.pm.verify.domain.DomainSet;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
import android.graphics.Bitmap;
import android.icu.util.ULocale;
import android.net.Uri;
@@ -420,21 +418,6 @@ public class PackageInstaller {
public static final String EXTRA_WARNINGS = "android.content.pm.extra.WARNINGS";
/**
- * When verification is blocked as part of the installation, additional reason for the block
- * will be provided to the installer with a {@link VerificationFailedReason} as part of the
- * installation result returned via the {@link IntentSender} in
- * {@link Session#commit(IntentSender)}. This extra is provided only when the installation has
- * failed. Installers can use this extra to check if the installation failure was caused by a
- * verification failure.
- *
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final String EXTRA_VERIFICATION_FAILURE_REASON =
- "android.content.pm.extra.VERIFICATION_FAILURE_REASON";
-
- /**
* Streaming installation pending.
* Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
*
@@ -777,90 +760,6 @@ public class PackageInstaller {
@Retention(RetentionPolicy.SOURCE)
public @interface UnarchivalStatus {}
- /**
- * Verification failed because of unknown reasons, such as when the verifier times out or cannot
- * be connected. It can also corresponds to the status of
- * {@link VerificationSession#VERIFICATION_INCOMPLETE_UNKNOWN} reported by the verifier via
- * {@link VerificationSession#reportVerificationIncomplete(int)}.
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_FAILED_REASON_UNKNOWN = 0;
-
- /**
- * Verification failed because the network is unavailable. This corresponds to the status of
- * {@link VerificationSession#VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE} reported by the
- * verifier via {@link VerificationSession#reportVerificationIncomplete(int)}.
- *
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE = 1;
-
- /**
- * Verification failed because the package is blocked, as reported by the verifier via
- * {@link VerificationSession#reportVerificationComplete(VerificationStatus)} or
- * {@link VerificationSession#reportVerificationComplete(VerificationStatus, PersistableBundle)}
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED = 2;
-
- /**
- * @hide
- */
- @IntDef(value = {
- VERIFICATION_FAILED_REASON_UNKNOWN,
- VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE,
- VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED,
- })
- public @interface VerificationFailedReason {
- }
-
- /**
- * Do not block installs, regardless of verification status.
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_POLICY_NONE = 0; // platform default
- /**
- * Only block installations on {@link #VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED}.
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_POLICY_BLOCK_FAIL_OPEN = 1;
- /**
- * Only block installations on {@link #VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED} and ask the
- * user if they'd like to install anyway when the verification is blocked for other reason.
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_POLICY_BLOCK_FAIL_WARN = 2;
- /**
- * Block installations whose verification status is blocked for any reason.
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- public static final int VERIFICATION_POLICY_BLOCK_FAIL_CLOSED = 3;
- /**
- * @hide
- */
- @IntDef(value = {
- VERIFICATION_POLICY_NONE,
- VERIFICATION_POLICY_BLOCK_FAIL_OPEN,
- VERIFICATION_POLICY_BLOCK_FAIL_WARN,
- VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface VerificationPolicy {
- }
/** Default set of checksums - includes all available checksums.
* @see Session#requestChecksums */
@@ -1604,40 +1503,6 @@ public class PackageInstaller {
}
/**
- * Return the current verification enforcement policy. This may only be called by the
- * package currently set by the system as the verifier agent.
- * @hide
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
- public final @VerificationPolicy int getVerificationPolicy() {
- try {
- return mInstaller.getVerificationPolicy(mUserId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Set the current verification enforcement policy which will be applied to all the future
- * installation sessions. This may only be called by the package currently set by the system as
- * the verifier agent.
- * @hide
- * @return whether the new policy was successfully set.
- */
- @FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
- @SystemApi
- @RequiresPermission(android.Manifest.permission.VERIFICATION_AGENT)
- public final boolean setVerificationPolicy(@VerificationPolicy int policy) {
- try {
- return mInstaller.setVerificationPolicy(policy, mUserId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* An installation that is being actively staged. For an install to succeed,
* all existing and new packages must have identical package names, version
* codes, and signing certificates.
@@ -2935,8 +2800,6 @@ public class PackageInstaller {
/** {@hide} */
public @Nullable String dexoptCompilerFilter = null;
/** {@hide} */
- public boolean forceVerification;
- /** {@hide} */
public boolean isAutoInstallDependenciesEnabled = true;
private final ArrayMap<String, Integer> mPermissionStates;
@@ -2992,7 +2855,6 @@ public class PackageInstaller {
developmentInstallFlags = source.readInt();
unarchiveId = source.readInt();
dexoptCompilerFilter = source.readString();
- forceVerification = source.readBoolean();
isAutoInstallDependenciesEnabled = source.readBoolean();
}
@@ -3030,7 +2892,6 @@ public class PackageInstaller {
ret.developmentInstallFlags = developmentInstallFlags;
ret.unarchiveId = unarchiveId;
ret.dexoptCompilerFilter = dexoptCompilerFilter;
- ret.forceVerification = forceVerification;
ret.isAutoInstallDependenciesEnabled = isAutoInstallDependenciesEnabled;
return ret;
}
@@ -3741,14 +3602,6 @@ public class PackageInstaller {
}
/**
- * Used by adb installations to force enable the verification for this install.
- * {@hide}
- */
- public void setForceVerification() {
- this.forceVerification = true;
- }
-
- /**
* Optionally indicate whether missing SDK or static shared library dependencies should be
* automatically fetched and installed when installing an app that wants to use these
* dependencies.
@@ -3761,7 +3614,7 @@ public class PackageInstaller {
* dependencies aren't already installed.
*/
@FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
- public void setEnableAutoInstallDependencies(boolean enableAutoInstallDependencies) {
+ public void setAutoInstallDependenciesEnabled(boolean enableAutoInstallDependencies) {
isAutoInstallDependenciesEnabled = enableAutoInstallDependencies;
}
@@ -3800,7 +3653,6 @@ public class PackageInstaller {
pw.printHexPair("developmentInstallFlags", developmentInstallFlags);
pw.printPair("unarchiveId", unarchiveId);
pw.printPair("dexoptCompilerFilter", dexoptCompilerFilter);
- pw.printPair("forceVerification", forceVerification);
pw.printPair("isAutoInstallDependenciesEnabled", isAutoInstallDependenciesEnabled);
pw.println();
}
@@ -3848,7 +3700,6 @@ public class PackageInstaller {
dest.writeInt(developmentInstallFlags);
dest.writeInt(unarchiveId);
dest.writeString(dexoptCompilerFilter);
- dest.writeBoolean(forceVerification);
dest.writeBoolean(isAutoInstallDependenciesEnabled);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 37295ac94823..d2b43b9bd2b4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3200,6 +3200,16 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device is capable of ranging with
+ * other devices using channel sounding via Bluetooth Low Energy radio.
+ */
+ @FlaggedApi(com.android.ranging.flags.Flags.FLAG_RANGING_CS_ENABLED)
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING =
+ "android.hardware.bluetooth_le.channel_sounding";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device has a camera facing away
* from the screen.
*/
@@ -5172,25 +5182,6 @@ public abstract class PackageManager {
"android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER";
/**
- * Used by the system to query a {@link android.content.pm.verify.pkg.VerifierService} provider,
- * which registers itself via an intent-filter handling this action.
- *
- * <p class="note">Only the system can bind to such a verifier service. This is protected by the
- * {@link android.Manifest.permission#BIND_VERIFICATION_AGENT} permission. The verifier service
- * app should protect the service by adding this permission in the service declaration in its
- * manifest.
- * <p>
- * A verifier service must be a privileged app and hold the
- * {@link android.Manifest.permission#VERIFICATION_AGENT} permission.
- *
- * @hide
- */
- @SystemApi
- @FlaggedApi(android.content.pm.Flags.FLAG_VERIFICATION_SERVICE)
- @SdkConstant(SdkConstantType.SERVICE_ACTION)
- public static final String ACTION_VERIFY_PACKAGE = "android.content.pm.action.VERIFY_PACKAGE";
-
- /**
* The names of the requested permissions.
* <p>
* <strong>Type:</strong> String[]
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 4285b0a2b91a..8243d88e6260 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.RequiresPermission;
+import android.health.connect.HealthPermissions;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Printer;
@@ -361,8 +362,10 @@ public class ServiceInfo extends ComponentInfo
* {@link android.Manifest.permission#FOREGROUND_SERVICE_HEALTH} and one of the following
* permissions:
* {@link android.Manifest.permission#ACTIVITY_RECOGNITION},
- * {@link android.Manifest.permission#BODY_SENSORS},
* {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS}.
+ * {@link android.health.connect.HealthPermissions#READ_HEART_RATE},
+ * {@link android.health.connect.HealthPermissions#READ_SKIN_TEMPERATURE},
+ * {@link android.health.connect.HealthPermissions#READ_OXYGEN_SATURATION},
*/
@RequiresPermission(
allOf = {
@@ -370,10 +373,13 @@ public class ServiceInfo extends ComponentInfo
},
anyOf = {
Manifest.permission.ACTIVITY_RECOGNITION,
- Manifest.permission.BODY_SENSORS,
Manifest.permission.HIGH_SAMPLING_RATE_SENSORS,
+ HealthPermissions.READ_HEART_RATE,
+ HealthPermissions.READ_SKIN_TEMPERATURE,
+ HealthPermissions.READ_OXYGEN_SATURATION,
}
)
+ @FlaggedApi(android.permission.flags.Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 1 << 8;
/**
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index e181ae8ef3c7..fbe581c5d524 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -312,14 +312,6 @@ flag {
}
flag {
- name: "verification_service"
- namespace: "package_manager_service"
- description: "Feature flag to enable the new verification service."
- bug: "360129103"
- is_fixed_read_only: true
-}
-
-flag {
name: "sdk_dependency_installer"
is_exported: true
namespace: "package_manager_service"
@@ -364,7 +356,7 @@ flag {
name: "support_minor_versions_in_minsdkversion"
namespace: "package_manager_service"
description: "Block app installations that specify an incompatible minor SDK version"
- bug: "377474232"
+ bug: "377302905"
}
flag {
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index c83cf9601cd7..1d8209da6559 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -142,6 +142,11 @@ public class ApkLite {
private final boolean mIsSdkLibrary;
/**
+ * Indicates if this apk is a static library.
+ */
+ private final boolean mIsStaticLibrary;
+
+ /**
* List of SDK names used by this apk.
*/
private final @NonNull List<String> mUsesSdkLibraries;
@@ -191,7 +196,7 @@ public class ApkLite {
Set<String> requiredSplitTypes, Set<String> splitTypes,
boolean hasDeviceAdminReceiver, boolean isSdkLibrary,
List<String> usesSdkLibraries, long[] usesSdkLibrariesVersionsMajor,
- String[][] usesSdkLibrariesCertDigests,
+ String[][] usesSdkLibrariesCertDigests, boolean isStaticLibrary,
List<String> usesStaticLibraries, long[] usesStaticLibrariesVersionsMajor,
String[][] usesStaticLibrariesCertDigests,
boolean updatableSystem,
@@ -229,6 +234,7 @@ public class ApkLite {
mRollbackDataPolicy = rollbackDataPolicy;
mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
mIsSdkLibrary = isSdkLibrary;
+ mIsStaticLibrary = isStaticLibrary;
mUsesSdkLibraries = usesSdkLibraries;
mUsesSdkLibrariesVersionsMajor = usesSdkLibrariesVersionsMajor;
mUsesSdkLibrariesCertDigests = usesSdkLibrariesCertDigests;
@@ -275,6 +281,7 @@ public class ApkLite {
mRollbackDataPolicy = 0;
mHasDeviceAdminReceiver = false;
mIsSdkLibrary = false;
+ mIsStaticLibrary = false;
mUsesSdkLibraries = Collections.emptyList();
mUsesSdkLibrariesVersionsMajor = null;
mUsesSdkLibrariesCertDigests = null;
@@ -594,6 +601,14 @@ public class ApkLite {
}
/**
+ * Indicates if this apk is a static library.
+ */
+ @DataClass.Generated.Member
+ public boolean isIsStaticLibrary() {
+ return mIsStaticLibrary;
+ }
+
+ /**
* List of SDK names used by this apk.
*/
@DataClass.Generated.Member
@@ -662,10 +677,10 @@ public class ApkLite {
}
@DataClass.Generated(
- time = 1730202160705L,
+ time = 1731589363302L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 05c8f31df5d6..72542036232c 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -44,6 +44,7 @@ import android.util.Slog;
import com.android.internal.pm.pkg.component.flags.Flags;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.XmlUtils;
import libcore.io.IoUtils;
import libcore.util.HexEncoding;
@@ -465,6 +466,7 @@ public class ApkLiteParseUtils {
boolean hasDeviceAdminReceiver = false;
boolean isSdkLibrary = false;
+ boolean isStaticLibrary = false;
List<String> usesSdkLibraries = new ArrayList<>();
long[] usesSdkLibrariesVersionsMajor = new long[0];
String[][] usesSdkLibrariesCertDigests = new String[0][0];
@@ -542,8 +544,13 @@ public class ApkLiteParseUtils {
}
String usesSdkLibName = parser.getAttributeValue(
ANDROID_RES_NAMESPACE, "name");
- long usesSdkLibVersionMajor = parser.getAttributeIntValue(
- ANDROID_RES_NAMESPACE, "versionMajor", -1);
+ // TODO(b/379219371): Due to a bug in bundletool, some apps can use
+ // versionMajor as string. Until it is resolved, we are adding a
+ // workaround here.
+ String usesSdkLibVersionMajorString = parser.getAttributeValue(
+ ANDROID_RES_NAMESPACE, "versionMajor");
+ long usesSdkLibVersionMajor = XmlUtils.convertValueToInt(
+ usesSdkLibVersionMajorString, -1);
String usesSdkCertDigest = parser.getAttributeValue(
ANDROID_RES_NAMESPACE, "certDigest");
@@ -588,6 +595,9 @@ public class ApkLiteParseUtils {
/*allowDuplicates=*/ true);
break;
case TAG_USES_STATIC_LIBRARY:
+ if (!android.content.pm.Flags.sdkDependencyInstaller()) {
+ break;
+ }
String usesStaticLibName = parser.getAttributeValue(
ANDROID_RES_NAMESPACE, "name");
long usesStaticLibVersion = parser.getAttributeIntValue(
@@ -656,6 +666,7 @@ public class ApkLiteParseUtils {
SharedLibraryInfo.TYPE_SDK_PACKAGE));
break;
case TAG_STATIC_LIBRARY:
+ isSdkLibrary = true;
// Mirrors ParsingPackageUtils#parseStaticLibrary until lite and full
// parsing are combined
String staticLibName = parser.getAttributeValue(
@@ -809,7 +820,7 @@ public class ApkLiteParseUtils {
requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
hasDeviceAdminReceiver, isSdkLibrary, usesSdkLibraries,
- usesSdkLibrariesVersionsMajor, usesSdkLibrariesCertDigests,
+ usesSdkLibrariesVersionsMajor, usesSdkLibrariesCertDigests, isStaticLibrary,
usesStaticLibraries, usesStaticLibrariesVersions,
usesStaticLibrariesCertDigests, updatableSystem, emergencyInstaller,
declaredLibraries));
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index 76b25fed2ac2..0e11eecfc7ec 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -114,6 +114,10 @@ public class PackageLite {
* Indicates if this package is a sdk.
*/
private final boolean mIsSdkLibrary;
+ /**
+ * Indicates if this package is a static library.
+ */
+ private final boolean mIsStaticLibrary;
private final @NonNull List<String> mUsesSdkLibraries;
@@ -164,6 +168,7 @@ public class PackageLite {
mUsesSdkLibraries = baseApk.getUsesSdkLibraries();
mUsesSdkLibrariesVersionsMajor = baseApk.getUsesSdkLibrariesVersionsMajor();
mUsesSdkLibrariesCertDigests = baseApk.getUsesSdkLibrariesCertDigests();
+ mIsStaticLibrary = baseApk.isIsStaticLibrary();
mUsesStaticLibraries = baseApk.getUsesStaticLibraries();
mUsesStaticLibrariesVersions = baseApk.getUsesStaticLibrariesVersions();
mUsesStaticLibrariesCertDigests = baseApk.getUsesStaticLibrariesCertDigests();
@@ -455,6 +460,14 @@ public class PackageLite {
return mIsSdkLibrary;
}
+ /**
+ * Indicates if this package is a static library.
+ */
+ @DataClass.Generated.Member
+ public boolean isIsStaticLibrary() {
+ return mIsStaticLibrary;
+ }
+
@DataClass.Generated.Member
public @NonNull List<String> getUsesSdkLibraries() {
return mUsesSdkLibraries;
@@ -499,10 +512,10 @@ public class PackageLite {
}
@DataClass.Generated(
- time = 1730203707341L,
+ time = 1731591578587L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl b/core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl
deleted file mode 100644
index 2ab745205193..000000000000
--- a/core/java/android/content/pm/verify/pkg/IVerificationSessionInterface.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.os.PersistableBundle;
-
-/**
- * Non-oneway interface that allows the verifier to communicate with the system.
- * @hide
- */
-interface IVerificationSessionInterface {
- long getTimeoutTime(int verificationId);
- long extendTimeRemaining(int verificationId, long additionalMs);
- boolean setVerificationPolicy(int verificationId, int policy);
- void reportVerificationIncomplete(int verificationId, int reason);
- void reportVerificationComplete(int verificationId, in VerificationStatus status, in @nullable PersistableBundle extensionResponse);
-} \ No newline at end of file
diff --git a/core/java/android/content/pm/verify/pkg/VerificationSession.java b/core/java/android/content/pm/verify/pkg/VerificationSession.java
deleted file mode 100644
index 97f78e0978fa..000000000000
--- a/core/java/android/content/pm/verify/pkg/VerificationSession.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.content.pm.Flags;
-import android.content.pm.PackageInstaller;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This class is used by the system to describe the details about a verification request sent to the
- * verification agent, aka the verifier. It includes the interfaces for the verifier to communicate
- * back to the system.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-@SystemApi
-public final class VerificationSession implements Parcelable {
- /**
- * The verification cannot be completed because of unknown reasons.
- */
- public static final int VERIFICATION_INCOMPLETE_UNKNOWN = 0;
- /**
- * The verification cannot be completed because the network is unavailable.
- */
- public static final int VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE = 1;
-
- /**
- * @hide
- */
- @IntDef(prefix = {"VERIFICATION_INCOMPLETE_"}, value = {
- VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE,
- VERIFICATION_INCOMPLETE_UNKNOWN,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface VerificationIncompleteReason {
- }
-
- private final int mId;
- private final int mInstallSessionId;
- @NonNull
- private final String mPackageName;
- @NonNull
- private final Uri mStagedPackageUri;
- @NonNull
- private final SigningInfo mSigningInfo;
- @NonNull
- private final List<SharedLibraryInfo> mDeclaredLibraries;
- @NonNull
- private final PersistableBundle mExtensionParams;
- @NonNull
- private final IVerificationSessionInterface mSession;
- /**
- * The current policy that is active for the session. It might not be
- * the same as the original policy that was initially assigned for this verification session,
- * because the active policy can be overridden by {@link #setVerificationPolicy(int)}.
- * <p>To improve the latency, store the original policy value and any changes made to it,
- * so that {@link #getVerificationPolicy()} does not need to make a binder call to retrieve the
- * currently active policy.</p>
- */
- private volatile @PackageInstaller.VerificationPolicy int mVerificationPolicy;
-
- /**
- * Constructor used by the system to describe the details of a verification session.
- * @hide
- */
- public VerificationSession(int id, int installSessionId, @NonNull String packageName,
- @NonNull Uri stagedPackageUri, @NonNull SigningInfo signingInfo,
- @NonNull List<SharedLibraryInfo> declaredLibraries,
- @NonNull PersistableBundle extensionParams,
- @PackageInstaller.VerificationPolicy int defaultPolicy,
- @NonNull IVerificationSessionInterface session) {
- mId = id;
- mInstallSessionId = installSessionId;
- mPackageName = packageName;
- mStagedPackageUri = stagedPackageUri;
- mSigningInfo = signingInfo;
- mDeclaredLibraries = declaredLibraries;
- mExtensionParams = extensionParams;
- mVerificationPolicy = defaultPolicy;
- mSession = session;
- }
-
- /**
- * A unique identifier tied to this specific verification session.
- */
- public int getId() {
- return mId;
- }
-
- /**
- * The package name of the app that is to be verified.
- */
- public @NonNull String getPackageName() {
- return mPackageName;
- }
-
- /**
- * The id of the installation session associated with the verification.
- */
- public int getInstallSessionId() {
- return mInstallSessionId;
- }
-
- /**
- * The Uri of the path where the package's code files are located.
- */
- public @NonNull Uri getStagedPackageUri() {
- return mStagedPackageUri;
- }
-
- /**
- * Signing info of the package to be verified.
- */
- public @NonNull SigningInfo getSigningInfo() {
- return mSigningInfo;
- }
-
- /**
- * Returns a mapping of any shared libraries declared in the manifest
- * to the {@link SharedLibraryInfo.Type} that is declared. This will be an empty
- * map if no shared libraries are declared by the package.
- */
- @NonNull
- public List<SharedLibraryInfo> getDeclaredLibraries() {
- return Collections.unmodifiableList(mDeclaredLibraries);
- }
-
- /**
- * Returns any extension params associated with the verification request.
- */
- @NonNull
- public PersistableBundle getExtensionParams() {
- return mExtensionParams;
- }
-
- /**
- * Get the value of Clock.elapsedRealtime() at which time this verification
- * will timeout as incomplete if no other verification response is provided.
- * @throws SecurityException if the caller is not the current verifier bound by the system.
- */
- public long getTimeoutTime() {
- try {
- return mSession.getTimeoutTime(mId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Return the current policy that is active for this session.
- * <p>If the policy for this session has been changed by {@link #setVerificationPolicy},
- * the return value of this method is the current policy that is active for this session.
- * Otherwise, the return value is the same as the initial policy that was assigned to the
- * session when it was first created.</p>
- */
- public @PackageInstaller.VerificationPolicy int getVerificationPolicy() {
- return mVerificationPolicy;
- }
-
- /**
- * Override the verification policy for this session.
- * @return True if the override was successful, False otherwise.
- * @throws SecurityException if the caller is not the current verifier bound by the system.
- */
- public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy) {
- if (mVerificationPolicy == policy) {
- // No effective policy change
- return true;
- }
- try {
- if (mSession.setVerificationPolicy(mId, policy)) {
- mVerificationPolicy = policy;
- return true;
- } else {
- return false;
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Extend the timeout for this session by the provided additionalMs to
- * fetch relevant information over the network or wait for the network.
- * This may be called multiple times. If the request would bypass any max
- * duration by the system, the method will return a lower value than the
- * requested amount that indicates how much the time was extended.
- * @throws SecurityException if the caller is not the current verifier bound by the system.
- */
- public long extendTimeRemaining(long additionalMs) {
- try {
- return mSession.extendTimeRemaining(mId, additionalMs);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Report to the system that verification could not be completed along
- * with an approximate reason to pass on to the installer.]
- * @throws SecurityException if the caller is not the current verifier bound by the system.
- */
- public void reportVerificationIncomplete(@VerificationIncompleteReason int reason) {
- try {
- mSession.reportVerificationIncomplete(mId, reason);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Report to the system that the verification has completed and the
- * install process may act on that status to either block in the case
- * of failure or continue to process the install in the case of success.
- * @throws SecurityException if the caller is not the current verifier bound by the system.
- */
- public void reportVerificationComplete(@NonNull VerificationStatus status) {
- try {
- mSession.reportVerificationComplete(mId, status, /* extensionResponse= */ null);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Same as {@link #reportVerificationComplete(VerificationStatus)}, but also provide
- * a result to the extension params provided in the request, which will be passed to the
- * installer in the installation result.
- * @throws SecurityException if the caller is not the current verifier bound by the system.
- */
- public void reportVerificationComplete(@NonNull VerificationStatus status,
- @NonNull PersistableBundle extensionResponse) {
- try {
- mSession.reportVerificationComplete(mId, status, extensionResponse);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- private VerificationSession(@NonNull Parcel in) {
- mId = in.readInt();
- mInstallSessionId = in.readInt();
- mPackageName = in.readString8();
- mStagedPackageUri = Uri.CREATOR.createFromParcel(in);
- mSigningInfo = SigningInfo.CREATOR.createFromParcel(in);
- mDeclaredLibraries = in.createTypedArrayList(SharedLibraryInfo.CREATOR);
- mExtensionParams = in.readPersistableBundle(getClass().getClassLoader());
- mVerificationPolicy = in.readInt();
- mSession = IVerificationSessionInterface.Stub.asInterface(in.readStrongBinder());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mId);
- dest.writeInt(mInstallSessionId);
- dest.writeString8(mPackageName);
- Uri.writeToParcel(dest, mStagedPackageUri);
- mSigningInfo.writeToParcel(dest, flags);
- dest.writeTypedList(mDeclaredLibraries);
- dest.writePersistableBundle(mExtensionParams);
- dest.writeInt(mVerificationPolicy);
- dest.writeStrongBinder(mSession.asBinder());
- }
-
- @NonNull
- public static final Creator<VerificationSession> CREATOR = new Creator<>() {
- @Override
- public VerificationSession createFromParcel(@NonNull Parcel in) {
- return new VerificationSession(in);
- }
-
- @Override
- public VerificationSession[] newArray(int size) {
- return new VerificationSession[size];
- }
- };
-}
diff --git a/core/java/android/content/pm/verify/pkg/VerificationStatus.java b/core/java/android/content/pm/verify/pkg/VerificationStatus.java
deleted file mode 100644
index 4d0379d79773..000000000000
--- a/core/java/android/content/pm/verify/pkg/VerificationStatus.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.content.pm.Flags;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used by the verifier to describe the status of the verification request, whether
- * it's successful or it has failed along with any relevant details.
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-public final class VerificationStatus implements Parcelable {
- /**
- * The ASL status has not been determined. This happens in situations where the verification
- * service is not monitoring ASLs, and means the ASL data in the app is not necessarily bad but
- * can't be trusted.
- */
- public static final int VERIFIER_STATUS_ASL_UNDEFINED = 0;
-
- /**
- * The app's ASL data is considered to be in a good state.
- */
- public static final int VERIFIER_STATUS_ASL_GOOD = 1;
-
- /**
- * There is something bad in the app's ASL data; the user should be warned about this when shown
- * the ASL data and/or appropriate decisions made about the use of this data by the platform.
- */
- public static final int VERIFIER_STATUS_ASL_BAD = 2;
-
- /** @hide */
- @IntDef(prefix = {"VERIFIER_STATUS_ASL_"}, value = {
- VERIFIER_STATUS_ASL_UNDEFINED,
- VERIFIER_STATUS_ASL_GOOD,
- VERIFIER_STATUS_ASL_BAD,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface VerifierStatusAsl {}
-
- private boolean mIsVerified;
- private @VerifierStatusAsl int mAslStatus;
- @NonNull
- private String mFailuresMessage = "";
-
- private VerificationStatus() {}
-
- /**
- * @return whether the status is set to verified or not.
- */
- public boolean isVerified() {
- return mIsVerified;
- }
-
- /**
- * @return the failure message associated with the failure status.
- */
- @NonNull
- public String getFailureMessage() {
- return mFailuresMessage;
- }
-
- /**
- * @return the asl status.
- */
- public @VerifierStatusAsl int getAslStatus() {
- return mAslStatus;
- }
-
- /**
- * Builder to construct a {@link VerificationStatus} object.
- */
- public static final class Builder {
- final VerificationStatus mStatus = new VerificationStatus();
-
- /**
- * Set in the status whether the verification has succeeded or failed.
- */
- @NonNull
- public Builder setVerified(boolean verified) {
- mStatus.mIsVerified = verified;
- return this;
- }
-
- /**
- * Set a developer-facing failure message to include in the verification failure status.
- */
- @NonNull
- public Builder setFailureMessage(@NonNull String failureMessage) {
- mStatus.mFailuresMessage = failureMessage;
- return this;
- }
-
- /**
- * Set the ASL status, as defined in {@link VerifierStatusAsl}.
- */
- @NonNull
- public Builder setAslStatus(@VerifierStatusAsl int aslStatus) {
- mStatus.mAslStatus = aslStatus;
- return this;
- }
-
- /**
- * Build the status object.
- */
- @NonNull
- public VerificationStatus build() {
- return mStatus;
- }
- }
-
- private VerificationStatus(Parcel in) {
- mIsVerified = in.readBoolean();
- mAslStatus = in.readInt();
- mFailuresMessage = in.readString8();
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeBoolean(mIsVerified);
- dest.writeInt(mAslStatus);
- dest.writeString8(mFailuresMessage);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @NonNull
- public static final Creator<VerificationStatus> CREATOR = new Creator<>() {
- @Override
- public VerificationStatus createFromParcel(@NonNull Parcel in) {
- return new VerificationStatus(in);
- }
-
- @Override
- public VerificationStatus[] newArray(int size) {
- return new VerificationStatus[size];
- }
- };
-}
diff --git a/core/java/android/content/pm/verify/pkg/VerifierService.java b/core/java/android/content/pm/verify/pkg/VerifierService.java
deleted file mode 100644
index ccf211915326..000000000000
--- a/core/java/android/content/pm/verify/pkg/VerifierService.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify.pkg;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.Flags;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-
-/**
- * A base service implementation for the verifier agent to implement.
- *
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_VERIFICATION_SERVICE)
-public abstract class VerifierService extends Service {
- /**
- * Called when a package name is available for a pending verification,
- * giving the verifier opportunity to pre-fetch any relevant information
- * that may be needed should a verification for the package be required.
- */
- public abstract void onPackageNameAvailable(@NonNull String packageName);
-
- /**
- * Called when a package recently provided via {@link #onPackageNameAvailable}
- * is no longer expected to be installed. This is a hint that any pre-fetch or
- * cache created as a result of the previous call may be be cleared.
- * <p>This method will never be called after {@link #onVerificationRequired} is called for the
- * same package. Once a verification is officially requested by
- * {@link #onVerificationRequired}, it cannot be cancelled.
- * </p>
- */
- public abstract void onVerificationCancelled(@NonNull String packageName);
-
- /**
- * Called when an application needs to be verified. Details about the
- * verification and actions that can be taken on it will be encapsulated in
- * the provided {@link VerificationSession} parameter.
- */
- public abstract void onVerificationRequired(@NonNull VerificationSession session);
-
- /**
- * Called when a verification needs to be retried. This can be encountered
- * when a prior verification was marked incomplete and the user has indicated
- * that they've resolved the issue, or when a timeout is reached, but the
- * the system is attempting to retry. Details about the
- * verification and actions that can be taken on it will be encapsulated in
- * the provided {@link VerificationSession} parameter.
- */
- public abstract void onVerificationRetry(@NonNull VerificationSession session);
-
- /**
- * Called in the case that an active verification has failed. Any APIs called
- * on the {@link VerificationSession} instance associated with this {@code verificationId} will
- * throw an {@link IllegalStateException}.
- */
- public abstract void onVerificationTimeout(int verificationId);
-
- /**
- * Called when the verifier service is bound to the system.
- */
- public @Nullable IBinder onBind(@Nullable Intent intent) {
- if (intent == null || !PackageManager.ACTION_VERIFY_PACKAGE.equals(intent.getAction())) {
- return null;
- }
- return new IVerifierService.Stub() {
- @Override
- public void onPackageNameAvailable(@NonNull String packageName) {
- VerifierService.this.onPackageNameAvailable(packageName);
- }
-
- @Override
- public void onVerificationCancelled(@NonNull String packageName) {
- VerifierService.this.onVerificationCancelled(packageName);
- }
-
- @Override
- public void onVerificationRequired(@NonNull VerificationSession session) {
- VerifierService.this.onVerificationRequired(session);
- }
-
- @Override
- public void onVerificationRetry(@NonNull VerificationSession session) {
- VerifierService.this.onVerificationRetry(session);
- }
-
- @Override
- public void onVerificationTimeout(int verificationId) {
- VerifierService.this.onVerificationTimeout(verificationId);
- }
- };
- }
-}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 4551bd52c960..bbfae8117b16 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -75,7 +75,10 @@ public final class AssetManager implements AutoCloseable {
private static final String TAG = "AssetManager";
private static final boolean DEBUG_REFS = false;
- private static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
+ /**
+ * @hide
+ */
+ public static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
private static final String FRAMEWORK_APK_PATH_DEVICE = "/system/framework/framework-res.apk";
private static final String FRAMEWORK_APK_PATH_RAVENWOOD = "ravenwood-data/framework-res.apk";
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index f23c193e2da0..6fc7d90a8237 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -105,3 +105,12 @@ flag {
# This flag is used to control aapt2 behavior.
is_fixed_read_only: true
}
+
+flag {
+ name: "resources_minor_version_support"
+ is_exported: true
+ namespace: "resource_manager"
+ description: "Feature flag for supporting minor version in Resources"
+ bug: "373535266"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/content/res/loader/ResourcesProvider.java b/core/java/android/content/res/loader/ResourcesProvider.java
index b097bc0dcd8c..830b7e0fa2d0 100644
--- a/core/java/android/content/res/loader/ResourcesProvider.java
+++ b/core/java/android/content/res/loader/ResourcesProvider.java
@@ -90,8 +90,6 @@ public class ResourcesProvider implements AutoCloseable, Closeable {
throws IOException {
Objects.requireNonNull(overlayInfo);
Preconditions.checkArgument(overlayInfo.isFabricated(), "Not accepted overlay");
- Preconditions.checkStringNotEmpty(
- overlayInfo.getTargetOverlayableName(), "Without overlayable name");
final String overlayName =
OverlayManagerImpl.checkOverlayNameValid(overlayInfo.getOverlayName());
final String path =
diff --git a/core/java/android/hardware/contexthub/HubEndpointInfo.java b/core/java/android/hardware/contexthub/HubEndpointInfo.java
index b1d55239ac43..5265d5663459 100644
--- a/core/java/android/hardware/contexthub/HubEndpointInfo.java
+++ b/core/java/android/hardware/contexthub/HubEndpointInfo.java
@@ -156,7 +156,7 @@ public final class HubEndpointInfo implements Parcelable {
mRequiredPermissions = Arrays.asList(endpointInfo.requiredPermissions);
mHubServiceInfos = new ArrayList<>(endpointInfo.services.length);
for (int i = 0; i < endpointInfo.services.length; i++) {
- mHubServiceInfos.set(i, new HubServiceInfo(endpointInfo.services[i]));
+ mHubServiceInfos.add(new HubServiceInfo(endpointInfo.services[i]));
}
}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 3284761eb273..ed510e467f82 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -281,4 +281,6 @@ interface IInputManager {
AidlInputGestureData[] getCustomInputGestures(int userId, int tag);
AidlInputGestureData[] getAppLaunchBookmarks();
+
+ void resetLockedModifierState();
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index f8241925dff0..10224c1be788 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -260,7 +260,7 @@ public final class InputManager {
}
/**
- * Custom input gesture error: Input gesture already exists
+ * Custom input gesture result success
*
* @hide
*/
@@ -1590,6 +1590,21 @@ public final class InputManager {
}
/**
+ * Resets locked modifier state (i.e.. Caps Lock, Num Lock, Scroll Lock state)
+ *
+ * @hide
+ */
+ @TestApi
+ @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+ public void resetLockedModifierState() {
+ try {
+ mIm.resetLockedModifierState();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* A callback used to be notified about battery state changes for an input device. The
* {@link #onBatteryStateChanged(int, long, BatteryState)} method will be called once after the
* listener is successfully registered to provide the initial battery state of the device.
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 71b60cff9367..114459e5e819 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -31,7 +31,7 @@ import static com.android.hardware.input.Flags.touchpadTapDragging;
import static com.android.hardware.input.Flags.touchpadThreeFingerTapShortcut;
import static com.android.hardware.input.Flags.touchpadVisualizer;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
-import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
+import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiKeyGestures;
import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
import static com.android.input.flags.Flags.enableInputFilterRustImpl;
import static com.android.input.flags.Flags.keyboardRepeatKeys;
@@ -522,8 +522,11 @@ public class InputSettings {
* @hide
*/
public static boolean useTouchpadThreeFingerTapShortcut(@NonNull Context context) {
- // TODO(b/365063048): determine whether to enable the shortcut based on the settings.
- return isTouchpadThreeFingerTapShortcutFeatureFlagEnabled();
+ int customizedShortcut = Settings.System.getIntForUser(context.getContentResolver(),
+ Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED, UserHandle.USER_CURRENT);
+ return customizedShortcut != KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED
+ && isTouchpadThreeFingerTapShortcutFeatureFlagEnabled();
}
/**
@@ -1155,6 +1158,6 @@ public class InputSettings {
* @hide
*/
public static boolean doesKeyGestureEventHandlerSupportMultiKeyGestures() {
- return useKeyGestureEventHandler() && useKeyGestureEventHandlerMultiPressGestures();
+ return useKeyGestureEventHandler() && useKeyGestureEventHandlerMultiKeyGestures();
}
}
diff --git a/core/java/android/hardware/input/KeyGlyphMap.java b/core/java/android/hardware/input/KeyGlyphMap.java
index f82d1cf276b9..de5df9188c17 100644
--- a/core/java/android/hardware/input/KeyGlyphMap.java
+++ b/core/java/android/hardware/input/KeyGlyphMap.java
@@ -133,6 +133,14 @@ public final class KeyGlyphMap implements Parcelable {
}
};
+ public int getModifierState() {
+ return mModifierState;
+ }
+
+ public int getKeycode() {
+ return mKeycode;
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index fee074901c10..0c89059a475a 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -88,6 +88,17 @@ flag {
}
flag {
+ name: "input_manager_lifecycle_support"
+ namespace: "input"
+ description: "Add support for Lifecycle support in input manager"
+ bug: "362473586"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
namespace: "input_native"
name: "manage_key_gestures"
description: "Manage key gestures through Input APIs"
@@ -103,8 +114,8 @@ flag {
}
flag {
- namespace: "input_native"
- name: "use_key_gesture_event_handler_multi_press_gestures"
+ namespace: "input"
+ name: "use_key_gesture_event_handler_multi_key_gestures"
description: "Use KeyGestureEvent handler APIs to control multi key press gestures"
bug: "358569822"
}
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index 4bc5bd2427ea..26308f69cfbe 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -16,6 +16,9 @@
package android.inputmethodservice;
+import static android.view.inputmethod.Flags.FLAG_VERIFY_KEY_EVENT;
+
+import android.annotation.FlaggedApi;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -193,6 +196,12 @@ public abstract class AbstractInputMethodService extends WindowProviderService
}
}
+ @FlaggedApi(FLAG_VERIFY_KEY_EVENT)
+ @Override
+ public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) {
+ return AbstractInputMethodService.this.onShouldVerifyKeyEvent(event);
+ }
+
/**
* Take care of dispatching incoming trackball events to the appropriate
* callbacks on the service, and tell the client when this is done.
@@ -308,6 +317,14 @@ public abstract class AbstractInputMethodService extends WindowProviderService
return false;
}
+ /**
+ * @see InputMethodService#onShouldVerifyKeyEvent(KeyEvent)
+ */
+ @FlaggedApi(FLAG_VERIFY_KEY_EVENT)
+ public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) {
+ return false;
+ }
+
/** @hide */
@Override
public final int getWindowType() {
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 62b131af74fe..9b37533f5b02 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -16,12 +16,16 @@
package android.inputmethodservice;
+import static android.view.inputmethod.Flags.verifyKeyEvent;
+
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Rect;
+import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.Looper;
import android.os.Message;
+import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
import android.view.InputChannel;
@@ -41,6 +45,8 @@ import com.android.internal.inputmethod.IRemoteInputConnection;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
+import java.util.Objects;
+
class IInputMethodSessionWrapper extends IInputMethodSession.Stub
implements HandlerCaller.Callback {
private static final String TAG = "InputMethodWrapper";
@@ -56,6 +62,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
private static final int DO_REMOVE_IME_SURFACE = 130;
private static final int DO_FINISH_INPUT = 140;
private static final int DO_INVALIDATE_INPUT = 150;
+ private final Context mContext;
@UnsupportedAppUsage
@@ -66,6 +73,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
public IInputMethodSessionWrapper(Context context,
InputMethodSession inputMethodSession, InputChannel channel) {
+ mContext = context;
mCaller = new HandlerCaller(context, null,
this, true /*asyncHandler*/);
mInputMethodSession = inputMethodSession;
@@ -233,6 +241,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
}
private final class ImeInputEventReceiver extends InputEventReceiver
implements InputMethodSession.EventCallback {
+ // Time after which a KeyEvent is invalid
+ private static final long KEY_EVENT_ALLOW_PERIOD_MS = 100L;
private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>();
public ImeInputEventReceiver(InputChannel inputChannel, Looper looper) {
@@ -247,10 +257,23 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
return;
}
+ if (event instanceof KeyEvent keyEvent && needsVerification(keyEvent)) {
+ // any KeyEvent with modifiers (e.g. Ctrl/Alt/Fn) must be verified that
+ // they originated from system.
+ InputManager im = mContext.getSystemService(InputManager.class);
+ Objects.requireNonNull(im);
+ final long age = SystemClock.uptimeMillis() - keyEvent.getEventTime();
+ if (age >= KEY_EVENT_ALLOW_PERIOD_MS && im.verifyInputEvent(keyEvent) == null) {
+ Log.w(TAG, "Unverified or Invalid KeyEvent injected into IME. Dropping "
+ + keyEvent);
+ finishInputEvent(event, false /* handled */);
+ return;
+ }
+ }
+
final int seq = event.getSequenceNumber();
mPendingEvents.put(seq, event);
- if (event instanceof KeyEvent) {
- KeyEvent keyEvent = (KeyEvent)event;
+ if (event instanceof KeyEvent keyEvent) {
mInputMethodSession.dispatchKeyEvent(seq, keyEvent, this);
} else {
MotionEvent motionEvent = (MotionEvent)event;
@@ -271,5 +294,21 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
finishInputEvent(event, handled);
}
}
+
+ private boolean hasKeyModifiers(KeyEvent event) {
+ if (event.hasNoModifiers()) {
+ return false;
+ }
+ return event.hasModifiers(KeyEvent.META_CTRL_ON)
+ || event.hasModifiers(KeyEvent.META_ALT_ON)
+ || event.hasModifiers(KeyEvent.KEYCODE_FUNCTION);
+ }
+
+ private boolean needsVerification(KeyEvent event) {
+ //TODO(b/331730488): Handle a11y events as well.
+ return verifyKeyEvent()
+ && (hasKeyModifiers(event)
+ || mInputMethodSession.onShouldVerifyKeyEvent(event));
+ }
}
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index dadb5c386b76..4bde8e2b44ee 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -56,6 +56,7 @@ import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECT
import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED;
import static android.view.inputmethod.Flags.FLAG_CONNECTIONLESS_HANDWRITING;
import static android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API;
+import static android.view.inputmethod.Flags.FLAG_VERIFY_KEY_EVENT;
import static android.view.inputmethod.Flags.ctrlShiftShortcut;
import static android.view.inputmethod.Flags.predictiveBackIme;
@@ -407,6 +408,12 @@ public class InputMethodService extends AbstractInputMethodService {
private boolean mUsingCtrlShiftShortcut = false;
/**
+ * Last handwriting bounds used for stylus handwriting
+ * {@link #setStylusHandwritingRegion(Region)}.
+ */
+ private Region mLastHandwritingRegion;
+
+ /**
* Returns whether {@link InputMethodService} is responsible for rendering the back button and
* the IME switcher button or not when the gestural navigation is enabled.
*
@@ -1532,6 +1539,7 @@ public class InputMethodService extends AbstractInputMethodService {
return;
}
editorInfo.makeCompatible(getApplicationInfo().targetSdkVersion);
+ mLastHandwritingRegion = null;
getInputMethodInternal().restartInput(new RemoteInputConnection(ric, sessionId),
editorInfo);
}
@@ -2840,6 +2848,7 @@ public class InputMethodService extends AbstractInputMethodService {
mHandler.removeCallbacks(mFinishHwRunnable);
}
mFinishHwRunnable = null;
+ mLastHandwritingRegion = null;
final int requestId = mHandwritingRequestId.getAsInt();
mHandwritingRequestId = OptionalInt.empty();
@@ -3166,6 +3175,40 @@ public class InputMethodService extends AbstractInputMethodService {
registerDefaultOnBackInvokedCallback();
}
+ /**
+ * Sets a new stylus handwriting region as user continues to write on an editor on screen.
+ * Stylus strokes that are started within the {@code touchableRegion} are treated as
+ * continuation of handwriting and all the events outside are passed-through to the IME target
+ * app, causing stylus handwriting to finish {@link #finishStylusHandwriting()}.
+ * By default, {@link WindowManager#getMaximumWindowMetrics()} is handwritable and
+ * {@code touchableRegion} resets after each handwriting session.
+ * <p>
+ * For example, the IME can use this API to dynamically expand the stylus handwriting region on
+ * every stylus stroke as user continues to write on an editor. The region should grow around
+ * the last stroke so that a UI element below the IME window is still interactable when it is
+ * spaced sufficiently away (~2 character dimensions) from last stroke.
+ * </p>
+ * <p>
+ * Note: Setting handwriting touchable region is supported on IMEs that support stylus
+ * handwriting {@link InputMethodInfo#supportsStylusHandwriting()}.
+ * </p>
+ *
+ * @param handwritingRegion new stylus handwritable {@link Region} that can accept stylus touch.
+ */
+ @FlaggedApi(Flags.FLAG_ADAPTIVE_HANDWRITING_BOUNDS)
+ public final void setStylusHandwritingRegion(@NonNull Region handwritingRegion) {
+ if (handwritingRegion.equals(mLastHandwritingRegion)) {
+ Log.v(TAG, "Failed to set setStylusHandwritingRegion():"
+ + " same region set twice.");
+ return;
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "Setting new handwriting region for stylus handwriting "
+ + handwritingRegion + " from last " + mLastHandwritingRegion);
+ }
+ mLastHandwritingRegion = handwritingRegion;
+ }
/**
* Registers an {@link OnBackInvokedCallback} to handle back invocation when ahead-of-time
@@ -3735,6 +3778,23 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
+ * Received by the IME before dispatch to {@link #onKeyDown(int, KeyEvent)} to let the system
+ * know if the {@link KeyEvent} needs to be verified that it originated from the system.
+ * {@link KeyEvent}s may originate from outside of the system and any sensitive keys should be
+ * marked for verification. One example of this could be using key shortcuts for switching to
+ * another IME.
+ *
+ * @param keyEvent the event that may need verification.
+ * @return {@code true} if {@link KeyEvent} should have its HMAC verified before dispatch,
+ * {@code false} otherwise.
+ */
+ @FlaggedApi(FLAG_VERIFY_KEY_EVENT)
+ @Override
+ public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent keyEvent) {
+ return false;
+ }
+
+ /**
* Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
* KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
* the event).
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index 1b2c575917b2..b461f95fec53 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -1,5 +1,5 @@
package: "android.net.vcn"
-container: "system"
+container: "com.android.tethering"
flag {
name: "safe_mode_config"
@@ -15,14 +15,4 @@ flag {
description: "Expose APIs from VCN for mainline migration"
is_exported: true
bug: "376339506"
-}
-
-flag {
- name: "fix_config_garbage_collection"
- namespace: "vcn"
- description: "Handle race condition in subscription change"
- bug: "370862489"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
} \ No newline at end of file
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 3b5a99ed089a..01222cdd38b3 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -36,6 +36,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -651,28 +652,39 @@ public final class BinderProxy implements IBinder {
private native boolean unlinkToDeathNative(DeathRecipient recipient, int flags);
/**
- * This list is to hold strong reference to the frozen state callbacks. The callbacks are only
- * weakly referenced by JNI so the strong references here are needed to keep the callbacks
- * around until the proxy is GC'ed.
+ * This map is to hold strong reference to the frozen state callbacks.
+ *
+ * The callbacks are only weakly referenced by JNI so the strong references here are needed to
+ * keep the callbacks around until the proxy is GC'ed.
+ *
+ * The key is the original callback passed into {@link #addFrozenStateChangeCallback}. The value
+ * is the wrapped callback created in {@link #addFrozenStateChangeCallback} to dispatch the
+ * calls on the desired executor.
*/
- private List<FrozenStateChangeCallback> mFrozenStateChangeCallbacks =
- Collections.synchronizedList(new ArrayList<>());
+ private Map<FrozenStateChangeCallback, FrozenStateChangeCallback> mFrozenStateChangeCallbacks =
+ Collections.synchronizedMap(new HashMap<>());
/**
* See {@link IBinder#addFrozenStateChangeCallback(FrozenStateChangeCallback)}
*/
- public void addFrozenStateChangeCallback(FrozenStateChangeCallback callback)
+ public void addFrozenStateChangeCallback(Executor executor, FrozenStateChangeCallback callback)
throws RemoteException {
- addFrozenStateChangeCallbackNative(callback);
- mFrozenStateChangeCallbacks.add(callback);
+ FrozenStateChangeCallback wrappedCallback = (who, state) ->
+ executor.execute(() -> callback.onFrozenStateChanged(who, state));
+ addFrozenStateChangeCallbackNative(wrappedCallback);
+ mFrozenStateChangeCallbacks.put(callback, wrappedCallback);
}
/**
* See {@link IBinder#removeFrozenStateChangeCallback}
*/
- public boolean removeFrozenStateChangeCallback(FrozenStateChangeCallback callback) {
- mFrozenStateChangeCallbacks.remove(callback);
- return removeFrozenStateChangeCallbackNative(callback);
+ public boolean removeFrozenStateChangeCallback(FrozenStateChangeCallback callback)
+ throws IllegalArgumentException {
+ FrozenStateChangeCallback wrappedCallback = mFrozenStateChangeCallbacks.remove(callback);
+ if (wrappedCallback == null) {
+ throw new IllegalArgumentException("callback not found");
+ }
+ return removeFrozenStateChangeCallbackNative(wrappedCallback);
}
private native void addFrozenStateChangeCallbackNative(FrozenStateChangeCallback callback)
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 036ccd84a600..4c9f08d80d4b 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -123,11 +123,6 @@ public final class MessageQueue {
// We can lift this restriction in the future after we've made it possible for test authors
// to test Looper and MessageQueue without resorting to reflection.
- // Holdback study.
- if (mUseConcurrent && Flags.messageQueueForceLegacy()) {
- mUseConcurrent = false;
- }
-
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index a997f4c86704..8cfd32449537 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -25,6 +26,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import java.io.FileDescriptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
/**
* Base interface for a remotable object, the core part of a lightweight
@@ -397,12 +399,31 @@ public interface IBinder {
@interface State {
}
+ /**
+ * Represents the frozen state of the remote process.
+ *
+ * While in this state, the remote process won't be able to receive and handle a
+ * transaction. Therefore, any asynchronous transactions will be buffered and delivered when
+ * the process is unfrozen, and any synchronous transactions will result in an error.
+ *
+ * Buffered transactions may be stale by the time that the process is unfrozen and handles
+ * them. To avoid overwhelming the remote process with stale events or overflowing their
+ * buffers, it's best to avoid sending binder transactions to a frozen process.
+ */
int STATE_FROZEN = 0;
+
+ /**
+ * Represents the unfrozen state of the remote process.
+ *
+ * In this state, the process hosting the object can execute and is not restricted
+ * by the freezer from using the CPU or responding to binder transactions.
+ */
int STATE_UNFROZEN = 1;
/**
* Interface for receiving a callback when the process hosting an IBinder
* has changed its frozen state.
+ *
* @param who The IBinder whose hosting process has changed state.
* @param state The latest state.
*/
@@ -427,16 +448,32 @@ public interface IBinder {
* <p>You will only receive state change notifications for remote binders, as local binders by
* definition can't be frozen without you being frozen too.</p>
*
+ * @param executor The executor on which to run the callback.
+ * @param callback The callback used to deliver state change notifications.
+ *
* <p>@throws {@link UnsupportedOperationException} if the kernel binder driver does not support
* this feature.
*/
@FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK)
- default void addFrozenStateChangeCallback(@NonNull FrozenStateChangeCallback callback)
+ default void addFrozenStateChangeCallback(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull FrozenStateChangeCallback callback)
throws RemoteException {
throw new UnsupportedOperationException();
}
/**
+ * Same as {@link #addFrozenStateChangeCallback(Executor, FrozenStateChangeCallback)} except
+ * that callbacks are invoked on a binder thread.
+ *
+ * @hide
+ */
+ default void addFrozenStateChangeCallback(@NonNull FrozenStateChangeCallback callback)
+ throws RemoteException {
+ addFrozenStateChangeCallback(Runnable::run, callback);
+ }
+
+ /**
* Unregister a {@link FrozenStateChangeCallback}. The callback will no longer be invoked when
* the hosting process changes its frozen state.
*/
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 33120556339f..a043da9b7a36 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -20,6 +20,7 @@ package android.os;
import android.os.CpuHeadroomParamsInternal;
import android.os.GpuHeadroomParamsInternal;
import android.os.IHintSession;
+import android.os.SessionCreationConfig;
import android.hardware.power.ChannelConfig;
import android.hardware.power.SessionConfig;
import android.hardware.power.SessionTag;
@@ -34,8 +35,8 @@ interface IHintManager {
* Throws UnsupportedOperationException if ADPF is not supported, and IllegalStateException
* if creation is supported but fails.
*/
- IHintSession createHintSessionWithConfig(in IBinder token, in int[] threadIds,
- in long durationNanos, in SessionTag tag, out SessionConfig config);
+ IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
+ in SessionCreationConfig creationConfig, out SessionConfig config);
/**
* Get preferred rate limit in nanoseconds.
@@ -56,4 +57,9 @@ interface IHintManager {
long getCpuHeadroomMinIntervalMillis();
float getGpuHeadroom(in GpuHeadroomParamsInternal params);
long getGpuHeadroomMinIntervalMillis();
+
+ /**
+ * Get Maximum number of graphics pipeline threads allowed per-app.
+ */
+ int getMaxGraphicsPipelineThreadsCount();
}
diff --git a/core/java/android/os/PerformanceHintManager.java b/core/java/android/os/PerformanceHintManager.java
index 224b10d0eaca..2b0042d653b1 100644
--- a/core/java/android/os/PerformanceHintManager.java
+++ b/core/java/android/os/PerformanceHintManager.java
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import com.android.internal.util.Preconditions;
@@ -106,7 +107,9 @@ public final class PerformanceHintManager {
* All timings should be in {@link SystemClock#uptimeNanos()}.
*/
public static class Session implements Closeable {
- private long mNativeSessionPtr;
+ /** @hide */
+ @UnsupportedAppUsage
+ public long mNativeSessionPtr;
/** @hide */
public Session(long nativeSessionPtr) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 07fded19c799..9e7bf47ae83f 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1823,14 +1823,16 @@ public final class PowerManager {
}
/**
- * Returns the interactive state for a specific display, which may not be the same as the
- * global wakefulness (which is true when any display is awake).
+ * Returns true if the specified display is in an interactive state. This may not be the
+ * same as the global wakefulness (which is true when any display is interactive).
+ * @see #isInteractive()
*
- * @param displayId
- * @return whether the given display is present and interactive, or false
+ * @param displayId The Display ID to check for interactivity.
+ * @return True if the display is in an interactive state.
*
* @hide
*/
+ @TestApi
public boolean isInteractive(int displayId) {
return mInteractiveCache.query(displayId);
}
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index 91c482faf7d7..4123209eb755 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -29,6 +30,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -134,6 +136,7 @@ public class RemoteCallbackList<E extends IInterface> {
private final @FrozenCalleePolicy int mFrozenCalleePolicy;
private final int mMaxQueueSize;
+ private final Executor mExecutor;
private final class Interface implements IBinder.DeathRecipient,
IBinder.FrozenStateChangeCallback {
@@ -197,7 +200,7 @@ public class RemoteCallbackList<E extends IInterface> {
void maybeSubscribeToFrozenCallback() throws RemoteException {
if (mFrozenCalleePolicy != FROZEN_CALLEE_POLICY_UNSET) {
try {
- mBinder.addFrozenStateChangeCallback(this);
+ mBinder.addFrozenStateChangeCallback(mExecutor, this);
} catch (UnsupportedOperationException e) {
// The kernel does not support frozen notifications. In this case we want to
// silently fall back to FROZEN_CALLEE_POLICY_UNSET. This is done by simply
@@ -211,7 +214,7 @@ public class RemoteCallbackList<E extends IInterface> {
if (mFrozenCalleePolicy != FROZEN_CALLEE_POLICY_UNSET) {
try {
mBinder.removeFrozenStateChangeCallback(this);
- } catch (UnsupportedOperationException e) {
+ } catch (UnsupportedOperationException | IllegalArgumentException e) {
// The kernel does not support frozen notifications. Ignore the error and move
// on.
}
@@ -237,6 +240,7 @@ public class RemoteCallbackList<E extends IInterface> {
private @FrozenCalleePolicy int mFrozenCalleePolicy;
private int mMaxQueueSize = DEFAULT_MAX_QUEUE_SIZE;
private InterfaceDiedCallback mInterfaceDiedCallback;
+ private Executor mExecutor;
/**
* Creates a Builder for {@link RemoteCallbackList}.
@@ -285,6 +289,18 @@ public class RemoteCallbackList<E extends IInterface> {
}
/**
+ * Sets the executor to be used when invoking callbacks asynchronously.
+ *
+ * This is only used when callbacks need to be invoked asynchronously, e.g. when the process
+ * hosting a callback becomes unfrozen. Callbacks that can be invoked immediately run on the
+ * same thread that calls {@link #broadcast} synchronously.
+ */
+ public @NonNull Builder setExecutor(@NonNull @CallbackExecutor Executor executor) {
+ mExecutor = executor;
+ return this;
+ }
+
+ /**
* For notifying when the process hosting a callback interface has died.
*
* @param <E> The remote callback interface type.
@@ -308,15 +324,21 @@ public class RemoteCallbackList<E extends IInterface> {
* @return The built {@link RemoteCallbackList} object.
*/
public @NonNull RemoteCallbackList<E> build() {
+ Executor executor = mExecutor;
+ if (executor == null && mFrozenCalleePolicy != FROZEN_CALLEE_POLICY_UNSET) {
+ // TODO Throw an exception here once the existing API caller is updated to provide
+ // an executor.
+ executor = new HandlerExecutor(Handler.getMain());
+ }
if (mInterfaceDiedCallback != null) {
- return new RemoteCallbackList<E>(mFrozenCalleePolicy, mMaxQueueSize) {
+ return new RemoteCallbackList<E>(mFrozenCalleePolicy, mMaxQueueSize, executor) {
@Override
public void onCallbackDied(E deadInterface, Object cookie) {
mInterfaceDiedCallback.onInterfaceDied(this, deadInterface, cookie);
}
};
}
- return new RemoteCallbackList<E>(mFrozenCalleePolicy, mMaxQueueSize);
+ return new RemoteCallbackList<E>(mFrozenCalleePolicy, mMaxQueueSize, executor);
}
}
@@ -341,13 +363,23 @@ public class RemoteCallbackList<E extends IInterface> {
}
/**
+ * Returns the executor used when invoking callbacks asynchronously.
+ *
+ * @return The executor.
+ */
+ @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK)
+ public @Nullable Executor getExecutor() {
+ return mExecutor;
+ }
+
+ /**
* Creates a RemoteCallbackList with {@link #FROZEN_CALLEE_POLICY_UNSET}. This is equivalent to
* <pre>
* new RemoteCallbackList.Build(RemoteCallbackList.FROZEN_CALLEE_POLICY_UNSET).build()
* </pre>
*/
public RemoteCallbackList() {
- this(FROZEN_CALLEE_POLICY_UNSET, DEFAULT_MAX_QUEUE_SIZE);
+ this(FROZEN_CALLEE_POLICY_UNSET, DEFAULT_MAX_QUEUE_SIZE, null);
}
/**
@@ -362,10 +394,14 @@ public class RemoteCallbackList<E extends IInterface> {
* recipient's process is frozen. Once the limit is reached, the oldest callbacks would be
* dropped to keep the size under limit. Ignored except for
* {@link #FROZEN_CALLEE_POLICY_ENQUEUE_ALL}.
+ *
+ * @param executor The executor used when invoking callbacks asynchronously.
*/
- private RemoteCallbackList(@FrozenCalleePolicy int frozenCalleePolicy, int maxQueueSize) {
+ private RemoteCallbackList(@FrozenCalleePolicy int frozenCalleePolicy, int maxQueueSize,
+ @CallbackExecutor Executor executor) {
mFrozenCalleePolicy = frozenCalleePolicy;
mMaxQueueSize = maxQueueSize;
+ mExecutor = executor;
}
/**
diff --git a/core/java/android/os/SessionCreationConfig.aidl b/core/java/android/os/SessionCreationConfig.aidl
new file mode 100644
index 000000000000..cdc0ef461e0c
--- /dev/null
+++ b/core/java/android/os/SessionCreationConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.hardware.power.SessionTag;
+import android.hardware.power.SessionMode;
+
+/** {@hide} */
+parcelable SessionCreationConfig {
+ /**
+ * List of tids to be included in the hint session.
+ */
+ int[] tids;
+
+ /**
+ * The initial target work duration of this hint session in nanoseconds.
+ */
+ long targetWorkDurationNanos;
+
+ /**
+ * List of the modes to be enabled upon session creation.
+ */
+ SessionMode[] modesToEnable;
+}
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index f6bc3894be4b..0a0e80614fa7 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -18,6 +18,7 @@ package android.os;
import static android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS;
+import android.annotation.DurationMillisLong;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -34,6 +35,7 @@ import android.hardware.vibrator.IVibrator;
import android.hardware.vibrator.V1_0.EffectStrength;
import android.hardware.vibrator.V1_3.Effect;
import android.net.Uri;
+import android.os.vibrator.BasicPwleSegment;
import android.os.vibrator.Flags;
import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.PrimitiveSegment;
@@ -1713,10 +1715,13 @@ public abstract class VibrationEffect implements Parcelable {
/**
* Add a haptic primitive to the end of the current composition.
*
+ * <p>Similar to {@link #addPrimitive(int, float, int, int)}, but default
+ * delay type applied is {@link #DELAY_TYPE_PAUSE}.
+ *
* @param primitiveId The primitive to add
* @param scale The scale to apply to the intensity of the primitive.
- * @param delay The amount of time in milliseconds to wait before playing this primitive,
- * starting at the time the previous element in this composition is finished.
+ * @param delay The amount of time in milliseconds to wait between the end of the last
+ * primitive and the beginning of this one (i.e. a pause in the composition).
* @return This {@link Composition} object to enable adding multiple elements in one chain.
*/
@NonNull
@@ -1843,6 +1848,8 @@ public abstract class VibrationEffect implements Parcelable {
* .build();
* }</pre>
*
+ * <p>The builder automatically starts all effects at 0 amplitude.
+ *
* <p>It is crucial to ensure that the frequency range used in your effect is compatible with
* the device's capabilities. The framework will not play any frequencies that fall partially
* or completely outside the device's supported range. It will also not attempt to correct or
@@ -1908,7 +1915,7 @@ public abstract class VibrationEffect implements Parcelable {
firstSegment.getEndAmplitude(),
initialFrequencyHz, // Update start frequency
firstSegment.getEndFrequencyHz(),
- (int) firstSegment.getDuration()));
+ firstSegment.getDuration()));
}
return this;
@@ -1930,25 +1937,26 @@ public abstract class VibrationEffect implements Parcelable {
* transition as quickly as possible, use
* {@link VibratorEnvelopeEffectInfo#getMinControlPointDurationMillis()}.
*
- * @param amplitude The amplitude value between 0 and 1, inclusive. 0 represents the
- * vibrator being off, and 1 represents the maximum achievable amplitude
- * at this frequency.
- * @param frequencyHz The frequency in Hz, must be greater than zero.
- * @param timeMillis The transition time in milliseconds.
+ * @param amplitude The amplitude value between 0 and 1, inclusive. 0 represents the
+ * vibrator being off, and 1 represents the maximum achievable
+ * amplitude
+ * at this frequency.
+ * @param frequencyHz The frequency in Hz, must be greater than zero.
+ * @param durationMillis The transition time in milliseconds.
*/
@FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
@SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
@NonNull
public WaveformEnvelopeBuilder addControlPoint(
@FloatRange(from = 0, to = 1) float amplitude,
- @FloatRange(from = 0) float frequencyHz, int timeMillis) {
+ @FloatRange(from = 0) float frequencyHz, @DurationMillisLong long durationMillis) {
if (Float.isNaN(mLastFrequencyHz)) {
mLastFrequencyHz = frequencyHz;
}
mSegments.add(new PwleSegment(mLastAmplitude, amplitude, mLastFrequencyHz, frequencyHz,
- timeMillis));
+ durationMillis));
mLastAmplitude = amplitude;
mLastFrequencyHz = frequencyHz;
@@ -1980,6 +1988,168 @@ public abstract class VibrationEffect implements Parcelable {
}
/**
+ * A builder for waveform effects defined by their envelope, designed to provide a consistent
+ * haptic perception across devices with varying capabilities.
+ *
+ * <p>This builder simplifies the creation of waveform effects by automatically adapting them
+ * to different devices based on their capabilities. Effects are defined by control points
+ * specifying target vibration intensity and sharpness, along with durations to reach those
+ * targets. The vibrator will smoothly transition between these control points.
+ *
+ * <p><b>Intensity:</b> Defines the overall strength of the vibration, ranging from
+ * 0 (off) to 1 (maximum achievable strength). Higher values result in stronger
+ * vibrations. Supported intensity values guarantee sensitivity levels (SL) above
+ * 10 dB SL to ensure human perception.
+ *
+ * <p><b>Sharpness:</b> Defines the crispness of the vibration, ranging from 0 to 1.
+ * Lower values produce smoother vibrations, while higher values create a sharper,
+ * more snappy sensation. Sharpness is mapped to its equivalent frequency within
+ * the device's supported frequency range.
+ *
+ * <p>While this builder handles most of the adaptation logic, it does come with some
+ * limitations:
+ * <ul>
+ * <li>It may not use the full range of frequencies</li>
+ * <li>It's restricted to a frequency range that can generate output of at least 10 db
+ * SL</li>
+ * <li>Effects must end with a zero intensity control point. Failure to end at a zero
+ * intensity control point will result in an {@link IllegalStateException}.</li>
+ * </ul>
+ *
+ * <p>The builder automatically starts all effects at 0 intensity.
+ *
+ * <p>To avoid these limitations and to have more control over the effects output, use
+ * {@link WaveformEnvelopeBuilder}, where direct amplitude and frequency values can be used.
+ *
+ * <p>For optimal cross-device consistency, it's recommended to limit the number of control
+ * points to a maximum of 16. However this is not mandatory, and if a pattern exceeds the
+ * maximum number of allowed control points, the framework will automatically break down the
+ * effect to ensure it plays correctly.
+ *
+ * <p>For example, the following code creates a vibration effect that ramps up the intensity
+ * from a low-pitched to a high-pitched strong vibration over 500ms and then ramps it down to
+ * 0 (off) over 100ms:
+ *
+ * <pre>{@code
+ * VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
+ * .setInitialSharpness(0.0f)
+ * .addControlPoint(1.0f, 1.0f, 500)
+ * .addControlPoint(0.0f, 1.0f, 100)
+ * .build();
+ * }</pre>
+ */
+ @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public static final class BasicEnvelopeBuilder {
+
+ private ArrayList<BasicPwleSegment> mSegments = new ArrayList<>();
+ private float mLastIntensity = 0f;
+ private float mLastSharpness = Float.NaN;
+
+ public BasicEnvelopeBuilder() {}
+
+ /**
+ * Sets the initial sharpness for the basic envelope effect.
+ *
+ * <p>The effect will start vibrating at this sharpness when it transitions to the
+ * intensity and sharpness defined by the first control point.
+ *
+ * <p> The sharpness defines the crispness of the vibration, ranging from 0 to 1. Lower
+ * values translate to smoother vibrations, while higher values create a sharper more snappy
+ * sensation. This value is mapped to the supported frequency range of the device.
+ *
+ * @param initialSharpness The starting sharpness of the vibration in the range of [0, 1].
+ */
+ @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ @SuppressWarnings("MissingGetterMatchingBuilder")// No getter to initial sharpness once set.
+ @NonNull
+ public BasicEnvelopeBuilder setInitialSharpness(
+ @FloatRange(from = 0, to = 1) float initialSharpness) {
+
+ if (mSegments.isEmpty()) {
+ mLastSharpness = initialSharpness;
+ } else {
+ BasicPwleSegment firstSegment = mSegments.getFirst();
+ mSegments.set(0, new BasicPwleSegment(
+ firstSegment.getStartIntensity(),
+ firstSegment.getEndIntensity(),
+ initialSharpness, // Update start sharpness
+ firstSegment.getEndSharpness(),
+ firstSegment.getDuration()));
+ }
+
+ return this;
+ }
+
+ /**
+ * Adds a new control point to the end of this waveform envelope.
+ *
+ * <p>Intensity defines the overall strength of the vibration, ranging from 0 (off) to 1
+ * (maximum achievable strength). Higher values translate to stronger vibrations.
+ *
+ * <p>Sharpness defines the crispness of the vibration, ranging from 0 to 1. Lower
+ * values translate to smoother vibrations, while higher values create a sharper more snappy
+ * sensation. This value is mapped to the supported frequency range of the device.
+ *
+ * <p>Time specifies the duration (in milliseconds) for the vibrator to smoothly transition
+ * from the previous control point to this new one. It must be greater than zero. To
+ * transition as quickly as possible, use
+ * {@link VibratorEnvelopeEffectInfo#getMinControlPointDurationMillis()}.
+ *
+ * @param intensity The target vibration intensity, ranging from 0 (off) to 1 (maximum
+ * strength).
+ * @param sharpness The target sharpness, ranging from 0 (smoothest) to 1 (sharpest).
+ * @param durationMillis The transition time in milliseconds.
+ */
+ @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ @SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
+ @NonNull
+ public BasicEnvelopeBuilder addControlPoint(
+ @FloatRange(from = 0, to = 1) float intensity,
+ @FloatRange(from = 0, to = 1) float sharpness,
+ @DurationMillisLong long durationMillis) {
+
+ if (Float.isNaN(mLastSharpness)) {
+ mLastSharpness = sharpness;
+ }
+
+ mSegments.add(new BasicPwleSegment(mLastIntensity, intensity, mLastSharpness, sharpness,
+ durationMillis));
+
+ mLastIntensity = intensity;
+ mLastSharpness = sharpness;
+
+ return this;
+ }
+
+ /**
+ * Build the waveform as a single {@link VibrationEffect}.
+ *
+ * <p>The {@link BasicEnvelopeBuilder} object is still valid after this call, so you can
+ * continue adding more primitives to it and generating more {@link VibrationEffect}s by
+ * calling this method again.
+ *
+ * @return The {@link VibrationEffect} resulting from the list of control points.
+ * @throws IllegalStateException if the last control point does not end at zero intensity.
+ */
+ @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ @NonNull
+ public VibrationEffect build() {
+ if (mSegments.isEmpty()) {
+ throw new IllegalStateException(
+ "BasicEnvelopeBuilder must have at least one control point to build.");
+ }
+ if (mSegments.getLast().getEndIntensity() != 0) {
+ throw new IllegalStateException(
+ "Basic envelope effects must end at a zero intensity control point.");
+ }
+ VibrationEffect effect = new Composed(mSegments, /* repeatIndex= */ -1);
+ effect.validate();
+ return effect;
+ }
+
+ }
+
+ /**
* A builder for waveform haptic effects.
*
* <p>Waveform vibrations constitute of one or more timed transitions to new sets of vibration
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 9b1bf057b815..5ac53f1bf39d 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -4,15 +4,6 @@ container: "system"
# keep-sorted start block=yes newline_separated=yes
flag {
- # Holdback study for concurrent MessageQueue.
- # Do not promote beyond trunkfood.
- namespace: "system_performance"
- name: "message_queue_force_legacy"
- description: "Whether to holdback concurrent MessageQueue (force legacy)."
- bug: "336880969"
-}
-
-flag {
name: "adpf_gpu_report_actual_work_duration"
is_exported: true
namespace: "game"
@@ -21,6 +12,15 @@ flag {
}
flag {
+ name: "adpf_graphics_pipeline"
+ is_exported: true
+ namespace: "game"
+ description: "Guards use of SessionCreationConfig and Graphics Pipeline mode"
+ is_fixed_read_only: true
+ bug: "367803904"
+}
+
+flag {
name: "adpf_hwui_gpu"
namespace: "game"
description: "Guards use of the FMQ channel for ADPF"
diff --git a/core/java/android/os/vibrator/BasicPwleSegment.java b/core/java/android/os/vibrator/BasicPwleSegment.java
new file mode 100644
index 000000000000..ed68173404a1
--- /dev/null
+++ b/core/java/android/os/vibrator/BasicPwleSegment.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.vibrator;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * A {@link VibrationEffectSegment} that represents a smooth transition from the starting
+ * intensity and sharpness to new values over a specified duration.
+ *
+ * <p>The intensity and sharpness are expressed by float values in the range [0, 1], where
+ * intensity represents the user-perceived strength of the vibration, while sharpness represents
+ * the crispness of the vibration.
+ *
+ * @hide
+ */
+@TestApi
+@FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+public final class BasicPwleSegment extends VibrationEffectSegment {
+ private final float mStartIntensity;
+ private final float mEndIntensity;
+ private final float mStartSharpness;
+ private final float mEndSharpness;
+ private final long mDuration;
+
+ BasicPwleSegment(@NonNull Parcel in) {
+ this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readLong());
+ }
+
+ /** @hide */
+ @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public BasicPwleSegment(float startIntensity, float endIntensity, float startSharpness,
+ float endSharpness, long duration) {
+ mStartIntensity = startIntensity;
+ mEndIntensity = endIntensity;
+ mStartSharpness = startSharpness;
+ mEndSharpness = endSharpness;
+ mDuration = duration;
+ }
+
+ public float getStartIntensity() {
+ return mStartIntensity;
+ }
+
+ public float getEndIntensity() {
+ return mEndIntensity;
+ }
+
+ public float getStartSharpness() {
+ return mStartSharpness;
+ }
+
+ public float getEndSharpness() {
+ return mEndSharpness;
+ }
+
+ @Override
+ public long getDuration() {
+ return mDuration;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof BasicPwleSegment)) {
+ return false;
+ }
+ BasicPwleSegment other = (BasicPwleSegment) o;
+ return Float.compare(mStartIntensity, other.mStartIntensity) == 0
+ && Float.compare(mEndIntensity, other.mEndIntensity) == 0
+ && Float.compare(mStartSharpness, other.mStartSharpness) == 0
+ && Float.compare(mEndSharpness, other.mEndSharpness) == 0
+ && mDuration == other.mDuration;
+ }
+
+ /** @hide */
+ @Override
+ public boolean areVibrationFeaturesSupported(@NonNull VibratorInfo vibratorInfo) {
+ return vibratorInfo.areEnvelopeEffectsSupported();
+ }
+
+ /** @hide */
+ @Override
+ public boolean isHapticFeedbackCandidate() {
+ return true;
+ }
+
+ /** @hide */
+ @Override
+ public void validate() {
+ Preconditions.checkArgumentInRange(mStartSharpness, 0f, 1f, "startSharpness");
+ Preconditions.checkArgumentInRange(mEndSharpness, 0f, 1f, "endSharpness");
+ Preconditions.checkArgumentInRange(mStartIntensity, 0f, 1f, "startIntensity");
+ Preconditions.checkArgumentInRange(mEndIntensity, 0f, 1f, "endIntensity");
+ Preconditions.checkArgumentPositive(mDuration, "Time must be greater than zero.");
+ }
+
+ /** @hide */
+ @NonNull
+ @Override
+ public BasicPwleSegment resolve(int defaultAmplitude) {
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ @Override
+ public BasicPwleSegment scale(float scaleFactor) {
+ float newStartIntensity = VibrationEffect.scale(mStartIntensity, scaleFactor);
+ float newEndIntensity = VibrationEffect.scale(mEndIntensity, scaleFactor);
+ if (Float.compare(mStartIntensity, newStartIntensity) == 0
+ && Float.compare(mEndIntensity, newEndIntensity) == 0) {
+ return this;
+ }
+ return new BasicPwleSegment(newStartIntensity, newEndIntensity, mStartSharpness,
+ mEndSharpness,
+ mDuration);
+ }
+
+ /** @hide */
+ @NonNull
+ @Override
+ public BasicPwleSegment scaleLinearly(float scaleFactor) {
+ float newStartIntensity = VibrationEffect.scaleLinearly(mStartIntensity, scaleFactor);
+ float newEndIntensity = VibrationEffect.scaleLinearly(mEndIntensity, scaleFactor);
+ if (Float.compare(mStartIntensity, newStartIntensity) == 0
+ && Float.compare(mEndIntensity, newEndIntensity) == 0) {
+ return this;
+ }
+ return new BasicPwleSegment(newStartIntensity, newEndIntensity, mStartSharpness,
+ mEndSharpness,
+ mDuration);
+ }
+
+ /** @hide */
+ @NonNull
+ @Override
+ public BasicPwleSegment applyEffectStrength(int effectStrength) {
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mStartIntensity, mEndIntensity, mStartSharpness, mEndSharpness,
+ mDuration);
+ }
+
+ @Override
+ public String toString() {
+ return "BasicPwle{startIntensity=" + mStartIntensity
+ + ", endIntensity=" + mEndIntensity
+ + ", startSharpness=" + mStartSharpness
+ + ", endSharpness=" + mEndSharpness
+ + ", duration=" + mDuration
+ + "}";
+ }
+
+ /** @hide */
+ @Override
+ public String toDebugString() {
+ return String.format(Locale.US, "Pwle=%dms(intensity=%.2f @ %.2f to %.2f @ %.2f)",
+ mDuration,
+ mStartIntensity,
+ mStartSharpness,
+ mEndIntensity,
+ mEndSharpness);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(PARCEL_TOKEN_PWLE);
+ dest.writeFloat(mStartIntensity);
+ dest.writeFloat(mEndIntensity);
+ dest.writeFloat(mStartSharpness);
+ dest.writeFloat(mEndSharpness);
+ dest.writeLong(mDuration);
+ }
+
+ @NonNull
+ public static final Creator<BasicPwleSegment> CREATOR =
+ new Creator<BasicPwleSegment>() {
+ @Override
+ public BasicPwleSegment createFromParcel(Parcel in) {
+ // Skip the type token
+ in.readInt();
+ return new BasicPwleSegment(in);
+ }
+
+ @Override
+ public BasicPwleSegment[] newArray(int size) {
+ return new BasicPwleSegment[size];
+ }
+ };
+}
diff --git a/core/java/android/os/vibrator/PwlePoint.java b/core/java/android/os/vibrator/PwlePoint.java
index ea3ae6c4649d..4be5c681f708 100644
--- a/core/java/android/os/vibrator/PwlePoint.java
+++ b/core/java/android/os/vibrator/PwlePoint.java
@@ -63,4 +63,12 @@ public final class PwlePoint {
public int hashCode() {
return Objects.hash(mAmplitude, mFrequencyHz, mTimeMillis);
}
+
+ @Override
+ public String toString() {
+ return "PwlePoint{amplitude=" + mAmplitude
+ + ", frequency=" + mFrequencyHz
+ + ", time=" + mTimeMillis
+ + "}";
+ }
}
diff --git a/core/java/android/os/vibrator/PwleSegment.java b/core/java/android/os/vibrator/PwleSegment.java
index 9074bde19321..942b7b3e524d 100644
--- a/core/java/android/os/vibrator/PwleSegment.java
+++ b/core/java/android/os/vibrator/PwleSegment.java
@@ -44,16 +44,16 @@ public final class PwleSegment extends VibrationEffectSegment {
private final float mStartFrequencyHz;
private final float mEndAmplitude;
private final float mEndFrequencyHz;
- private final int mDuration;
+ private final long mDuration;
PwleSegment(@android.annotation.NonNull Parcel in) {
- this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readInt());
+ this(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat(), in.readLong());
}
/** @hide */
@FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public PwleSegment(float startAmplitude, float endAmplitude, float startFrequencyHz,
- float endFrequencyHz, int duration) {
+ float endFrequencyHz, long duration) {
mStartAmplitude = startAmplitude;
mEndAmplitude = endAmplitude;
mStartFrequencyHz = startFrequencyHz;
@@ -213,7 +213,7 @@ public final class PwleSegment extends VibrationEffectSegment {
dest.writeFloat(mEndAmplitude);
dest.writeFloat(mStartFrequencyHz);
dest.writeFloat(mEndFrequencyHz);
- dest.writeInt(mDuration);
+ dest.writeLong(mDuration);
}
@android.annotation.NonNull
diff --git a/core/java/android/os/vibrator/VibrationEffectSegment.java b/core/java/android/os/vibrator/VibrationEffectSegment.java
index b934e11415d1..325a058e3aa3 100644
--- a/core/java/android/os/vibrator/VibrationEffectSegment.java
+++ b/core/java/android/os/vibrator/VibrationEffectSegment.java
@@ -47,6 +47,7 @@ public abstract class VibrationEffectSegment implements Parcelable {
static final int PARCEL_TOKEN_STEP = 3;
static final int PARCEL_TOKEN_RAMP = 4;
static final int PARCEL_TOKEN_PWLE = 5;
+ static final int PARCEL_TOKEN_BASIC_PWLE = 6;
/** Prevent subclassing from outside of this package */
VibrationEffectSegment() {
@@ -228,7 +229,12 @@ public abstract class VibrationEffectSegment implements Parcelable {
if (Flags.normalizedPwleEffects()) {
return new PwleSegment(in);
}
- // Fall through if the flag is not enabled.
+ // Fall through to default if the flag is not enabled.
+ case PARCEL_TOKEN_BASIC_PWLE:
+ if (Flags.normalizedPwleEffects()) {
+ return new BasicPwleSegment(in);
+ }
+ // Fall through to default if the flag is not enabled.
default:
throw new IllegalStateException(
"Unexpected vibration event type token in parcel.");
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index b5a822b715d5..55ba4afc9c68 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -418,3 +418,21 @@ flag {
description: "Add new checkOp APIs that accept attributionTag"
bug: "240617242"
}
+
+flag {
+ name: "device_policy_management_role_split_create_managed_profile_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "enterprise"
+ description: "Gives the device policy management role the ability to create a managed profile using new APIs"
+ bug: "375382324"
+}
+
+flag {
+ name: "use_profile_labels_for_default_app_section_titles"
+ is_exported: true
+ is_fixed_read_only: true
+ namespace: "profile_experiences"
+ description: "Use profile labels from UserManager for default app section titles to allow partner customization"
+ bug: "358369931"
+}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1b289fdabbd1..99ff38b43adc 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3151,7 +3151,7 @@ public final class ContactsContract {
* {@link #DEFAULT_ACCOUNT_STATE_CLOUD} or
* {@link #DEFAULT_ACCOUNT_STATE_SIM}, or null otherwise.
*/
- public DefaultAccountAndState(@DefaultAccountState int state,
+ private DefaultAccountAndState(@DefaultAccountState int state,
@Nullable Account account) {
if (!isValidDefaultAccountState(state)) {
throw new IllegalArgumentException("Invalid default account state.");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a35c9c1cd4ec..23f76299d8c4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6271,6 +6271,14 @@ public final class Settings {
public static final String TOUCHPAD_TAP_DRAGGING = "touchpad_tap_dragging";
/**
+ * Whether to enable three finger tap customization on touchpads.
+ *
+ * @hide
+ */
+ public static final String TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION =
+ "touchpad_three_finger_tap_customization";
+
+ /**
* Whether to enable a right-click zone on touchpads.
*
* When set to 1, pressing to click in a section on the right-hand side of the touchpad will
@@ -20454,6 +20462,29 @@ public final class Settings {
* @hide
*/
public static final String AUTO_BEDTIME_MODE = "auto_bedtime_mode";
+
+ /**
+ * Indicates that all elements of the system status tray on wear should be rendered
+ * by default wear system.
+ *
+ * @hide
+ */
+ public static final int STATUS_TRAY_CONFIGURATION_DEFAULT = 0;
+
+ /**
+ * Indicates that all elements of the system status tray on wear should be hidden.
+ *
+ * @hide
+ */
+ public static final int STATUS_TRAY_CONFIGURATION_SYSTEM_HIDDEN = 1;
+
+ /**
+ * Configuration of system status tray in wear.
+ *
+ * @hide
+ */
+ public static final String WEAR_SYSTEM_STATUS_TRAY_CONFIGURATION =
+ "wear_system_status_tray_configuration";
}
}
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 9fe0dda136d1..0302fafd2f6c 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -281,7 +281,7 @@ public final class AdvancedProtectionManager {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+ @RequiresPermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
public void setAdvancedProtectionEnabled(boolean enabled) {
try {
mService.setAdvancedProtectionEnabled(enabled);
@@ -297,7 +297,7 @@ public final class AdvancedProtectionManager {
*/
@SystemApi
@NonNull
- @RequiresPermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+ @RequiresPermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
try {
return mService.getAdvancedProtectionFeatures();
diff --git a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
index 68307632027a..1939f829c700 100644
--- a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
+++ b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
@@ -31,8 +31,8 @@ interface IAdvancedProtectionService {
void registerAdvancedProtectionCallback(IAdvancedProtectionCallback callback);
@EnforcePermission("QUERY_ADVANCED_PROTECTION_MODE")
void unregisterAdvancedProtectionCallback(IAdvancedProtectionCallback callback);
- @EnforcePermission("SET_ADVANCED_PROTECTION_MODE")
+ @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE")
void setAdvancedProtectionEnabled(boolean enabled);
- @EnforcePermission("SET_ADVANCED_PROTECTION_MODE")
+ @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE")
List<AdvancedProtectionFeature> getAdvancedProtectionFeatures();
} \ No newline at end of file
diff --git a/core/java/android/security/authenticationpolicy/AuthenticationPolicyManager.java b/core/java/android/security/authenticationpolicy/AuthenticationPolicyManager.java
new file mode 100644
index 000000000000..75abd5fa4bb0
--- /dev/null
+++ b/core/java/android/security/authenticationpolicy/AuthenticationPolicyManager.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.security.authenticationpolicy;
+
+import static android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE;
+import static android.security.Flags.FLAG_SECURE_LOCKDOWN;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.os.RemoteException;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * AuthenticationPolicyManager is a centralized interface for managing authentication related
+ * policies on the device. This includes device locking capabilities to protect users in "at risk"
+ * environments.
+ *
+ * AuthenticationPolicyManager is designed to protect Android users by integrating with apps and
+ * key system components, such as the lock screen. It is not related to enterprise control surfaces
+ * and does not offer additional administrative controls.
+ *
+ * <p>
+ * To use this class, call {@link #enableSecureLockDevice} to enable secure lock on the device.
+ * This will require the caller to have the
+ * {@link android.Manifest.permission#MANAGE_SECURE_LOCK_DEVICE} permission.
+ *
+ * <p>
+ * To disable secure lock on the device, call {@link #disableSecureLockDevice}. This will require
+ * the caller to have the {@link android.Manifest.permission#MANAGE_SECURE_LOCK_DEVICE} permission.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(FLAG_SECURE_LOCKDOWN)
+@SystemService(Context.AUTHENTICATION_POLICY_SERVICE)
+public final class AuthenticationPolicyManager {
+ private static final String TAG = "AuthenticationPolicyManager";
+
+ @NonNull private final IAuthenticationPolicyService mAuthenticationPolicyService;
+ @NonNull private final Context mContext;
+
+ /**
+ * Error result code for {@link #enableSecureLockDevice} and {@link
+ * #disableSecureLockDevice}.
+ *
+ * Secure lock device request status unknown.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int ERROR_UNKNOWN = 0;
+
+ /**
+ * Success result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
+ *
+ * Secure lock device request successful.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int SUCCESS = 1;
+
+ /**
+ * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
+ *
+ * Secure lock device is unsupported.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int ERROR_UNSUPPORTED = 2;
+
+
+ /**
+ * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
+ *
+ * Invalid secure lock device request params provided.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int ERROR_INVALID_PARAMS = 3;
+
+
+ /**
+ * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
+ *
+ * Secure lock device is unavailable because there are no biometrics enrolled on the device.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int ERROR_NO_BIOMETRICS_ENROLLED = 4;
+
+ /**
+ * Error result code for {@link #enableSecureLockDevice} and {@link #disableSecureLockDevice}.
+ *
+ * Secure lock device is unavailable because the device has no biometric hardware or the
+ * biometric sensors do not meet
+ * {@link android.hardware.biometrics.BiometricManager.Authenticators#BIOMETRIC_STRONG}
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int ERROR_INSUFFICIENT_BIOMETRICS = 5;
+
+ /**
+ * Error result code for {@link #enableSecureLockDevice}.
+ *
+ * Secure lock is already enabled.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public static final int ERROR_ALREADY_ENABLED = 6;
+
+ /**
+ * Communicates the current status of a request to enable secure lock on the device.
+ *
+ * @hide
+ */
+ @IntDef(prefix = {"ENABLE_SECURE_LOCK_DEVICE_STATUS_"}, value = {
+ ERROR_UNKNOWN,
+ SUCCESS,
+ ERROR_UNSUPPORTED,
+ ERROR_INVALID_PARAMS,
+ ERROR_NO_BIOMETRICS_ENROLLED,
+ ERROR_INSUFFICIENT_BIOMETRICS,
+ ERROR_ALREADY_ENABLED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EnableSecureLockDeviceRequestStatus {}
+
+ /**
+ * Communicates the current status of a request to disable secure lock on the device.
+ *
+ * @hide
+ */
+ @IntDef(prefix = {"DISABLE_SECURE_LOCK_DEVICE_STATUS_"}, value = {
+ ERROR_UNKNOWN,
+ SUCCESS,
+ ERROR_UNSUPPORTED,
+ ERROR_INVALID_PARAMS,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DisableSecureLockDeviceRequestStatus {}
+
+ /** @hide */
+ public AuthenticationPolicyManager(@NonNull Context context,
+ @NonNull IAuthenticationPolicyService authenticationPolicyService) {
+ mContext = context;
+ mAuthenticationPolicyService = authenticationPolicyService;
+ }
+
+ /**
+ * Called by a privileged component to remotely enable secure lock on the device.
+ *
+ * Secure lock is an enhanced security state that restricts access to sensitive data (app
+ * notifications, widgets, quick settings, assistant, etc) and requires multi-factor
+ * authentication for device entry, such as
+ * {@link android.hardware.biometrics.BiometricManager.Authenticators#DEVICE_CREDENTIAL} and
+ * {@link android.hardware.biometrics.BiometricManager.Authenticators#BIOMETRIC_STRONG}.
+ *
+ * If secure lock is already enabled when this method is called, it will return
+ * {@link ERROR_ALREADY_ENABLED}.
+ *
+ * @param params EnableSecureLockDeviceParams for caller to supply params related to the secure
+ * lock device request
+ * @return @EnableSecureLockDeviceRequestStatus int indicating the result of the secure lock
+ * device request
+ *
+ * @hide
+ */
+ @EnableSecureLockDeviceRequestStatus
+ @RequiresPermission(MANAGE_SECURE_LOCK_DEVICE)
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public int enableSecureLockDevice(@NonNull EnableSecureLockDeviceParams params) {
+ try {
+ return mAuthenticationPolicyService.enableSecureLockDevice(params);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Called by a privileged component to disable secure lock on the device.
+ *
+ * If secure lock is already disabled when this method is called, it will return
+ * {@link SUCCESS}.
+ *
+ * @param params @DisableSecureLockDeviceParams for caller to supply params related to the
+ * secure lock device request
+ * @return @DisableSecureLockDeviceRequestStatus int indicating the result of the secure lock
+ * device request
+ *
+ * @hide
+ */
+ @DisableSecureLockDeviceRequestStatus
+ @RequiresPermission(MANAGE_SECURE_LOCK_DEVICE)
+ @SystemApi
+ @FlaggedApi(FLAG_SECURE_LOCKDOWN)
+ public int disableSecureLockDevice(@NonNull DisableSecureLockDeviceParams params) {
+ try {
+ return mAuthenticationPolicyService.disableSecureLockDevice(params);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+}
diff --git a/core/java/android/content/pm/verify/pkg/VerificationStatus.aidl b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.aidl
index 6a1cb4f2d1d2..81f7726a500c 100644
--- a/core/java/android/content/pm/verify/pkg/VerificationStatus.aidl
+++ b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.aidl
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.security.authenticationpolicy;
-package android.content.pm.verify.pkg;
-
-/** @hide */
-parcelable VerificationStatus;
+/**
+ * @hide
+ */
+parcelable DisableSecureLockDeviceParams; \ No newline at end of file
diff --git a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
new file mode 100644
index 000000000000..64a3f0f60f96
--- /dev/null
+++ b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.authenticationpolicy;
+
+import static android.security.Flags.FLAG_SECURE_LOCKDOWN;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Parameters related to a request to disable secure lock on the device.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(FLAG_SECURE_LOCKDOWN)
+public final class DisableSecureLockDeviceParams implements Parcelable {
+
+ /**
+ * Client message associated with the request to disable secure lock on the device. This message
+ * will be shown on the device when secure lock mode is disabled.
+ */
+ private final @NonNull String mMessage;
+
+ /**
+ * Creates DisableSecureLockDeviceParams with the given params.
+ *
+ * @param message Allows clients to pass in a message with information about the request to
+ * disable secure lock on the device. This message will be shown to the user when
+ * secure lock mode is disabled. If an empty string is provided, it will default
+ * to a system-defined string (e.g. "Secure lock mode has been disabled.")
+ */
+ public DisableSecureLockDeviceParams(@NonNull String message) {
+ mMessage = message;
+ }
+
+ private DisableSecureLockDeviceParams(@NonNull Parcel in) {
+ mMessage = Objects.requireNonNull(in.readString8());
+ }
+
+ public static final @NonNull Creator<DisableSecureLockDeviceParams> CREATOR =
+ new Creator<DisableSecureLockDeviceParams>() {
+ @Override
+ public DisableSecureLockDeviceParams createFromParcel(Parcel in) {
+ return new DisableSecureLockDeviceParams(in);
+ }
+
+ @Override
+ public DisableSecureLockDeviceParams[] newArray(int size) {
+ return new DisableSecureLockDeviceParams[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mMessage);
+ }
+}
diff --git a/core/java/android/content/pm/verify/pkg/VerificationSession.aidl b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.aidl
index ac855850a86c..9e496f82ec69 100644
--- a/core/java/android/content/pm/verify/pkg/VerificationSession.aidl
+++ b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.aidl
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.security.authenticationpolicy;
-package android.content.pm.verify.pkg;
-
-/** @hide */
-parcelable VerificationSession;
+/**
+ * @hide
+ */
+parcelable EnableSecureLockDeviceParams; \ No newline at end of file
diff --git a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
new file mode 100644
index 000000000000..1d727727ce37
--- /dev/null
+++ b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.security.authenticationpolicy;
+
+import static android.security.Flags.FLAG_SECURE_LOCKDOWN;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+
+/**
+ * Parameters related to a request to enable secure lock on the device.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(FLAG_SECURE_LOCKDOWN)
+public final class EnableSecureLockDeviceParams implements Parcelable {
+
+ /**
+ * Client message associated with the request to enable secure lock on the device. This message
+ * will be shown on the device when secure lock mode is enabled.
+ */
+ private final @NonNull String mMessage;
+
+ /**
+ * Creates EnableSecureLockDeviceParams with the given params.
+ *
+ * @param message Allows clients to pass in a message with information about the request to
+ * enable secure lock on the device. This message will be shown to the user when
+ * secure lock mode is enabled. If an empty string is provided, it will default
+ * to a system-defined string (e.g. "Device is securely locked remotely.")
+ */
+ public EnableSecureLockDeviceParams(@NonNull String message) {
+ mMessage = message;
+ }
+
+ private EnableSecureLockDeviceParams(@NonNull Parcel in) {
+ mMessage = Objects.requireNonNull(in.readString8());
+ }
+
+ public static final @NonNull Creator<EnableSecureLockDeviceParams> CREATOR =
+ new Creator<EnableSecureLockDeviceParams>() {
+ @Override
+ public EnableSecureLockDeviceParams createFromParcel(Parcel in) {
+ return new EnableSecureLockDeviceParams(in);
+ }
+
+ @Override
+ public EnableSecureLockDeviceParams[] newArray(int size) {
+ return new EnableSecureLockDeviceParams[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mMessage);
+ }
+}
diff --git a/core/java/android/content/pm/verify/pkg/IVerifierService.aidl b/core/java/android/security/authenticationpolicy/IAuthenticationPolicyService.aidl
index d3071fd67b9d..5ad4534c257a 100644
--- a/core/java/android/content/pm/verify/pkg/IVerifierService.aidl
+++ b/core/java/android/security/authenticationpolicy/IAuthenticationPolicyService.aidl
@@ -14,18 +14,19 @@
* limitations under the License.
*/
-package android.content.pm.verify.pkg;
+package android.security.authenticationpolicy;
-import android.content.pm.verify.pkg.VerificationSession;
+import android.security.authenticationpolicy.EnableSecureLockDeviceParams;
+import android.security.authenticationpolicy.DisableSecureLockDeviceParams;
/**
- * Oneway interface that allows the system to communicate to the verifier service agent.
+ * Communication channel from AuthenticationPolicyManager to AuthenticationPolicyService.
* @hide
*/
-oneway interface IVerifierService {
- void onPackageNameAvailable(in String packageName);
- void onVerificationCancelled(in String packageName);
- void onVerificationRequired(in VerificationSession session);
- void onVerificationRetry(in VerificationSession session);
- void onVerificationTimeout(int verificationId);
+interface IAuthenticationPolicyService {
+ @EnforcePermission("MANAGE_SECURE_LOCK_DEVICE")
+ int enableSecureLockDevice(in EnableSecureLockDeviceParams params);
+
+ @EnforcePermission("MANAGE_SECURE_LOCK_DEVICE")
+ int disableSecureLockDevice(in DisableSecureLockDeviceParams params);
} \ No newline at end of file
diff --git a/core/java/android/security/authenticationpolicy/OWNERS b/core/java/android/security/authenticationpolicy/OWNERS
new file mode 100644
index 000000000000..4310d1a3a9db
--- /dev/null
+++ b/core/java/android/security/authenticationpolicy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/security/authenticationpolicy/OWNERS \ No newline at end of file
diff --git a/core/java/android/security/forensic/IForensicService.aidl b/core/java/android/security/forensic/IForensicService.aidl
deleted file mode 100644
index 8039b264f0e5..000000000000
--- a/core/java/android/security/forensic/IForensicService.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.forensic;
-
-import android.security.forensic.IForensicServiceCommandCallback;
-import android.security.forensic.IForensicServiceStateCallback;
-
-/**
- * Binder interface to communicate with ForensicService.
- * @hide
- */
-interface IForensicService {
- @EnforcePermission("READ_FORENSIC_STATE")
- void addStateCallback(IForensicServiceStateCallback callback);
- @EnforcePermission("READ_FORENSIC_STATE")
- void removeStateCallback(IForensicServiceStateCallback callback);
- @EnforcePermission("MANAGE_FORENSIC_STATE")
- void enable(IForensicServiceCommandCallback callback);
- @EnforcePermission("MANAGE_FORENSIC_STATE")
- void disable(IForensicServiceCommandCallback callback);
-}
diff --git a/core/java/android/security/forensic/IForensicEventTransport.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
index 80e78eb9cf49..8759f72ca08a 100644
--- a/core/java/android/security/forensic/IForensicEventTransport.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
@@ -14,25 +14,25 @@
* limitations under the License.
*/
-package android.security.forensic;
-import android.security.forensic.ForensicEvent;
+package android.security.intrusiondetection;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import com.android.internal.infra.AndroidFuture;
/** {@hide} */
-oneway interface IForensicEventTransport {
+oneway interface IIntrusionDetectionEventTransport {
/**
* Initialize the server side.
*/
void initialize(in AndroidFuture<int> resultFuture);
/**
- * Send forensic logging data to the backup destination.
- * The data is a list of ForensicEvent.
- * The ForensicEvent is an abstract class that represents
+ * Send intrusiondetection logging data to the backup destination.
+ * The data is a list of IntrusionDetectionEvent.
+ * The IntrusionDetectionEvent is an abstract class that represents
* different type of events.
*/
- void addData(in List<ForensicEvent> events, in AndroidFuture<int> resultFuture);
+ void addData(in List<IntrusionDetectionEvent> events, in AndroidFuture<int> resultFuture);
/**
* Release the binder to the server.
diff --git a/core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl
new file mode 100644
index 000000000000..0ba94185ddec
--- /dev/null
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionService.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.intrusiondetection;
+
+import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
+
+/**
+ * Binder interface to communicate with IntrusionDetectionService.
+ * @hide
+ */
+interface IIntrusionDetectionService {
+ @EnforcePermission("READ_INTRUSION_DETECTION_STATE")
+ void addStateCallback(IIntrusionDetectionServiceStateCallback callback);
+ @EnforcePermission("READ_INTRUSION_DETECTION_STATE")
+ void removeStateCallback(IIntrusionDetectionServiceStateCallback callback);
+ @EnforcePermission("MANAGE_INTRUSION_DETECTION_STATE")
+ void enable(IIntrusionDetectionServiceCommandCallback callback);
+ @EnforcePermission("MANAGE_INTRUSION_DETECTION_STATE")
+ void disable(IIntrusionDetectionServiceCommandCallback callback);
+}
diff --git a/core/java/android/security/forensic/IForensicServiceCommandCallback.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceCommandCallback.aidl
index 6d1456ea0426..80f09d520cc8 100644
--- a/core/java/android/security/forensic/IForensicServiceCommandCallback.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceCommandCallback.aidl
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
/**
* @hide
*/
- oneway interface IForensicServiceCommandCallback {
+ oneway interface IIntrusionDetectionServiceCommandCallback {
@Backing(type="int")
enum ErrorCode{
UNKNOWN = 0,
diff --git a/core/java/android/security/forensic/IForensicServiceStateCallback.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceStateCallback.aidl
index 1b68c7b14bca..c88dc210320c 100644
--- a/core/java/android/security/forensic/IForensicServiceStateCallback.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionServiceStateCallback.aidl
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
/**
* @hide
*/
- oneway interface IForensicServiceStateCallback {
+ oneway interface IIntrusionDetectionServiceStateCallback {
@Backing(type="int")
enum State{
UNKNOWN = 0,
diff --git a/core/java/android/security/forensic/ForensicEvent.aidl b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.aidl
index a321fb0cb939..80b439673b3d 100644
--- a/core/java/android/security/forensic/ForensicEvent.aidl
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
/** {@hide} */
-parcelable ForensicEvent;
+parcelable IntrusionDetectionEvent;
diff --git a/core/java/android/security/forensic/ForensicEvent.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
index 3d908cca150c..538acf99c9fe 100644
--- a/core/java/android/security/forensic/ForensicEvent.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
@@ -30,12 +30,12 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
- * A class that represents a forensic event.
+ * A class that represents a intrusiondetection event.
* @hide
*/
@FlaggedApi(Flags.FLAG_AFL_API)
-public final class ForensicEvent implements Parcelable {
- private static final String TAG = "ForensicEvent";
+public final class IntrusionDetectionEvent implements Parcelable {
+ private static final String TAG = "IntrusionDetectionEvent";
public static final int SECURITY_EVENT = 0;
public static final int NETWORK_EVENT_DNS = 1;
@@ -44,9 +44,9 @@ public final class ForensicEvent implements Parcelable {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
- ForensicEvent.SECURITY_EVENT,
- ForensicEvent.NETWORK_EVENT_DNS,
- ForensicEvent.NETWORK_EVENT_CONNECT,
+ IntrusionDetectionEvent.SECURITY_EVENT,
+ IntrusionDetectionEvent.NETWORK_EVENT_DNS,
+ IntrusionDetectionEvent.NETWORK_EVENT_CONNECT,
})
public @interface EventType {}
@@ -56,39 +56,39 @@ public final class ForensicEvent implements Parcelable {
private final DnsEvent mNetworkEventDns;
private final ConnectEvent mNetworkEventConnect;
- public static final @NonNull Parcelable.Creator<ForensicEvent> CREATOR =
+ public static final @NonNull Parcelable.Creator<IntrusionDetectionEvent> CREATOR =
new Parcelable.Creator<>() {
- public ForensicEvent createFromParcel(Parcel in) {
- return new ForensicEvent(in);
+ public IntrusionDetectionEvent createFromParcel(Parcel in) {
+ return new IntrusionDetectionEvent(in);
}
- public ForensicEvent[] newArray(int size) {
- return new ForensicEvent[size];
+ public IntrusionDetectionEvent[] newArray(int size) {
+ return new IntrusionDetectionEvent[size];
}
};
- public ForensicEvent(@NonNull SecurityEvent securityEvent) {
+ public IntrusionDetectionEvent(@NonNull SecurityEvent securityEvent) {
mType = SECURITY_EVENT;
mSecurityEvent = securityEvent;
mNetworkEventDns = null;
mNetworkEventConnect = null;
}
- public ForensicEvent(@NonNull DnsEvent dnsEvent) {
+ public IntrusionDetectionEvent(@NonNull DnsEvent dnsEvent) {
mType = NETWORK_EVENT_DNS;
mNetworkEventDns = dnsEvent;
mSecurityEvent = null;
mNetworkEventConnect = null;
}
- public ForensicEvent(@NonNull ConnectEvent connectEvent) {
+ public IntrusionDetectionEvent(@NonNull ConnectEvent connectEvent) {
mType = NETWORK_EVENT_CONNECT;
mNetworkEventConnect = connectEvent;
mSecurityEvent = null;
mNetworkEventDns = null;
}
- private ForensicEvent(@NonNull Parcel in) {
+ private IntrusionDetectionEvent(@NonNull Parcel in) {
mType = in.readInt();
switch (mType) {
case SECURITY_EVENT:
@@ -111,7 +111,7 @@ public final class ForensicEvent implements Parcelable {
}
}
- /** Returns the type of the forensic event. */
+ /** Returns the type of the IntrusionDetectionEvent. */
@NonNull
public @EventType int getType() {
return mType;
@@ -170,7 +170,7 @@ public final class ForensicEvent implements Parcelable {
@Override
public String toString() {
- return "ForensicEvent{"
+ return "IntrusionDetectionEvent{"
+ "mType=" + mType
+ '}';
}
diff --git a/core/java/android/security/forensic/ForensicManager.java b/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
index 9126182eda7b..e2463384d0c8 100644
--- a/core/java/android/security/forensic/ForensicManager.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.security.forensic;
+package android.security.intrusiondetection;
-import static android.Manifest.permission.MANAGE_FORENSIC_STATE;
-import static android.Manifest.permission.READ_FORENSIC_STATE;
+import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
+import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
@@ -41,23 +41,23 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
- * ForensicManager manages the forensic logging on Android devices.
- * Upon user consent, forensic logging collects various device events for
+ * IntrusionDetectionManager manages the intrusion detection on Android devices.
+ * Upon user consent, intrusion detection collects various device events for
* off-device investigation of potential device compromise.
* <p>
- * Forensic logging can either be enabled ({@link #STATE_ENABLED}
+ * Intrusion detection logging can either be enabled ({@link #STATE_ENABLED}
* or disabled ({@link #STATE_DISABLED}).
* <p>
- * The Forensic logs will be transferred to
- * {@link android.security.forensic.ForensicEventTransport}.
+ * The intrusion detection logs will be transferred to
+ * {@link android.security.intrusiondetection.IntrusionDetectionEventTransport}.
*
* @hide
*/
@SystemApi
@FlaggedApi(Flags.FLAG_AFL_API)
-@SystemService(Context.FORENSIC_SERVICE)
-public class ForensicManager {
- private static final String TAG = "ForensicManager";
+@SystemService(Context.INTRUSION_DETECTION_SERVICE)
+public class IntrusionDetectionManager {
+ private static final String TAG = "IntrusionDetectionManager";
/** @hide */
@Target(ElementType.TYPE_USE)
@@ -67,7 +67,7 @@ public class ForensicManager {
STATE_DISABLED,
STATE_ENABLED
})
- public @interface ForensicState {}
+ public @interface IntrusionDetectionState {}
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -77,64 +77,65 @@ public class ForensicManager {
ERROR_TRANSPORT_UNAVAILABLE,
ERROR_DATA_SOURCE_UNAVAILABLE
})
- public @interface ForensicError {}
+ public @interface IntrusionDetectionError {}
/**
* Indicates an unknown state
*/
- public static final int STATE_UNKNOWN = IForensicServiceStateCallback.State.UNKNOWN;
+ public static final int STATE_UNKNOWN = IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
/**
- * Indicates an state that the forensic is turned off.
+ * Indicates an state that the intrusion detection is turned off.
*/
- public static final int STATE_DISABLED = IForensicServiceStateCallback.State.DISABLED;
+ public static final int STATE_DISABLED = IIntrusionDetectionServiceStateCallback.State.DISABLED;
/**
- * Indicates an state that the forensic is turned on.
+ * Indicates an state that the intrusion detection is turned on.
*/
- public static final int STATE_ENABLED = IForensicServiceStateCallback.State.ENABLED;
+ public static final int STATE_ENABLED = IIntrusionDetectionServiceStateCallback.State.ENABLED;
/**
* Indicates an unknown error
*/
- public static final int ERROR_UNKNOWN = IForensicServiceCommandCallback.ErrorCode.UNKNOWN;
+ public static final int ERROR_UNKNOWN =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.UNKNOWN;
/**
* Indicates an error due to insufficient access rights.
*/
public static final int ERROR_PERMISSION_DENIED =
- IForensicServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
/**
- * Indicates an error due to unavailability of the forensic event transport.
+ * Indicates an error due to unavailability of the intrusion detection event transport.
*/
public static final int ERROR_TRANSPORT_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
/**
* Indicates an error due to unavailability of the data source.
*/
public static final int ERROR_DATA_SOURCE_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
- private final IForensicService mService;
+ private final IIntrusionDetectionService mService;
- private final ConcurrentHashMap<Consumer<Integer>, IForensicServiceStateCallback>
+ private final ConcurrentHashMap<Consumer<Integer>, IIntrusionDetectionServiceStateCallback>
mStateCallbacks = new ConcurrentHashMap<>();
/**
* Constructor
*
- * @param service A valid instance of IForensicService.
+ * @param service A valid instance of IIntrusionDetectionService.
* @hide
*/
- public ForensicManager(IForensicService service) {
+ public IntrusionDetectionManager(IIntrusionDetectionService service) {
mService = service;
}
/**
- * Add a callback to monitor the state of the ForensicService.
+ * Add a callback to monitor the state of the IntrusionDetectionService.
*
* @param executor The executor through which the callback should be invoked.
* @param callback The callback for state change.
@@ -142,9 +143,9 @@ public class ForensicManager {
* to reflect the init state.
* The callback can be registered only once.
*/
- @RequiresPermission(READ_FORENSIC_STATE)
+ @RequiresPermission(READ_INTRUSION_DETECTION_STATE)
public void addStateCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull @ForensicState Consumer<Integer> callback) {
+ @NonNull @IntrusionDetectionState Consumer<Integer> callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
@@ -153,8 +154,8 @@ public class ForensicManager {
return;
}
- final IForensicServiceStateCallback wrappedCallback =
- new IForensicServiceStateCallback.Stub() {
+ final IIntrusionDetectionServiceStateCallback wrappedCallback =
+ new IIntrusionDetectionServiceStateCallback.Stub() {
@Override
public void onStateChange(int state) {
executor.execute(() -> callback.accept(state));
@@ -170,19 +171,19 @@ public class ForensicManager {
}
/**
- * Remove a callback to monitor the state of the ForensicService.
+ * Remove a callback to monitor the state of the IntrusionDetectionService.
*
* @param callback The callback to remove.
*/
- @RequiresPermission(READ_FORENSIC_STATE)
- public void removeStateCallback(@NonNull Consumer<@ForensicState Integer> callback) {
+ @RequiresPermission(READ_INTRUSION_DETECTION_STATE)
+ public void removeStateCallback(@NonNull Consumer<@IntrusionDetectionState Integer> callback) {
Objects.requireNonNull(callback);
if (!mStateCallbacks.containsKey(callback)) {
Log.d(TAG, "removeStateCallback callback not present");
return;
}
- IForensicServiceStateCallback wrappedCallback = mStateCallbacks.get(callback);
+ IIntrusionDetectionServiceStateCallback wrappedCallback = mStateCallbacks.get(callback);
try {
mService.removeStateCallback(wrappedCallback);
@@ -194,22 +195,23 @@ public class ForensicManager {
}
/**
- * Enable forensic logging.
- * If successful, ForensicService will transition to {@link #STATE_ENABLED} state.
+ * Enable intrusion detection.
+ * If successful, IntrusionDetectionService will transition to {@link #STATE_ENABLED} state.
* <p>
- * When forensic logging is enabled, various device events will be collected and
- * sent over to the registered {@link android.security.forensic.ForensicEventTransport}.
+ * When intrusion detection is enabled, various device events will be collected and
+ * sent over to the registered
+ * {@link android.security.intrusiondetection.IntrusionDetectionEventTransport}.
*
* @param executor The executor through which the callback should be invoked.
* @param callback The callback for the command result.
*/
- @RequiresPermission(MANAGE_FORENSIC_STATE)
+ @RequiresPermission(MANAGE_INTRUSION_DETECTION_STATE)
public void enable(@NonNull @CallbackExecutor Executor executor,
@NonNull CommandCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
try {
- mService.enable(new IForensicServiceCommandCallback.Stub() {
+ mService.enable(new IIntrusionDetectionServiceCommandCallback.Stub() {
@Override
public void onSuccess() {
executor.execute(callback::onSuccess);
@@ -226,23 +228,23 @@ public class ForensicManager {
}
/**
- * Disable forensic logging.
- * If successful, ForensicService will transition to {@link #STATE_DISABLED}.
+ * Disable intrusion detection.
+ * If successful, IntrusionDetectionService will transition to {@link #STATE_DISABLED}.
* <p>
- * When forensic logging is disabled, device events will no longer be collected.
- * Any events that have been collected but not yet sent to ForensicEventTransport
+ * When intrusion detection is disabled, device events will no longer be collected.
+ * Any events that have been collected but not yet sent to IntrusionDetectionEventTransport
* will be transferred as a final batch.
*
* @param executor The executor through which the callback should be invoked.
* @param callback The callback for the command result.
*/
- @RequiresPermission(MANAGE_FORENSIC_STATE)
+ @RequiresPermission(MANAGE_INTRUSION_DETECTION_STATE)
public void disable(@NonNull @CallbackExecutor Executor executor,
@NonNull CommandCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
try {
- mService.disable(new IForensicServiceCommandCallback.Stub() {
+ mService.disable(new IIntrusionDetectionServiceCommandCallback.Stub() {
@Override
public void onSuccess() {
executor.execute(callback::onSuccess);
@@ -271,6 +273,6 @@ public class ForensicManager {
* Called when command fails.
* @param error The error number.
*/
- void onFailure(@ForensicError int error);
+ void onFailure(@IntrusionDetectionError int error);
}
}
diff --git a/core/java/android/security/forensic/OWNERS b/core/java/android/security/intrusiondetection/OWNERS
index d9e82a6e42f2..d9e82a6e42f2 100644
--- a/core/java/android/security/forensic/OWNERS
+++ b/core/java/android/security/intrusiondetection/OWNERS
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index 61213e6293ba..a825a7e110f5 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -16,6 +16,7 @@
package android.service.carrier;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -26,6 +27,8 @@ import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
+import com.android.internal.telephony.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -97,16 +100,317 @@ public abstract class CarrierMessagingService extends Service {
public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
/**
- * SMS/MMS sending failed. We should not retry via the carrier network.
+ * SMS/MMS sending failed due to an unspecified issue. Sending will not be retried via the
+ * carrier network.
+ *
+ * <p>Maps to SmsManager.RESULT_RIL_GENERIC_FAILURE for SMS and SmsManager.MMS_ERROR_UNSPECIFIED
+ * for MMS.
*/
public static final int SEND_STATUS_ERROR = 2;
+ /**
+ * More precise error reasons for outbound SMS send requests. These will not be retried on the
+ * carrier network.
+ *
+ * <p>Each code maps directly to an SmsManager code (e.g. SEND_STATS_RESULT_ERROR_NULL_PDU maps
+ * to SmsManager.RESULT_ERROR_NULL_PDU).
+ */
+
+ /**
+ * Generic failure cause.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_GENERIC_FAILURE
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE = 200;
+
+ /**
+ * Failed because no pdu provided.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_NULL_PDU
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_NULL_PDU = 201;
+
+ /**
+ * Failed because service is currently unavailable.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_NO_SERVICE = 202;
+
+ /**
+ * Failed because we reached the sending queue limit.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED = 203;
+
+ /**
+ * Failed because FDN is enabled.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE = 204;
+
+ /**
+ * Failed because user denied the sending of this short code.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 205;
+
+ /**
+ * Failed because the user has denied this app ever send premium short codes.
+ *
+ * @see android.telephony.SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 206;
+
+ /**
+ * Failed because of network rejection.
+ *
+ * @see android.telephony.SmsManager.RESULT_NETWORK_REJECT
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_NETWORK_REJECT = 207;
+
+ /**
+ * Failed because of invalid arguments.
+ *
+ * @see android.telephony.SmsManager.RESULT_INVALID_ARGUMENTS
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_INVALID_ARGUMENTS = 208;
+
+ /**
+ * Failed because of an invalid state.
+ *
+ * @see android.telephony.SmsManager.RESULT_INVALID_STATE
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_INVALID_STATE = 209;
+
+ /**
+ * Failed because the sms format is not valid.
+ *
+ * @see android.telephony.SmsManager.RESULT_INVALID_SMS_FORMAT
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_INVALID_SMS_FORMAT = 210;
+
+ /**
+ * Failed because of a network error.
+ *
+ * @see android.telephony.SmsManager.RESULT_NETWORK_ERROR
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_NETWORK_ERROR = 211;
+
+ /**
+ * Failed because of an encoding error.
+ *
+ * @see android.telephony.SmsManager.RESULT_ENCODING_ERROR
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_ENCODING_ERROR = 212;
+
+ /**
+ * Failed because of an invalid smsc address
+ *
+ * @see android.telephony.SmsManager.RESULT_INVALID_SMSC_ADDRESS
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS = 213;
+
+ /**
+ * Failed because the operation is not allowed.
+ *
+ * @see android.telephony.SmsManager.RESULT_OPERATION_NOT_ALLOWED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED = 214;
+
+ /**
+ * Failed because the operation was cancelled.
+ *
+ * @see android.telephony.SmsManager.RESULT_CANCELLED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_CANCELLED = 215;
+
+ /**
+ * Failed because the request is not supported.
+ *
+ * @see android.telephony.SmsManager.RESULT_REQUEST_NOT_SUPPORTED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED = 216;
+
+ /**
+ * Failed sending during an emergency call.
+ *
+ * @see android.telephony.SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY = 217;
+
+ /**
+ * Failed to send an sms retry.
+ *
+ * @see android.telephony.SmsManager.RESULT_SMS_SEND_RETRY_FAILED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED = 218;
+
+ /**
+ * More precise error reasons for outbound MMS send requests. These will not be retried on the
+ * carrier network.
+ *
+ * <p>Each code maps directly to an SmsManager code (e.g.
+ * SEND_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS maps to SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS).
+ */
+
+ /**
+ * Unspecific MMS error occurred during send.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_UNSPECIFIED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_UNSPECIFIED = 400;
+
+ /**
+ * ApnException occurred during MMS network setup.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_INVALID_APN
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_INVALID_APN = 401;
+
+ /**
+ * An error occurred during the MMS connection setup.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS = 402;
+
+ /**
+ * An error occurred during the HTTP client setup.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_HTTP_FAILURE
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_HTTP_FAILURE = 403;
+
+ /**
+ * An I/O error occurred reading the PDU.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_IO_ERROR
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_IO_ERROR = 404;
+
+ /**
+ * An error occurred while retrying sending the MMS.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_RETRY
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_RETRY = 405;
+
+ /**
+ * The carrier-dependent configuration values could not be loaded.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_CONFIGURATION_ERROR
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_CONFIGURATION_ERROR = 406;
+
+ /**
+ * There is neither Wi-Fi nor mobile data network.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_NO_DATA_NETWORK
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_NO_DATA_NETWORK = 407;
+
+ /**
+ * The subscription id for the send is invalid.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_INVALID_SUBSCRIPTION_ID
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_INVALID_SUBSCRIPTION_ID = 408;
+
+ /**
+ * The subscription id for the send is inactive.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_INACTIVE_SUBSCRIPTION
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_INACTIVE_SUBSCRIPTION = 409;
+
+ /**
+ * Data is disabled for the MMS APN.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_DATA_DISABLED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_DATA_DISABLED = 410;
+
+ /**
+ * MMS is disabled by a carrier.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_MMS_DISABLED_BY_CARRIER
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int SEND_STATUS_MMS_ERROR_MMS_DISABLED_BY_CARRIER = 411;
+
/** @hide */
- @IntDef(prefix = { "SEND_STATUS_" }, value = {
- SEND_STATUS_OK,
- SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
- SEND_STATUS_ERROR
- })
+ @IntDef(
+ prefix = {"SEND_STATUS_"},
+ value = {
+ SEND_STATUS_OK,
+ SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
+ SEND_STATUS_ERROR,
+ SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE,
+ SEND_STATUS_RESULT_ERROR_NULL_PDU,
+ SEND_STATUS_RESULT_ERROR_NO_SERVICE,
+ SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED,
+ SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE,
+ SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED,
+ SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED,
+ SEND_STATUS_RESULT_NETWORK_REJECT,
+ SEND_STATUS_RESULT_INVALID_ARGUMENTS,
+ SEND_STATUS_RESULT_INVALID_STATE,
+ SEND_STATUS_RESULT_INVALID_SMS_FORMAT,
+ SEND_STATUS_RESULT_NETWORK_ERROR,
+ SEND_STATUS_RESULT_ENCODING_ERROR,
+ SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS,
+ SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED,
+ SEND_STATUS_RESULT_CANCELLED,
+ SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED,
+ SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY,
+ SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED,
+ SEND_STATUS_MMS_ERROR_UNSPECIFIED,
+ SEND_STATUS_MMS_ERROR_INVALID_APN,
+ SEND_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS,
+ SEND_STATUS_MMS_ERROR_HTTP_FAILURE,
+ SEND_STATUS_MMS_ERROR_IO_ERROR,
+ SEND_STATUS_MMS_ERROR_RETRY,
+ SEND_STATUS_MMS_ERROR_CONFIGURATION_ERROR,
+ SEND_STATUS_MMS_ERROR_NO_DATA_NETWORK,
+ SEND_STATUS_MMS_ERROR_INVALID_SUBSCRIPTION_ID,
+ SEND_STATUS_MMS_ERROR_INACTIVE_SUBSCRIPTION,
+ SEND_STATUS_MMS_ERROR_DATA_DISABLED,
+ SEND_STATUS_MMS_ERROR_MMS_DISABLED_BY_CARRIER
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface SendResult {}
@@ -121,16 +425,138 @@ public abstract class CarrierMessagingService extends Service {
public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
/**
- * MMS downloading failed. We should not retry via the carrier network.
+ * MMS downloading failed due to an unspecified issue. Downloading will not be retried via the
+ * carrier network.
+ *
+ * <p>Maps to SmsManager.MMR_ERROR_UNSPECIFIED.
*/
public static final int DOWNLOAD_STATUS_ERROR = 2;
+ /**
+ * More precise error reasons for inbound MMS download requests. These will not be retried on
+ * the carrier network.
+ *
+ * <p>Each code maps directly to an SmsManager code (e.g.
+ * DOWNLOAD_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS maps to
+ * SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS).
+ */
+
+ /**
+ * Unspecific MMS error occurred during download.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_UNSPECIFIED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_UNSPECIFIED = 600;
+
+ /**
+ * ApnException occurred during MMS network setup.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_INVALID_APN
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_INVALID_APN = 601;
+
+ /**
+ * An error occurred during the MMS connection setup.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS = 602;
+
+ /**
+ * An error occurred during the HTTP client setup.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_HTTP_FAILURE
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_HTTP_FAILURE = 603;
+
+ /**
+ * An I/O error occurred reading the PDU.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_IO_ERROR
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_IO_ERROR = 604;
+
+ /**
+ * An error occurred while retrying downloading the MMS.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_RETRY
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_RETRY = 605;
+
+ /**
+ * The carrier-dependent configuration values could not be loaded.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_CONFIGURATION_ERROR
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_CONFIGURATION_ERROR = 606;
+
+ /**
+ * There is neither Wi-Fi nor mobile data network.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_NO_DATA_NETWORK
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_NO_DATA_NETWORK = 607;
+
+ /**
+ * The subscription id for the download is invalid.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_INVALID_SUBSCRIPTION_ID
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_INVALID_SUBSCRIPTION_ID = 608;
+
+ /**
+ * The subscription id for the download is inactive.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_INACTIVE_SUBSCRIPTION
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_INACTIVE_SUBSCRIPTION = 609;
+
+ /**
+ * Data is disabled for the MMS APN.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_DATA_DISABLED
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_DATA_DISABLED = 610;
+
+ /**
+ * MMS is disabled by a carrier.
+ *
+ * @see android.telephony.SmsManager.MMS_ERROR_MMS_DISABLED_BY_CARRIER
+ */
+ @FlaggedApi(Flags.FLAG_TEMPORARY_FAILURES_IN_CARRIER_MESSAGING_SERVICE)
+ public static final int DOWNLOAD_STATUS_MMS_ERROR_MMS_DISABLED_BY_CARRIER = 611;
+
/** @hide */
- @IntDef(prefix = { "DOWNLOAD_STATUS_" }, value = {
- DOWNLOAD_STATUS_OK,
- DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK,
- DOWNLOAD_STATUS_ERROR
- })
+ @IntDef(
+ prefix = {"DOWNLOAD_STATUS_"},
+ value = {
+ DOWNLOAD_STATUS_OK,
+ DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK,
+ DOWNLOAD_STATUS_ERROR,
+ DOWNLOAD_STATUS_MMS_ERROR_UNSPECIFIED,
+ DOWNLOAD_STATUS_MMS_ERROR_INVALID_APN,
+ DOWNLOAD_STATUS_MMS_ERROR_UNABLE_CONNECT_MMS,
+ DOWNLOAD_STATUS_MMS_ERROR_HTTP_FAILURE,
+ DOWNLOAD_STATUS_MMS_ERROR_IO_ERROR,
+ DOWNLOAD_STATUS_MMS_ERROR_RETRY,
+ DOWNLOAD_STATUS_MMS_ERROR_CONFIGURATION_ERROR,
+ DOWNLOAD_STATUS_MMS_ERROR_NO_DATA_NETWORK,
+ DOWNLOAD_STATUS_MMS_ERROR_INVALID_SUBSCRIPTION_ID,
+ DOWNLOAD_STATUS_MMS_ERROR_INACTIVE_SUBSCRIPTION,
+ DOWNLOAD_STATUS_MMS_ERROR_DATA_DISABLED,
+ DOWNLOAD_STATUS_MMS_ERROR_MMS_DISABLED_BY_CARRIER
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface DownloadResult {}
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 24328eb1e825..13887781f1ec 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -2532,7 +2532,7 @@ public class ZenModeConfig implements Parcelable {
/** Returns whether the rule id corresponds to an implicit rule. */
public static boolean isImplicitRuleId(@NonNull String ruleId) {
- return ruleId.startsWith(IMPLICIT_RULE_ID_PREFIX);
+ return ruleId != null && ruleId.startsWith(IMPLICIT_RULE_ID_PREFIX);
}
private static int[] tryParseHourAndMinute(String value) {
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java b/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
index 1d08c5217129..1acb7b8460cf 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
@@ -19,7 +19,7 @@ package android.service.settings.preferences;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.SuppressLint;
-import android.app.PendingIntent;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -63,7 +63,7 @@ public final class SettingsPreferenceMetadata implements Parcelable {
private final boolean mRestricted;
private final int mSensitivity;
@Nullable
- private final PendingIntent mLaunchIntent;
+ private final Intent mLaunchIntent;
@NonNull
private final Bundle mExtras;
@@ -149,6 +149,8 @@ public final class SettingsPreferenceMetadata implements Parcelable {
/**
* Returns whether Preference is restricted.
+ * <p>If true, this means the Preference is treated as a Restricted Preference which indicates
+ * that it could be conditionally disabled/unavailable due to admin settings.
*/
public boolean isRestricted() {
return mRestricted;
@@ -165,14 +167,18 @@ public final class SettingsPreferenceMetadata implements Parcelable {
/**
* Returns the intent to launch the host app page for this Preference.
*/
+ @SuppressLint("IntentBuilderName")
@Nullable
- public PendingIntent getLaunchIntent() {
+ public Intent getLaunchIntent() {
return mLaunchIntent;
}
/**
* Returns any additional fields specific to this preference.
- * <p>Treat all data as optional.
+ * <p>Treat all data as optional. This may contain unstructured data for a given preference,
+ * where the type and format of this data may only known by inspecting the source code of that
+ * preference. As such, any access of this data must handle failures gracefully to account for
+ * changing or missing data.
*/
@NonNull
public Bundle getExtras() {
@@ -236,8 +242,8 @@ public final class SettingsPreferenceMetadata implements Parcelable {
mWritable = in.readBoolean();
mRestricted = in.readBoolean();
mSensitivity = in.readInt();
- mLaunchIntent = in.readParcelable(PendingIntent.class.getClassLoader(),
- PendingIntent.class);
+ mLaunchIntent = in.readParcelable(Intent.class.getClassLoader(),
+ Intent.class);
mExtras = Objects.requireNonNullElseGet(in.readBundle(), Bundle::new);
}
@@ -298,7 +304,7 @@ public final class SettingsPreferenceMetadata implements Parcelable {
private boolean mWritable = false;
private boolean mRestricted = false;
@WriteSensitivity private int mSensitivity = INTENT_ONLY;
- private PendingIntent mLaunchIntent;
+ private Intent mLaunchIntent;
private Bundle mExtras;
/**
@@ -411,7 +417,7 @@ public final class SettingsPreferenceMetadata implements Parcelable {
* Sets the intent to launch the host app page for this preference.
*/
@NonNull
- public Builder setLaunchIntent(@Nullable PendingIntent launchIntent) {
+ public Builder setLaunchIntent(@Nullable Intent launchIntent) {
mLaunchIntent = launchIntent;
return this;
}
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java b/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java
index 39995a47fcbe..f6d85d51ddd4 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceServiceClient.java
@@ -49,67 +49,55 @@ import java.util.concurrent.Executor;
* available services, a caller may query {@link android.content.pm.PackageManager} for applications
* that provide the intent action {@link SettingsPreferenceService#ACTION_PREFERENCE_SERVICE} that
* are also system applications ({@link android.content.pm.ApplicationInfo#FLAG_SYSTEM}).
+ * <p>
+ * Note: Each instance of this client will open a binding to an application. This can be resource
+ * intensive and affect the health of the system. It is essential that each client instance is
+ * only used when needed and the number of calls made are minimal.
*/
@FlaggedApi(Flags.FLAG_SETTINGS_CATALYST)
public class SettingsPreferenceServiceClient implements AutoCloseable {
+ @NonNull
private final Context mContext;
+ @NonNull
private final Intent mServiceIntent;
+ @NonNull
private final ServiceConnection mServiceConnection;
- private final boolean mSystemOnly;
+ @Nullable
private ISettingsPreferenceService mRemoteService;
/**
* Construct a client for binding to a {@link SettingsPreferenceService} provided by the
* application corresponding to the provided package name.
- * @param packageName - package name for which this client will initiate a service binding
+ * @param context Application context
+ * @param packageName package name for which this client will initiate a service binding
+ * @param callbackExecutor executor on which to invoke clientReadyCallback
+ * @param clientReadyCallback callback invoked once the client is ready, error otherwise
*/
- public SettingsPreferenceServiceClient(@NonNull Context context,
- @NonNull String packageName) {
- this(context, packageName, true, null);
+ public SettingsPreferenceServiceClient(
+ @NonNull Context context,
+ @NonNull String packageName,
+ @CallbackExecutor @NonNull Executor callbackExecutor,
+ @NonNull
+ OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientReadyCallback) {
+ this(context, packageName, true, callbackExecutor, clientReadyCallback);
}
/**
* @hide Only to be called directly by test
*/
@TestApi
- public SettingsPreferenceServiceClient(@NonNull Context context,
- @NonNull String packageName,
- boolean systemOnly,
- @Nullable ServiceConnection connectionListener) {
+ public SettingsPreferenceServiceClient(
+ @NonNull Context context,
+ @NonNull String packageName,
+ boolean systemOnly,
+ @CallbackExecutor @NonNull Executor callbackExecutor,
+ @NonNull
+ OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientReadyCallback) {
mContext = context.getApplicationContext();
mServiceIntent = new Intent(ACTION_PREFERENCE_SERVICE).setPackage(packageName);
- mSystemOnly = systemOnly;
- mServiceConnection = createServiceConnection(connectionListener);
- }
-
- /**
- * Initiate binding to service.
- * <p>If no service exists for the package provided or the package is not for a system
- * application, no binding will occur.
- */
- public void start() {
- PackageManager pm = mContext.getPackageManager();
- PackageManager.ResolveInfoFlags flags;
- if (mSystemOnly) {
- flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY);
- } else {
- flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL);
- }
- List<ResolveInfo> infos = pm.queryIntentServices(mServiceIntent, flags);
- if (infos.size() == 1) {
- mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
- }
- }
-
- /**
- * If there is an active service binding, unbind from that service.
- */
- public void stop() {
- if (mRemoteService != null) {
- mRemoteService = null;
- mContext.unbindService(mServiceConnection);
- }
+ mServiceConnection = createServiceConnection(callbackExecutor, clientReadyCallback);
+ connect(systemOnly, callbackExecutor, clientReadyCallback);
}
/**
@@ -209,40 +197,73 @@ public class SettingsPreferenceServiceClient implements AutoCloseable {
}
}
+ /**
+ * This client handles a resource, thus is it important to appropriately close that resource
+ * when it is no longer needed.
+ * <p>This method is provided by {@link AutoCloseable} and calling it
+ * will unbind any service binding.
+ */
+ @Override
+ public void close() {
+ if (mRemoteService != null) {
+ mRemoteService = null;
+ mContext.unbindService(mServiceConnection);
+ }
+ }
+
+ /*
+ * Initiate binding to service.
+ * <p>If no service exists for the package provided or the package is not for a system
+ * application, no binding will occur.
+ */
+ private void connect(
+ boolean matchSystemOnly,
+ @NonNull Executor callbackExecutor,
+ @NonNull OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientCallback) {
+ PackageManager pm = mContext.getPackageManager();
+ PackageManager.ResolveInfoFlags flags;
+ if (matchSystemOnly) {
+ flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY);
+ } else {
+ flags = PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL);
+ }
+ List<ResolveInfo> infos = pm.queryIntentServices(mServiceIntent, flags);
+ if (infos.size() != 1
+ || !mContext.bindService(mServiceIntent, mServiceConnection,
+ Context.BIND_AUTO_CREATE)) {
+ callbackExecutor.execute(() ->
+ clientCallback.onError(new IllegalStateException("Unable to bind service")));
+ }
+ }
+
@NonNull
- private ServiceConnection createServiceConnection(@Nullable ServiceConnection listener) {
+ private ServiceConnection createServiceConnection(
+ @NonNull Executor callbackExecutor,
+ @NonNull OutcomeReceiver<SettingsPreferenceServiceClient, Exception> clientCallback) {
return new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- mRemoteService = getPreferenceServiceInterface(service);
- if (listener != null) {
- listener.onServiceConnected(name, service);
- }
+ mRemoteService = ISettingsPreferenceService.Stub.asInterface(service);
+ callbackExecutor.execute(() ->
+ clientCallback.onResult(SettingsPreferenceServiceClient.this));
}
@Override
public void onServiceDisconnected(ComponentName name) {
mRemoteService = null;
- if (listener != null) {
- listener.onServiceDisconnected(name);
- }
}
- };
- }
- @NonNull
- private ISettingsPreferenceService getPreferenceServiceInterface(@NonNull IBinder service) {
- return ISettingsPreferenceService.Stub.asInterface(service);
- }
+ @Override
+ public void onBindingDied(ComponentName name) {
+ close();
+ }
- /**
- * This client handles a resource, thus is it important to appropriately close that resource
- * when it is no longer needed.
- * <p>This method is provided by {@link AutoCloseable} and calling it
- * will unbind any service binding.
- */
- @Override
- public void close() {
- stop();
+ @Override
+ public void onNullBinding(ComponentName name) {
+ callbackExecutor.execute(() -> clientCallback.onError(
+ new IllegalStateException("Unable to connect client")));
+ close();
+ }
+ };
}
}
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceValue.java b/core/java/android/service/settings/preferences/SettingsPreferenceValue.java
index f056e34a0dd2..08826ca9776b 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceValue.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceValue.java
@@ -44,6 +44,7 @@ public final class SettingsPreferenceValue implements Parcelable {
@Type
private final int mType;
private final boolean mBooleanValue;
+ private final int mIntValue;
private final long mLongValue;
private final double mDoubleValue;
@Nullable
@@ -65,6 +66,13 @@ public final class SettingsPreferenceValue implements Parcelable {
}
/**
+ * Returns the int value for Preference if type is {@link #TYPE_INT}.
+ */
+ public int getIntValue() {
+ return mIntValue;
+ }
+
+ /**
* Returns the long value for Preference if type is {@link #TYPE_LONG}.
*/
public long getLongValue() {
@@ -92,6 +100,7 @@ public final class SettingsPreferenceValue implements Parcelable {
TYPE_LONG,
TYPE_DOUBLE,
TYPE_STRING,
+ TYPE_INT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
@@ -104,6 +113,8 @@ public final class SettingsPreferenceValue implements Parcelable {
public static final int TYPE_DOUBLE = 2;
/** Value is of type string. Access via {@link #getStringValue}. */
public static final int TYPE_STRING = 3;
+ /** Value is of type int. Access via {@link #getIntValue}. */
+ public static final int TYPE_INT = 4;
private SettingsPreferenceValue(@NonNull Builder builder) {
mType = builder.mType;
@@ -111,6 +122,7 @@ public final class SettingsPreferenceValue implements Parcelable {
mLongValue = builder.mLongValue;
mDoubleValue = builder.mDoubleValue;
mStringValue = builder.mStringValue;
+ mIntValue = builder.mIntValue;
}
private SettingsPreferenceValue(@NonNull Parcel in) {
@@ -119,6 +131,7 @@ public final class SettingsPreferenceValue implements Parcelable {
mLongValue = in.readLong();
mDoubleValue = in.readDouble();
mStringValue = in.readString8();
+ mIntValue = in.readInt();
}
/** @hide */
@@ -129,6 +142,7 @@ public final class SettingsPreferenceValue implements Parcelable {
dest.writeLong(mLongValue);
dest.writeDouble(mDoubleValue);
dest.writeString8(mStringValue);
+ dest.writeInt(mIntValue);
}
/** @hide */
@@ -163,6 +177,7 @@ public final class SettingsPreferenceValue implements Parcelable {
private long mLongValue;
private double mDoubleValue;
private String mStringValue;
+ private int mIntValue;
/**
* Create Builder instance.
@@ -183,6 +198,15 @@ public final class SettingsPreferenceValue implements Parcelable {
}
/**
+ * Sets the int value for Preference.
+ */
+ @NonNull
+ public Builder setIntValue(int intValue) {
+ mIntValue = intValue;
+ return this;
+ }
+
+ /**
* Sets long value for Preference.
*/
@NonNull
diff --git a/core/java/android/service/wearable/WearableSensingService.java b/core/java/android/service/wearable/WearableSensingService.java
index 47ec0801f551..e20d5e996e66 100644
--- a/core/java/android/service/wearable/WearableSensingService.java
+++ b/core/java/android/service/wearable/WearableSensingService.java
@@ -27,6 +27,7 @@ import android.app.ambientcontext.AmbientContextEvent;
import android.app.ambientcontext.AmbientContextEventRequest;
import android.app.wearable.Flags;
import android.app.wearable.IWearableSensingCallback;
+import android.app.wearable.WearableConnection;
import android.app.wearable.WearableSensingDataRequest;
import android.app.wearable.WearableSensingManager;
import android.content.Context;
@@ -380,7 +381,11 @@ public abstract class WearableSensingService extends Service {
*
* @param secureWearableConnection The secure connection to the wearable.
* @param statusConsumer The consumer for the service status.
+ * @deprecated Use {@link #onSecureConnectionProvided(ParcelFileDescriptor, PersistableBundle,
+ * Consumer)} instead to receive a remote wearable device connection.
*/
+ @FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
+ @Deprecated
@BinderThread
public void onSecureConnectionProvided(
@NonNull ParcelFileDescriptor secureWearableConnection,
@@ -389,12 +394,20 @@ public abstract class WearableSensingService extends Service {
}
/**
- * Called when a secure connection to the wearable is available.
+ * Called when a secure connection to the wearable is available. See {@link
+ * WearableSensingManager#provideConnection(WearableConnection, Executor)} for details about the
+ * secure connection.
+ *
+ * <p>When the {@code secureWearableConnection} is closed, the system will send a {@link
+ * WearableSensingManager#STATUS_CHANNEL_ERROR} status code to the error callback provided by
+ * the caller of {@link WearableSensingManager#provideConnection(WearableConnection, Executor)}.
+ *
+ * <p>The implementing class should override this method. It should return an appropriate status
+ * code via {@code statusConsumer} after receiving the {@code secureWearableConnection}.
*
* @param secureWearableConnection The secure connection to the wearable.
* @param metadata Metadata related to the provided connection.
* @param statusConsumer The consumer for the service status.
- * @see #onSecureConnectionProvided(ParcelFileDescriptor, Consumer)
*/
@FlaggedApi(Flags.FLAG_ENABLE_CONCURRENT_WEARABLE_CONNECTIONS)
@BinderThread
diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java
index b7b8f0b1b5d8..a337ba2a57fb 100644
--- a/core/java/android/text/style/TtsSpan.java
+++ b/core/java/android/text/style/TtsSpan.java
@@ -19,6 +19,7 @@ package android.text.style;
import static com.android.text.flags.Flags.FLAG_TTS_SPAN_DURATION;
import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.PersistableBundle;
@@ -324,7 +325,8 @@ public class TtsSpan implements ParcelableSpan {
/**
* Argument used to specify the seconds of a time or duration. The seconds should be
- * provided as an integer in the range from 0 up to and including 59.
+ * provided as an integer in the range from 0 up to and including 59 for
+ * {@link #TYPE_TIME}.
* Can be used with {@link #TYPE_TIME} or {@link #TYPE_DURATION}.
*/
@FlaggedApi(FLAG_TTS_SPAN_DURATION)
@@ -1140,7 +1142,7 @@ public class TtsSpan implements ParcelableSpan {
* @return This instance.
* @see #ARG_HOURS
*/
- public TimeBuilder setHours(int hours) {
+ public TimeBuilder setHours(@IntRange(from = 0, to = 24) int hours) {
return setIntArgument(TtsSpan.ARG_HOURS, hours);
}
@@ -1151,7 +1153,7 @@ public class TtsSpan implements ParcelableSpan {
* @return This instance.
* @see #ARG_MINUTES
*/
- public TimeBuilder setMinutes(int minutes) {
+ public TimeBuilder setMinutes(@IntRange(from = 0, to = 59) int minutes) {
return setIntArgument(TtsSpan.ARG_MINUTES, minutes);
}
@@ -1162,7 +1164,7 @@ public class TtsSpan implements ParcelableSpan {
*/
@FlaggedApi(FLAG_TTS_SPAN_DURATION)
@NonNull
- public TimeBuilder setSeconds(int seconds) {
+ public TimeBuilder setSeconds(@IntRange(from = 0, to = 59) int seconds) {
return setIntArgument(TtsSpan.ARG_SECONDS, seconds);
}
}
diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java
index 264db4a604ff..239da87b71ee 100644
--- a/core/java/android/view/AttachedSurfaceControl.java
+++ b/core/java/android/view/AttachedSurfaceControl.java
@@ -210,6 +210,9 @@ public interface AttachedSurfaceControl {
/**
* Registers a {@link OnJankDataListener} to receive jank classification data about rendered
* frames.
+ * <p>
+ * Use {@link SurfaceControl.OnJankDataListenerRegistration#removeAfter} to unregister the
+ * listener.
*
* @param executor The executor on which the listener will be invoked.
* @param listener The listener to add.
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 11a3168daa0e..1f8f0820ca3a 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -372,4 +372,14 @@ interface IWindowSession {
*/
oneway void notifyImeWindowVisibilityChangedFromClient(IWindow window, boolean visible,
in ImeTracker.Token statsToken);
+
+ /**
+ * Notifies WindowState whether inset animations are currently running within the Window.
+ * This value is used by the server to vote for refresh rate.
+ * see {@link com.android.server.wm.WindowState#mInsetsAnimationRunning).
+ *
+ * @param window The window that is insets animaiton is running.
+ * @param running Indicates the insets animation state.
+ */
+ oneway void notifyInsetsAnimationRunningStateChanged(IWindow window, boolean running);
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index d56768d2db03..68674dd402b4 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -37,6 +37,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.Size;
+import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.ColorSpace;
@@ -58,6 +59,7 @@ import android.hardware.display.DeviceProductInfo;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
import android.hardware.graphics.common.DisplayDecorationSupport;
+import android.media.quality.PictureProfileHandle;
import android.opengl.EGLDisplay;
import android.opengl.EGLSync;
import android.os.Build;
@@ -234,7 +236,6 @@ public final class SurfaceControl implements Parcelable {
long nativeObject, float currentBufferRatio, float desiredRatio);
private static native void nativeSetDesiredHdrHeadroom(long transactionObj,
long nativeObject, float desiredRatio);
-
private static native void nativeSetCachingHint(long transactionObj,
long nativeObject, int cachingHint);
private static native void nativeSetDamageRegion(long transactionObj, long nativeObject,
@@ -314,6 +315,11 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeSetLuts(long transactionObj, long nativeObject,
float[] buffers, int[] slots, int[] dimensions, int[] sizes, int[] samplingKeys);
private static native void nativeEnableDebugLogCallPoints(long transactionObj);
+ private static native int nativeGetMaxPictureProfiles();
+ private static native void nativeSetPictureProfileId(long transactionObj,
+ long nativeObject, long pictureProfileId);
+ private static native void nativeSetContentPriority(long transactionObj, long nativeObject,
+ int priority);
/**
* Transforms that can be applied to buffers as they are displayed to a window.
@@ -598,8 +604,11 @@ public final class SurfaceControl implements Parcelable {
}
/**
- * Request a flush of any pending jank classification data. May cause the registered
- * listener to be invoked inband.
+ * Request a flush of any pending jank classification data.
+ * <p>
+ * May cause the registered listener to be invoked inband. Since jank is tracked by the
+ * system compositor by surface, flushing the data on one listener, will also cause other
+ * listeners on the same surface to receive jank classification data.
*/
public void flush() {
nativeFlushJankData(mNativeObject);
@@ -2833,6 +2842,33 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Retrieve the maximum number of concurrent picture profiles allowed across all displays.
+ *
+ * A picture profile is assigned to a layer via:
+ * <ul>
+ * <li>Picture processing via {@link MediaCodec.KEY_PICTURE_PROFILE}</li>
+ * <li>Picture processing via {@link SurfaceControl.Transaction#setPictureProfileHandle}
+ * </li>
+ * </ul>
+ *
+ * If the maximum number is exceeded, some layers will not receive profiles based on:
+ * <ul>
+ * <li>The content priority assigned by the app</li>
+ * <li>The system-determined priority of the app owning the layer</li>
+ * </ul>
+ *
+ * @see MediaCodec.KEY_PICTURE_PROFILE
+ * @see SurfaceControl.Transaction#setPictureProfileHandle
+ * @see SurfaceControl.Transaction#setContentPriority
+ *
+ * @hide
+ */
+ @IntRange(from = 0)
+ public static int getMaxPictureProfiles() {
+ return nativeGetMaxPictureProfiles();
+ }
+
+ /**
* Interface to handle request to
* {@link SurfaceControl.Transaction#addTransactionCommittedListener(Executor, TransactionCommittedListener)}
*/
@@ -4595,6 +4631,71 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Sets the desired picture profile handle for a layer.
+ * <p>
+ * A handle, retrieved from {@link MediaQualityManager#getProfileHandles}, which
+ * refers a set of parameters that are used to configure picture processing that is applied
+ * to all subsequent buffers to enhance the quality of their contents (e.g. gamma, color
+ * temperature, hue, saturation, etc.).
+ * <p>
+ * Setting a handle does not guarantee access to limited picture processing. The content
+ * priority for the as well as the prominance of app to the current user experience plays a
+ * role in which layer(s) get access to the limited picture processing resources. A maximum
+ * number of {@link MediaQualityManager.getMaxPictureProfiles} can be applied at any given
+ * point in time.
+ *
+ * @param sc The SurfaceControl of the layer that should be updated
+ * @param handle The picture profile handle which refers to the set of desired parameters
+ *
+ * @see MediaQualityManager#getMaxPictureProfiles
+ * @see MediaQualityManager#getProfileHandles
+ * @see MediaCodec.KEY_PICTURE_PROFILE
+ * @see SurfaceControl.Transaction#setContentPriority
+ *
+ * @hide
+ */
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
+ @SystemApi
+ public @NonNull Transaction setPictureProfileHandle(@NonNull SurfaceControl sc,
+ @NonNull PictureProfileHandle handle) {
+ checkPreconditions(sc);
+
+ nativeSetPictureProfileId(mNativeObject, sc.mNativeObject, handle.getId());
+ return this;
+ }
+
+ /**
+ * Sets the importance the layer's contents has to the app's user experience.
+ * <p>
+ * When a two layers within the same app are competing for a limited rendering resource,
+ * the priority will determine which layer gets access to the resource. The lower the
+ * priority, the more likely the layer will get access to the resource.
+ * <p>
+ * Resources managed by this priority:
+ * <ul>
+ * <li>Picture processing via {@link MediaCodec.KEY_PICTURE_PROFILE}</li>
+ * <li>Picture processing via {@link SurfaceControl.Transaction#setPictureProfileHandle}
+ * </li>
+ * </ul>
+ *
+ * @param sc The SurfaceControl of the layer that should be updated
+ * @param priority The priority this layer should have with respect to other layers in the
+ * app. The default priority is zero.
+ *
+ * @see MediaQualityManager#getMaxPictureProfiles
+ * @see MediaCodec.KEY_PICTURE_PROFILE
+ * @see SurfaceControl.Transaction#setPictureProfileHandle
+ */
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
+ public @NonNull Transaction setContentPriority(@NonNull SurfaceControl sc,
+ int priority) {
+ checkPreconditions(sc);
+
+ nativeSetContentPriority(mNativeObject, sc.mNativeObject, priority);
+ return this;
+ }
+
+ /**
* Sets the caching hint for the layer. By default, the caching hint is
* {@link CACHING_ENABLED}.
*
diff --git a/core/java/android/view/SurfaceControlActivePicture.java b/core/java/android/view/SurfaceControlActivePicture.java
new file mode 100644
index 000000000000..569159d73d2d
--- /dev/null
+++ b/core/java/android/view/SurfaceControlActivePicture.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.NonNull;
+import android.media.quality.PictureProfileHandle;
+
+/**
+ * A record of a visible layer that is using picture processing.
+ * @hide
+ */
+public class SurfaceControlActivePicture {
+ private final int mLayerId;
+ private final int mOwnerUid;
+ private final @NonNull PictureProfileHandle mPictureProfileHandle;
+
+ /**
+ * Create a record of a visible layer that is using picture processing.
+ *
+ * @param layerId the layer that is using picture processing
+ * @param ownerUid the UID of the package that owns the layer
+ * @param handle the handle for the picture profile that configured the processing
+ */
+ private SurfaceControlActivePicture(int layerId, int ownerUid, PictureProfileHandle handle) {
+ mLayerId = layerId;
+ mOwnerUid = ownerUid;
+ mPictureProfileHandle = handle;
+ }
+
+ /** The layer that is using picture processing. */
+ public int getLayerId() {
+ return mLayerId;
+ }
+
+ /** The UID of the package that owns the layer using picture processing. */
+ public int getOwnerUid() {
+ return mOwnerUid;
+ }
+
+ /** A handle that indicates which picture profile has configured the picture processing. */
+ public @NonNull PictureProfileHandle getPictureProfileHandle() {
+ return mPictureProfileHandle;
+ }
+}
diff --git a/core/java/android/view/SurfaceControlActivePictureListener.java b/core/java/android/view/SurfaceControlActivePictureListener.java
new file mode 100644
index 000000000000..d7c53748784f
--- /dev/null
+++ b/core/java/android/view/SurfaceControlActivePictureListener.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.RequiresPermission;
+
+import libcore.util.NativeAllocationRegistry;
+
+/**
+ * Allows for the monitoring of visible layers that are using picture processing.
+ * @hide
+ */
+public abstract class SurfaceControlActivePictureListener {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ SurfaceControlActivePictureListener.class.getClassLoader(),
+ nativeGetDestructor());
+
+ /**
+ * Callback when there are changes in the visible layers that are using picture processing.
+ *
+ * @param activePictures The visible layers that are using picture processing.
+ */
+ public abstract void onActivePicturesChanged(SurfaceControlActivePicture[] activePictures);
+
+ /**
+ * Start listening to changes in active pictures.
+ */
+ @RequiresPermission(android.Manifest.permission.OBSERVE_PICTURE_PROFILES)
+ public void startListening() {
+ synchronized (this) {
+ long nativePtr = nativeMakeAndStartListening();
+ mDestructor = sRegistry.registerNativeAllocation(this, nativePtr);
+ }
+ }
+
+ /**
+ * Stop listening to changes in active pictures.
+ */
+ @RequiresPermission(android.Manifest.permission.OBSERVE_PICTURE_PROFILES)
+ public void stopListening() {
+ final Runnable destructor;
+ synchronized (this) {
+ destructor = mDestructor;
+ }
+ if (destructor != null) {
+ destructor.run();
+ }
+ }
+
+ private native long nativeMakeAndStartListening();
+ private static native long nativeGetDestructor();
+
+ private Runnable mDestructor;
+}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 19d3dc4df04e..072a835eb664 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -110,7 +110,6 @@ import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_B
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
-import static android.view.accessibility.Flags.fixMergedContentChangeEventV2;
import static android.view.accessibility.Flags.forceInvertColor;
import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
import static android.view.flags.Flags.addSchandleToVriSurface;
@@ -2515,12 +2514,16 @@ public final class ViewRootImpl implements ViewParent,
@VisibleForTesting
public void notifyInsetsAnimationRunningStateChanged(boolean running) {
if (sToolkitSetFrameRateReadOnlyFlagValue) {
- mInsetsAnimationRunning = running;
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
Trace.instant(Trace.TRACE_TAG_VIEW,
TextUtils.formatSimple("notifyInsetsAnimationRunningStateChanged(%s)",
Boolean.toString(running)));
}
+ mInsetsAnimationRunning = running;
+ try {
+ mWindowSession.notifyInsetsAnimationRunningStateChanged(mWindow, running);
+ } catch (RemoteException e) {
+ }
}
}
@@ -12290,31 +12293,20 @@ public final class ViewRootImpl implements ViewParent,
}
if (mSource != null) {
- if (fixMergedContentChangeEventV2()) {
- View newSource = getCommonPredecessor(mSource, source);
- if (newSource != null) {
- newSource = newSource.getSelfOrParentImportantForA11y();
- }
- if (newSource == null) {
- // If there is no common predecessor, then mSource points to
- // a removed view, hence in this case always prefer the source.
- newSource = source;
- }
-
- mChangeTypes |= changeType;
- if (mSource != newSource) {
- mChangeTypes |= AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
- mSource = newSource;
- }
- } else {
+ View newSource = getCommonPredecessor(mSource, source);
+ if (newSource != null) {
+ newSource = newSource.getSelfOrParentImportantForA11y();
+ }
+ if (newSource == null) {
// If there is no common predecessor, then mSource points to
// a removed view, hence in this case always prefer the source.
- View predecessor = getCommonPredecessor(mSource, source);
- if (predecessor != null) {
- predecessor = predecessor.getSelfOrParentImportantForA11y();
- }
- mSource = (predecessor != null) ? predecessor : source;
- mChangeTypes |= changeType;
+ newSource = source;
+ }
+
+ mChangeTypes |= changeType;
+ if (mSource != newSource) {
+ mChangeTypes |= AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
+ mSource = newSource;
}
final int performingAction = mAccessibilityManager.getPerformingAction();
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 65e993049979..72a595d95ec2 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -679,6 +679,11 @@ public class WindowlessWindowManager implements IWindowSession {
@NonNull ImeTracker.Token statsToken) {
}
+ @Override
+ public void notifyInsetsAnimationRunningStateChanged(IWindow window, boolean running) {
+ // NO-OP
+ }
+
void setParentInterface(@Nullable ISurfaceControlViewHostParent parentInterface) {
IBinder oldInterface = mParentInterface == null ? null : mParentInterface.asBinder();
IBinder newInterface = parentInterface == null ? null : parentInterface.asBinder();
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index 8a006fa5b509..e60fc3ae6b47 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -99,16 +99,6 @@ flag {
flag {
namespace: "accessibility"
- name: "fix_merged_content_change_event_v2"
- description: "Fixes event type and source of content change event merged in ViewRootImpl"
- bug: "277305460"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
- namespace: "accessibility"
name: "flash_notification_system_api"
is_exported: true
description: "Makes flash notification APIs as system APIs for calling from mainline module"
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index 4f48cb684e8c..1806a8369d01 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -16,6 +16,7 @@
package android.view.inputmethod;
+import android.annotation.NonNull;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.Bundle;
@@ -125,6 +126,23 @@ public interface InputMethodSession {
public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback);
/**
+ * Received by the IME before dispatch to {@link InputMethodService#onKeyDown(int, KeyEvent)}
+ * to let the system know if the {@link KeyEvent} needs to be verified that it originated from
+ * the system. {@link KeyEvent}s may originate from outside of the system and any sensitive keys
+ * should be marked for verification. One example of this could be using key shortcuts for
+ * switching to another IME.
+ *
+ * @param event the event that may need verification.
+ * @return {@code true} if {@link KeyEvent} should have its HMAC verified before dispatch,
+ * {@code false} otherwise.
+ *
+ * @hide
+ */
+ default boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) {
+ return false;
+ }
+
+ /**
* This method is called when there is a track ball event.
*
* <p>
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index deaf95797127..73abc472be6d 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -184,3 +184,11 @@ flag {
bug: "350047836"
is_fixed_read_only: true
}
+
+flag {
+ name: "verify_key_event"
+ namespace: "input_method"
+ description: "Verify KeyEvents in IME"
+ bug: "331730488"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 98c00ac7f6f7..0bf6380eb904 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -16,17 +16,22 @@
package android.widget;
-import static android.view.flags.Flags.enableArrowIconOnHoverWhenClickable;
import static android.view.flags.Flags.FLAG_ENABLE_ARROW_ICON_ON_HOVER_WHEN_CLICKABLE;
+import static android.view.flags.Flags.enableArrowIconOnHoverWhenClickable;
import android.annotation.FlaggedApi;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.util.AttributeSet;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.widget.RemoteViews.RemoteView;
+import android.widget.flags.Flags;
/**
* A user interface element the user can tap or click to perform an action.
@@ -88,6 +93,12 @@ import android.widget.RemoteViews.RemoteView;
@RemoteView
public class Button extends TextView {
+ @ChangeId
+ @EnabledSince(targetSdkVersion = 36)
+ private static final long WEAR_MATERIAL3_BUTTON = 376561342L;
+
+ private static Boolean sUseWearMaterial3Style;
+
/**
* Simple constructor to use when creating a button from code.
*
@@ -118,7 +129,18 @@ public class Button extends TextView {
* @see android.view.View#View(Context, AttributeSet)
*/
public Button(Context context, AttributeSet attrs) {
- this(context, attrs, com.android.internal.R.attr.buttonStyle);
+ // Starting sdk 36+, wear devices will use a specific material3
+ // design. The new design will be applied when all of following conditions are met:
+ // 1. app target sdk is 36 or above.
+ // 2. feature flag rolled-out.
+ // 3. device is a watch.
+ // getButtonDefaultStyleAttr and getButtonDefaultStyleRes works together to alter the UI
+ // while considering the conditions above.
+ // Their results are mutual exclusive. i.e. when conditions above are all true,
+ // getButtonDefaultStyleRes returns non-zero value(new wear material3), abd
+ // getButtonDefaultStyleAttr returns 0. Otherwise, getButtonDefaultStyleAttr returns system
+ // attr com.android.internal.R.attr.buttonStyle and getButtonDefaultStyleRes returns 0.
+ this(context, attrs, getButtonDefaultStyleAttr(context), getButtonDefaultStyleRes());
}
/**
@@ -189,4 +211,24 @@ public class Button extends TextView {
}
return super.onResolvePointerIcon(event, pointerIndex);
}
+
+ private static int getButtonDefaultStyleAttr(Context context) {
+ sUseWearMaterial3Style = useWearMaterial3Style(context);
+ if (sUseWearMaterial3Style) {
+ return 0;
+ }
+ return com.android.internal.R.attr.buttonStyle;
+ }
+
+ private static int getButtonDefaultStyleRes() {
+ if (sUseWearMaterial3Style != null && sUseWearMaterial3Style) {
+ return com.android.internal.R.style.Widget_DeviceDefault_Button_WearMaterial3;
+ }
+ return 0;
+ }
+
+ private static boolean useWearMaterial3Style(Context context) {
+ return Flags.useWearMaterial3Ui() && CompatChanges.isChangeEnabled(WEAR_MATERIAL3_BUTTON)
+ && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 9b6311f35d17..80d39d1f9a1c 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -20,6 +20,7 @@ import static android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL;
import static android.appwidget.flags.Flags.FLAG_REMOTE_VIEWS_PROTO;
import static android.appwidget.flags.Flags.drawDataParcel;
import static android.appwidget.flags.Flags.remoteAdapterConversion;
+import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
import static android.util.proto.ProtoInputStream.NO_MORE_FIELDS;
import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
@@ -54,6 +55,10 @@ import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
+import android.content.om.FabricatedOverlay;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.content.om.OverlayManagerTransaction;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.ColorStateList;
@@ -1559,6 +1564,16 @@ public class RemoteViews implements Parcelable, Filter {
final Context context = ActivityThread.currentApplication();
final CompletableFuture<RemoteCollectionItems> result = new CompletableFuture<>();
+ String contextPackageName = context.getPackageName();
+ ComponentName intentComponent = intent.getComponent();
+ if (contextPackageName != null
+ && intentComponent != null
+ && (!contextPackageName.equals(intentComponent.getPackageName()))) {
+ // We shouldn't allow for connections to other packages
+ result.complete(new RemoteCollectionItems.Builder().build());
+ return result;
+ }
+
context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
result.defaultExecutor(), new ServiceConnection() {
@Override
@@ -8468,8 +8483,11 @@ public class RemoteViews implements Parcelable, Filter {
}
try {
LoadedApk.checkAndUpdateApkPaths(mApplication);
- return context.createApplicationContext(mApplication,
+ Context applicationContext = context.createApplicationContext(mApplication,
Context.CONTEXT_RESTRICTED);
+ // Get the correct apk paths while maintaining the current context's configuration.
+ return applicationContext.createConfigurationContext(
+ context.getResources().getConfiguration());
} catch (NameNotFoundException e) {
Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found");
}
@@ -8547,8 +8565,6 @@ public class RemoteViews implements Parcelable, Filter {
/**
* Object allowing the modification of a context to overload the system's dynamic colors.
*
- * Only colors from {@link android.R.color#system_accent1_0} to
- * {@link android.R.color#system_neutral2_1000} can be overloaded.
* @hide
*/
public static final class ColorResources {
@@ -8559,6 +8575,9 @@ public class RemoteViews implements Parcelable, Filter {
// Size, in bytes, of an entry in the array of colors in an ARSC file.
private static final int ARSC_ENTRY_SIZE = 16;
+ private static final String OVERLAY_NAME = "remote_views_color_resources";
+ private static final String OVERLAY_TARGET_PACKAGE_NAME = "android";
+
private final ResourcesLoader mLoader;
private final SparseIntArray mColorMapping;
@@ -8629,7 +8648,11 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
- * Adds a resource loader for theme colors to the given context.
+ * Adds a resource loader for theme colors to the given context. The loader is created
+ * based on resource files created at build time.
+ *
+ * <p>Only colors from {@link android.R.color#system_accent1_0} to
+ * {@link android.R.color#system_error_1000} can be overloaded.</p>
*
* @param context Context of the view hosting the widget.
* @param colorMapping Mapping of resources to color values.
@@ -8667,6 +8690,57 @@ public class RemoteViews implements Parcelable, Filter {
}
return null;
}
+
+ /**
+ * Adds a resource loader for theme colors to the given context. The loader is created
+ * using fabricated runtime resource overlay (FRRO).
+ *
+ * <p>The created class can overlay any color resources, private or public, at runtime.</p>
+ *
+ * @param context Context of the view hosting the widget.
+ * @param colorMapping Mapping of resources to color values.
+ *
+ * @hide
+ */
+ @Nullable
+ public static ColorResources createWithOverlay(Context context,
+ SparseIntArray colorMapping) {
+ try {
+ String owningPackage = context.getPackageName();
+ FabricatedOverlay overlay = new FabricatedOverlay.Builder(owningPackage,
+ OVERLAY_NAME, OVERLAY_TARGET_PACKAGE_NAME).build();
+
+ for (int i = 0; i < colorMapping.size(); i++) {
+ overlay.setResourceValue(
+ context.getResources().getResourceName(colorMapping.keyAt(i)),
+ TYPE_INT_COLOR_ARGB8, colorMapping.valueAt(i), null);
+ }
+ OverlayManager overlayManager = context.getSystemService(OverlayManager.class);
+ OverlayManagerTransaction.Builder transaction =
+ new OverlayManagerTransaction.Builder()
+ .registerFabricatedOverlay(overlay)
+ .setSelfTargeting(true);
+ overlayManager.commit(transaction.build());
+
+ OverlayInfo overlayInfo =
+ overlayManager.getOverlayInfosForTarget(OVERLAY_TARGET_PACKAGE_NAME)
+ .stream()
+ .filter(info -> TextUtils.equals(info.overlayName, OVERLAY_NAME)
+ && TextUtils.equals(info.packageName, owningPackage))
+ .findFirst()
+ .orElse(null);
+ if (overlayInfo == null) {
+ Log.e(LOG_TAG, "Failed to get overlay info ", new Throwable());
+ return null;
+ }
+ ResourcesLoader colorsLoader = new ResourcesLoader();
+ colorsLoader.addProvider(ResourcesProvider.loadOverlay(overlayInfo));
+ return new ColorResources(colorsLoader, colorMapping.clone());
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Failed to add theme color overlay into loader", e);
+ }
+ return null;
+ }
}
/**
diff --git a/core/java/android/widget/flags/flags.aconfig b/core/java/android/widget/flags/flags.aconfig
index f0ed83be8f1e..d9dc36ccc8c3 100644
--- a/core/java/android/widget/flags/flags.aconfig
+++ b/core/java/android/widget/flags/flags.aconfig
@@ -8,4 +8,12 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
-} \ No newline at end of file
+}
+
+flag {
+ name: "use_wear_material3_ui"
+ namespace: "wear_frameworks"
+ description: "Whether enable material3 style for wear frameworks' widgets."
+ is_exported: true
+ bug: "369480667"
+}
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index 16eb43700aef..b535effd393a 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -67,7 +67,6 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL
.setStiffness(SpringForce.STIFFNESS_MEDIUM)
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
private final SpringForce mButtonSpringForce = new SpringForce()
- .setStiffness(500)
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY);
private final DynamicAnimation.OnAnimationEndListener mOnAnimationEndListener =
(animation, canceled, value, velocity) -> {
@@ -157,6 +156,7 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL
/* frameTime */ System.nanoTime() / TimeUtils.NANOS_PER_MS);
if (predictiveBackSwipeEdgeNoneApi()) {
if (event.getSwipeEdge() == EDGE_NONE) {
+ mButtonSpringForce.setStiffness(SpringForce.STIFFNESS_LOW);
mSpring.setSpring(mButtonSpringForce);
mSpring.animateToFinalPosition(SCALE_FACTOR);
} else {
@@ -228,6 +228,7 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL
* @param finishCallback the callback to be invoked when the progress is reach to 0.
*/
public void onBackCancelled(@NonNull Runnable finishCallback) {
+ mButtonSpringForce.setStiffness(SpringForce.STIFFNESS_MEDIUM);
mBackCancelledFinishRunnable = finishCallback;
mSpring.addEndListener(mOnAnimationEndListener);
mSpring.animateToFinalPosition(0);
diff --git a/core/java/android/window/IBackAnimationHandoffHandler.aidl b/core/java/android/window/IBackAnimationHandoffHandler.aidl
new file mode 100644
index 000000000000..577948dd0abc
--- /dev/null
+++ b/core/java/android/window/IBackAnimationHandoffHandler.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+
+ */
+
+package android.window;
+
+import android.os.Bundle;
+import android.view.RemoteAnimationTarget;
+import android.window.BackMotionEvent;
+import android.window.WindowAnimationState;
+
+
+/**
+ * Interface that allows an {@link OnBackInvokedCallback} object to hand off an animation to another
+ * handler.
+ *
+ * @hide
+ */
+oneway interface IBackAnimationHandoffHandler {
+ /**
+ * Triggers a handoff of the animation of the given targets and their associated states.
+ * Important: since this is a one-way method, the caller must first make sure that the animation
+ * can indeed be taken over.
+ */
+ oneway void handOffAnimation(in RemoteAnimationTarget[] targets,
+ in WindowAnimationState[] states);
+}
diff --git a/core/java/android/window/IOnBackInvokedCallback.aidl b/core/java/android/window/IOnBackInvokedCallback.aidl
index e07d4a9fc61b..81ad4b7bd19e 100644
--- a/core/java/android/window/IOnBackInvokedCallback.aidl
+++ b/core/java/android/window/IOnBackInvokedCallback.aidl
@@ -18,6 +18,7 @@
package android.window;
import android.window.BackMotionEvent;
+import android.window.IBackAnimationHandoffHandler;
/**
* Interface that wraps a {@link OnBackInvokedCallback} object, to be stored in window manager
@@ -61,4 +62,9 @@ oneway interface IOnBackInvokedCallback {
* Sets whether the back gesture is past the trigger threshold.
*/
void setTriggerBack(in boolean triggerBack);
+
+ /**
+ * Sets a {@link IBackAnimationHandoffHandler} that can be used to hand off the back animation.
+ */
+ void setHandoffHandler(in IBackAnimationHandoffHandler handoffHandler);
}
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index c67b9cac250b..d478108d928a 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -392,6 +392,11 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
// no-op
}
+ @Override
+ public void setHandoffHandler(IBackAnimationHandoffHandler handoffHandler) {
+ // no-op
+ }
+
private void maybeRunOnAnimationCallback(Consumer<OnBackAnimationCallback> block) {
if (mCallback instanceof OnBackAnimationCallback) {
mHandler.post(() -> block.accept((OnBackAnimationCallback) mCallback));
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 0ea4bb41d3a4..20e3f6b93bd0 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -546,6 +546,11 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
}
@Override
+ public void setHandoffHandler(IBackAnimationHandoffHandler handoffHandler) {
+ // no-op
+ }
+
+ @Override
public void onBackProgressed(BackMotionEvent backEvent) {
// This is only called in some special cases such as when activity embedding is active
// or when the activity is letterboxed. Otherwise mProgressAnimator#onBackProgressed is
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index 96b9dc7cab0e..bb4770768cb1 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -29,14 +29,6 @@ flag {
flag {
namespace: "window_surfaces"
- name: "secure_window_state"
- description: "Move SC secure flag to WindowState level"
- is_fixed_read_only: true
- bug: "308662081"
-}
-
-flag {
- namespace: "window_surfaces"
name: "trusted_presentation_listener_for_window"
is_exported: true
description: "Enable trustedPresentationListener on windows public API"
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index ff69610dbf0e..86bbeb827703 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -200,6 +200,13 @@ flag {
}
flag {
+ name: "show_app_handle_large_screens"
+ namespace: "windowing_frontend"
+ description: "Show the app handle and the app menu also on large screens that don't enable desktop mode"
+ bug: "377689543"
+}
+
+flag {
name: "filter_irrelevant_input_device_change"
namespace: "windowing_frontend"
description: "Recompute display configuration only for necessary input device changes"
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index 07e178c0ba27..38593b4a2a99 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -19,6 +19,7 @@ package com.android.internal.content.om;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.PackagePartitions;
+import android.content.res.AssetManager;
import android.os.Build;
import android.os.Trace;
import android.util.ArrayMap;
@@ -533,7 +534,7 @@ public class OverlayConfig {
*/
@NonNull
public String[] createImmutableFrameworkIdmapsInZygote() {
- final String targetPath = "/system/framework/framework-res.apk";
+ final String targetPath = AssetManager.FRAMEWORK_APK_PATH;
final ArrayList<String> idmapPaths = new ArrayList<>();
final ArrayList<IdmapInvocation> idmapInvocations =
getImmutableFrameworkOverlayIdmapInvocations();
diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
index c4624498138d..fa5cf2a396b9 100644
--- a/core/java/com/android/internal/content/om/OverlayManagerImpl.java
+++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
@@ -35,6 +35,7 @@ import android.content.om.OverlayManagerTransaction.Request;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.parsing.FrameworkParsingPackageUtils;
+import android.content.res.AssetManager;
import android.os.FabricatedOverlayInfo;
import android.os.FabricatedOverlayInternal;
import android.os.FabricatedOverlayInternalEntry;
@@ -60,8 +61,8 @@ import java.util.List;
import java.util.Objects;
/**
- * This class provides the functionalities of registering an overlay, unregistering an overlay, and
- * getting the list of overlays information.
+ * This class provides the functionalities for managing self-targeting overlays, including
+ * registering an overlay, unregistering an overlay, and getting the list of overlays information.
*/
public class OverlayManagerImpl {
private static final String TAG = "OverlayManagerImpl";
@@ -234,14 +235,17 @@ public class OverlayManagerImpl {
Preconditions.checkArgument(!entryList.isEmpty(), "overlay entries shouldn't be empty");
final String overlayName = checkOverlayNameValid(overlayInternal.overlayName);
checkPackageName(overlayInternal.packageName);
- checkPackageName(overlayInternal.targetPackageName);
- Preconditions.checkStringNotEmpty(
- overlayInternal.targetOverlayable,
- "Target overlayable should be neither null nor empty string.");
+ Preconditions.checkStringNotEmpty(overlayInternal.targetPackageName);
final ApplicationInfo applicationInfo = mContext.getApplicationInfo();
- final String targetPackage = Preconditions.checkStringNotEmpty(
- applicationInfo.getBaseCodePath());
+ String targetPackage = null;
+ if (TextUtils.equals(overlayInternal.targetPackageName, "android")) {
+ targetPackage = AssetManager.FRAMEWORK_APK_PATH;
+ } else {
+ targetPackage = Preconditions.checkStringNotEmpty(
+ applicationInfo.getBaseCodePath());
+ }
+
final Path frroPath = mBasePath.resolve(overlayName + FRRO_EXTENSION);
final Path idmapPath = mBasePath.resolve(overlayName + IDMAP_EXTENSION);
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index 8771cde1de46..be3bbb2d1d94 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -70,7 +70,7 @@ public class LegacyProtoLogImpl implements IProtoLog {
private final TraceBuffer mBuffer;
private final LegacyProtoLogViewerConfigReader mViewerConfig;
private final Map<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
- private final Runnable mCacheUpdater;
+ private final ProtoLogCacheUpdater mCacheUpdater;
private final int mPerChunkSize;
private boolean mProtoLogEnabled;
@@ -78,14 +78,14 @@ public class LegacyProtoLogImpl implements IProtoLog {
private final Object mProtoLogEnabledLock = new Object();
public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
- Runnable cacheUpdater) {
+ ProtoLogCacheUpdater cacheUpdater) {
this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, cacheUpdater);
}
public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
- Runnable cacheUpdater) {
+ ProtoLogCacheUpdater cacheUpdater) {
mLogFile = file;
mBuffer = new TraceBuffer(bufferCapacity);
mLegacyViewerConfigFilename = viewerConfigFilename;
@@ -298,7 +298,7 @@ public class LegacyProtoLogImpl implements IProtoLog {
}
}
- mCacheUpdater.run();
+ mCacheUpdater.update(this);
return 0;
}
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index eb682dff14de..05a33fe830e8 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -51,7 +51,6 @@ import android.os.ServiceManager;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.text.TextUtils;
-import android.tracing.perfetto.DataSourceParams;
import android.tracing.perfetto.InitArguments;
import android.tracing.perfetto.Producer;
import android.tracing.perfetto.TracingContext;
@@ -86,7 +85,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import java.util.stream.Stream;
/**
* A service for the ProtoLog logging system.
@@ -98,10 +96,12 @@ public abstract class PerfettoProtoLogImpl extends IProtoLogClient.Stub implemen
@NonNull
protected final ProtoLogDataSource mDataSource;
+ @Nullable
+ protected final IProtoLogConfigurationService mConfigurationService;
@NonNull
protected final TreeMap<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
@NonNull
- private final Runnable mCacheUpdater;
+ private final ProtoLogCacheUpdater mCacheUpdater;
@NonNull
private final int[] mDefaultLogLevelCounts = new int[LogLevel.values().length];
@@ -117,10 +117,10 @@ public abstract class PerfettoProtoLogImpl extends IProtoLogClient.Stub implemen
private boolean mLogcatReady = false;
protected PerfettoProtoLogImpl(
- @NonNull Runnable cacheUpdater,
+ @NonNull ProtoLogDataSource dataSource,
+ @NonNull ProtoLogCacheUpdater cacheUpdater,
@NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
- this(cacheUpdater, groups,
- ProtoLogDataSource::new,
+ this(dataSource, cacheUpdater, groups,
android.tracing.Flags.clientSideProtoLogging() ?
IProtoLogConfigurationService.Stub.asInterface(
ServiceManager.getServiceOrThrow(PROTOLOG_CONFIGURATION_SERVICE)
@@ -129,49 +129,62 @@ public abstract class PerfettoProtoLogImpl extends IProtoLogClient.Stub implemen
}
protected PerfettoProtoLogImpl(
- @NonNull Runnable cacheUpdater,
+ @NonNull ProtoLogDataSource dataSource,
+ @NonNull ProtoLogCacheUpdater cacheUpdater,
@NonNull IProtoLogGroup[] groups,
- @NonNull ProtoLogDataSourceBuilder dataSourceBuilder,
@Nullable IProtoLogConfigurationService configurationService) {
- mDataSource = dataSourceBuilder.build(
- this::onTracingInstanceStart,
- this::onTracingFlush,
- this::onTracingInstanceStop);
- Producer.init(InitArguments.DEFAULTS);
- DataSourceParams params =
- new DataSourceParams.Builder()
- .setBufferExhaustedPolicy(
- DataSourceParams
- .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
- .build();
- // NOTE: Registering that datasource is an async operation, so there may be no data traced
- // for some messages logged right after the construction of this class.
- mDataSource.register(params);
-
- this.mCacheUpdater = cacheUpdater;
+ mDataSource = dataSource;
+ mCacheUpdater = cacheUpdater;
+ mConfigurationService = configurationService;
registerGroupsLocally(groups);
+ }
+
+ /**
+ * To be called to enable the ProtoLogImpl to start tracing to ProtoLog and register with all
+ * the expected ProtoLog components.
+ */
+ public void enable() {
+ Producer.init(InitArguments.DEFAULTS);
if (android.tracing.Flags.clientSideProtoLogging()) {
- Objects.requireNonNull(configurationService,
- "A null ProtoLog Configuration Service was provided!");
+ connectToConfigurationService();
+ }
- try {
- var args = createConfigurationServiceRegisterClientArgs();
+ mDataSource.registerOnStartCallback(this::onTracingInstanceStart);
+ mDataSource.registerOnFlushCallback(this::onTracingFlush);
+ mDataSource.registerOnStopCallback(this::onTracingInstanceStop);
+ }
- final var groupArgs = Stream.of(groups)
- .map(group -> new RegisterClientArgs
- .GroupConfig(group.name(), group.isLogToLogcat()))
- .toArray(RegisterClientArgs.GroupConfig[]::new);
- args.setGroups(groupArgs);
+ private void connectToConfigurationService() {
+ Objects.requireNonNull(mConfigurationService,
+ "A null ProtoLog Configuration Service was provided!");
- configurationService.registerClient(this, args);
- } catch (RemoteException e) {
- throw new RuntimeException("Failed to register ProtoLog client");
- }
+ try {
+ var args = createConfigurationServiceRegisterClientArgs();
+
+ final var groupArgs = mLogGroups.values().stream()
+ .map(group -> new RegisterClientArgs
+ .GroupConfig(group.name(), group.isLogToLogcat()))
+ .toArray(RegisterClientArgs.GroupConfig[]::new);
+ args.setGroups(groupArgs);
+
+ mConfigurationService.registerClient(this, args);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed to register ProtoLog client");
}
}
+ /**
+ * Should be called when we no longer want to use the ProtoLog logger to unlink ourselves from
+ * the datasource and the configuration service to ensure we no longer receive the callback.
+ */
+ public void disable() {
+ mDataSource.unregisterOnStartCallback(this::onTracingInstanceStart);
+ mDataSource.unregisterOnFlushCallback(this::onTracingFlush);
+ mDataSource.unregisterOnStopCallback(this::onTracingInstanceStop);
+ }
+
@NonNull
protected abstract RegisterClientArgs createConfigurationServiceRegisterClientArgs();
@@ -703,7 +716,7 @@ public abstract class PerfettoProtoLogImpl extends IProtoLogClient.Stub implemen
}
}
- mCacheUpdater.run();
+ mCacheUpdater.update(this);
return 0;
}
@@ -746,7 +759,7 @@ public abstract class PerfettoProtoLogImpl extends IProtoLogClient.Stub implemen
}
}
- mCacheUpdater.run();
+ mCacheUpdater.update(this);
this.mTracingInstances.incrementAndGet();
@@ -786,7 +799,7 @@ public abstract class PerfettoProtoLogImpl extends IProtoLogClient.Stub implemen
}
}
- mCacheUpdater.run();
+ mCacheUpdater.update(this);
Log.d(LOG_TAG, "Finished onTracingInstanceStop");
}
diff --git a/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java
index 967a5ed1744d..e0a77d2be724 100644
--- a/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java
@@ -42,10 +42,11 @@ public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
private final String mViewerConfigFilePath;
public ProcessedPerfettoProtoLogImpl(
+ @NonNull ProtoLogDataSource datasource,
@NonNull String viewerConfigFilePath,
- @NonNull Runnable cacheUpdater,
+ @NonNull ProtoLogCacheUpdater cacheUpdater,
@NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
- this(viewerConfigFilePath, new ViewerConfigInputStreamProvider() {
+ this(datasource, viewerConfigFilePath, new ViewerConfigInputStreamProvider() {
@NonNull
@Override
public AutoClosableProtoInputStream getInputStream() {
@@ -64,11 +65,12 @@ public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
@VisibleForTesting
public ProcessedPerfettoProtoLogImpl(
+ @NonNull ProtoLogDataSource datasource,
@NonNull String viewerConfigFilePath,
@NonNull ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
- @NonNull Runnable cacheUpdater,
+ @NonNull ProtoLogCacheUpdater cacheUpdater,
@NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
- super(cacheUpdater, groups);
+ super(datasource, cacheUpdater, groups);
this.mViewerConfigFilePath = viewerConfigFilePath;
@@ -80,15 +82,15 @@ public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
@VisibleForTesting
public ProcessedPerfettoProtoLogImpl(
+ @NonNull ProtoLogDataSource datasource,
@NonNull String viewerConfigFilePath,
@NonNull ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
@NonNull ProtoLogViewerConfigReader viewerConfigReader,
- @NonNull Runnable cacheUpdater,
+ @NonNull ProtoLogCacheUpdater cacheUpdater,
@NonNull IProtoLogGroup[] groups,
- @NonNull ProtoLogDataSourceBuilder dataSourceBuilder,
@Nullable IProtoLogConfigurationService configurationService)
throws ServiceManager.ServiceNotFoundException {
- super(cacheUpdater, groups, dataSourceBuilder, configurationService);
+ super(datasource, cacheUpdater, groups, configurationService);
this.mViewerConfigFilePath = viewerConfigFilePath;
diff --git a/core/java/com/android/internal/protolog/ProtoLog.java b/core/java/com/android/internal/protolog/ProtoLog.java
index d117e93d7de7..c81af959f36c 100644
--- a/core/java/com/android/internal/protolog/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/ProtoLog.java
@@ -17,6 +17,9 @@
package com.android.internal.protolog;
import android.os.ServiceManager;
+import android.tracing.perfetto.DataSourceParams;
+import android.tracing.perfetto.InitArguments;
+import android.tracing.perfetto.Producer;
import com.android.internal.protolog.common.IProtoLog;
import com.android.internal.protolog.common.IProtoLogGroup;
@@ -54,6 +57,8 @@ public class ProtoLog {
private static IProtoLog sProtoLogInstance;
+ private static ProtoLogDataSource sDataSource;
+
private static final Object sInitLock = new Object();
/**
@@ -69,26 +74,45 @@ public class ProtoLog {
// files to extract out the log strings. Otherwise, the trace calls are replaced with calls
// directly to the generated tracing implementations.
if (android.tracing.Flags.perfettoProtologTracing()) {
- synchronized (sInitLock) {
- final var allGroups = new HashSet<>(Arrays.stream(groups).toList());
- if (sProtoLogInstance != null) {
- // The ProtoLog instance has already been initialized in this process
- final var alreadyRegisteredGroups = sProtoLogInstance.getRegisteredGroups();
- allGroups.addAll(alreadyRegisteredGroups);
- }
-
- try {
- sProtoLogInstance = new UnprocessedPerfettoProtoLogImpl(
- allGroups.toArray(new IProtoLogGroup[0]));
- } catch (ServiceManager.ServiceNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
+ initializePerfettoProtoLog(groups);
} else {
sProtoLogInstance = new LogcatOnlyProtoLogImpl();
}
}
+ private static void initializePerfettoProtoLog(IProtoLogGroup... groups) {
+ var datasource = getSharedSingleInstanceDataSource();
+
+ synchronized (sInitLock) {
+ final var allGroups = new HashSet<>(Arrays.stream(groups).toList());
+ final var previousProtoLogImpl = sProtoLogInstance;
+ if (previousProtoLogImpl != null) {
+ // The ProtoLog instance has already been initialized in this process
+ final var alreadyRegisteredGroups = previousProtoLogImpl.getRegisteredGroups();
+ allGroups.addAll(alreadyRegisteredGroups);
+ }
+
+ sProtoLogInstance = createAndEnableNewPerfettoProtoLogImpl(
+ datasource, allGroups.toArray(new IProtoLogGroup[0]));
+ if (previousProtoLogImpl instanceof PerfettoProtoLogImpl) {
+ ((PerfettoProtoLogImpl) previousProtoLogImpl).disable();
+ }
+ }
+ }
+
+ private static PerfettoProtoLogImpl createAndEnableNewPerfettoProtoLogImpl(
+ ProtoLogDataSource datasource, IProtoLogGroup[] groups) {
+ try {
+ var unprocessedPerfettoProtoLogImpl =
+ new UnprocessedPerfettoProtoLogImpl(datasource, groups);
+ unprocessedPerfettoProtoLogImpl.enable();
+
+ return unprocessedPerfettoProtoLogImpl;
+ } catch (ServiceManager.ServiceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* DEBUG level log.
*
@@ -190,6 +214,32 @@ public class ProtoLog {
return sProtoLogInstance;
}
+ /**
+ * Gets or creates if it doesn't exist yet the protolog datasource to use in this process.
+ * We should re-use the same datasource to avoid registering the datasource multiple times in
+ * the same process, since there is no way to unregister the datasource after registration.
+ *
+ * @return The single ProtoLog datasource instance to be shared across all ProtoLog tracing
+ * objects.
+ */
+ public static synchronized ProtoLogDataSource getSharedSingleInstanceDataSource() {
+ if (sDataSource == null) {
+ Producer.init(InitArguments.DEFAULTS);
+ sDataSource = new ProtoLogDataSource();
+ DataSourceParams params =
+ new DataSourceParams.Builder()
+ .setBufferExhaustedPolicy(
+ DataSourceParams
+ .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
+ .build();
+ // NOTE: Registering that datasource is an async operation, so there may be no data
+ // traced for some messages logged right after the construction of this class.
+ sDataSource.register(params);
+ }
+
+ return sDataSource;
+ }
+
private static void logStringMessage(LogLevel logLevel, IProtoLogGroup group,
String stringMessage, Object... args) {
if (sProtoLogInstance == null) {
diff --git a/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl b/core/java/com/android/internal/protolog/ProtoLogCacheUpdater.java
index 699422493dd6..4f8655c6377b 100644
--- a/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl
+++ b/core/java/com/android/internal/protolog/ProtoLogCacheUpdater.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.media.tv.extension.scan;
+package com.android.internal.protolog;
-import android.os.Bundle;
+import com.android.internal.protolog.common.IProtoLog;
-/**
- * @hide
- */
-oneway interface IFavoriteNetworkListener {
- void onDetectFavoriteNetwork(in Bundle detectFavoriteNetworks);
+public interface ProtoLogCacheUpdater {
+ /**
+ * Update the cache based on the latest state of the active tracing configurations.
+ *
+ * @param protoLogInstance the instance to use to query the latest state of tracing.
+ */
+ void update(IProtoLog protoLogInstance);
}
diff --git a/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java b/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java
index e9a8770deb73..23f7c2a3d987 100644
--- a/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogConfigurationServiceImpl.java
@@ -34,9 +34,6 @@ import android.content.Context;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
-import android.tracing.perfetto.DataSourceParams;
-import android.tracing.perfetto.InitArguments;
-import android.tracing.perfetto.Producer;
import android.util.Log;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
@@ -110,39 +107,31 @@ public class ProtoLogConfigurationServiceImpl extends IProtoLogConfigurationServ
private final ViewerConfigFileTracer mViewerConfigFileTracer;
public ProtoLogConfigurationServiceImpl() {
- this(ProtoLogDataSource::new, ProtoLogConfigurationServiceImpl::dumpViewerConfig);
+ this(ProtoLog.getSharedSingleInstanceDataSource(),
+ ProtoLogConfigurationServiceImpl::dumpViewerConfig);
}
@VisibleForTesting
- public ProtoLogConfigurationServiceImpl(@NonNull ProtoLogDataSourceBuilder dataSourceBuilder) {
- this(dataSourceBuilder, ProtoLogConfigurationServiceImpl::dumpViewerConfig);
+ public ProtoLogConfigurationServiceImpl(@NonNull ProtoLogDataSource datasource) {
+ this(datasource, ProtoLogConfigurationServiceImpl::dumpViewerConfig);
}
@VisibleForTesting
public ProtoLogConfigurationServiceImpl(@NonNull ViewerConfigFileTracer tracer) {
- this(ProtoLogDataSource::new, tracer);
+ this(ProtoLog.getSharedSingleInstanceDataSource(), tracer);
}
@VisibleForTesting
public ProtoLogConfigurationServiceImpl(
- @NonNull ProtoLogDataSourceBuilder dataSourceBuilder,
+ @NonNull ProtoLogDataSource datasource,
@NonNull ViewerConfigFileTracer tracer) {
- mDataSource = dataSourceBuilder.build(
- this::onTracingInstanceStart,
- this::onTracingInstanceFlush,
- this::onTracingInstanceStop
- );
-
- // Initialize the Perfetto producer and register the Perfetto ProtoLog datasource to be
- // receive the lifecycle callbacks of the datasource and write the viewer configs if and
- // when required to the datasource.
- Producer.init(InitArguments.DEFAULTS);
- final var params = new DataSourceParams.Builder()
- .setBufferExhaustedPolicy(DataSourceParams.PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
- .build();
- mDataSource.register(params);
-
mViewerConfigFileTracer = tracer;
+
+ datasource.registerOnStartCallback(this::onTracingInstanceStart);
+ datasource.registerOnFlushCallback(this::onTracingInstanceFlush);
+ datasource.registerOnStopCallback(this::onTracingInstanceStop);
+
+ mDataSource = datasource;
}
public static class RegisterClientArgs extends IRegisterClientArgs.Stub {
diff --git a/core/java/com/android/internal/protolog/ProtoLogDataSource.java b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
index 0afb135ac6d9..ea452494b88d 100644
--- a/core/java/com/android/internal/protolog/ProtoLogDataSource.java
+++ b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
@@ -46,36 +46,30 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
ProtoLogDataSource.TlsState,
ProtoLogDataSource.IncrementalState> {
private static final String DATASOURCE_NAME = "android.protolog";
+ private final Map<Integer, ProtoLogConfig> mRunningInstances = new TreeMap<>();
+
@NonNull
- private final Instance.TracingInstanceStartCallback mOnStart;
+ private final Set<Instance.TracingInstanceStartCallback> mOnStartCallbacks = new HashSet<>();
@NonNull
- private final Runnable mOnFlush;
+ private final Set<Runnable> mOnFlushCallbacks = new HashSet<>();
@NonNull
- private final Instance.TracingInstanceStopCallback mOnStop;
+ private final Set<Instance.TracingInstanceStopCallback> mOnStopCallbacks = new HashSet<>();
- public ProtoLogDataSource(
- @NonNull Instance.TracingInstanceStartCallback onStart,
- @NonNull Runnable onFlush,
- @NonNull Instance.TracingInstanceStopCallback onStop) {
- this(onStart, onFlush, onStop, DATASOURCE_NAME);
+ public ProtoLogDataSource() {
+ this(DATASOURCE_NAME);
}
@VisibleForTesting
public ProtoLogDataSource(
- @NonNull Instance.TracingInstanceStartCallback onStart,
- @NonNull Runnable onFlush,
- @NonNull Instance.TracingInstanceStopCallback onStop,
@NonNull String dataSourceName) {
super(dataSourceName);
- this.mOnStart = onStart;
- this.mOnFlush = onFlush;
- this.mOnStop = onStop;
}
@Override
@@ -106,7 +100,8 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
}
return new Instance(
- this, instanceIndex, config, mOnStart, mOnFlush, mOnStop);
+ this, instanceIndex, config, this::executeOnStartCallbacks,
+ this::executeOnFlushCallbacks, this::executeOnStopCallbacks);
}
@Override
@@ -128,6 +123,84 @@ public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
return new IncrementalState();
}
+ /**
+ * Register an onStart callback that will be called when a tracing instance is started.
+ * The callback will be called immediately for all currently running tracing instances on
+ * registration.
+ * @param onStartCallback The callback to call on starting a tracing instance.
+ */
+ public synchronized void registerOnStartCallback(
+ Instance.TracingInstanceStartCallback onStartCallback) {
+ mOnStartCallbacks.add(onStartCallback);
+
+ for (var instanceIndex : mRunningInstances.keySet()) {
+ var config = mRunningInstances.get(instanceIndex);
+ onStartCallback.run(instanceIndex, config);
+ }
+ }
+
+ /**
+ * Register an onFlush callback that will be called when a tracing instance is about to flush.
+ * @param onFlushCallback The callback to call on flushing a tracing instance
+ */
+ public void registerOnFlushCallback(Runnable onFlushCallback) {
+ mOnFlushCallbacks.add(onFlushCallback);
+ }
+
+ /**
+ * Register an onStop callback that will be called when a tracing instance is being stopped.
+ * @param onStopCallback The callback to call on stopping a tracing instance.
+ */
+ public void registerOnStopCallback(Instance.TracingInstanceStopCallback onStopCallback) {
+ mOnStopCallbacks.add(onStopCallback);
+ }
+
+ /**
+ * Unregister an onStart callback.
+ * @param onStartCallback The callback object to unregister.
+ */
+ public void unregisterOnStartCallback(Instance.TracingInstanceStartCallback onStartCallback) {
+ mOnStartCallbacks.add(onStartCallback);
+ }
+
+ /**
+ * Unregister an onFlush callback.
+ * @param onFlushCallback The callback object to unregister.
+ */
+ public void unregisterOnFlushCallback(Runnable onFlushCallback) {
+ mOnFlushCallbacks.add(onFlushCallback);
+ }
+
+ /**
+ * Unregister an onStop callback.
+ * @param onStopCallback The callback object to unregister.
+ */
+ public void unregisterOnStopCallback(Instance.TracingInstanceStopCallback onStopCallback) {
+ mOnStopCallbacks.add(onStopCallback);
+ }
+
+ private synchronized void executeOnStartCallbacks(int instanceIdx, ProtoLogConfig config) {
+ mRunningInstances.put(instanceIdx, config);
+
+ for (var onStart : mOnStartCallbacks) {
+ onStart.run(instanceIdx, config);
+ }
+ }
+
+ private void executeOnFlushCallbacks() {
+ for (var onFlush : mOnFlushCallbacks) {
+ onFlush.run();
+ }
+ }
+
+ private synchronized void executeOnStopCallbacks(int instanceIdx, ProtoLogConfig config) {
+ mRunningInstances.remove(instanceIdx, config);
+
+ for (var onStop : mOnStopCallbacks) {
+ onStop.run(instanceIdx, config);
+ }
+ }
+
public static class TlsState {
@NonNull
private final ProtoLogConfig mConfig;
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 3378d08e7761..c2d4b21181b7 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -56,7 +56,7 @@ public class ProtoLogImpl {
private static TreeMap<String, IProtoLogGroup> sLogGroups;
@ProtoLogToolInjected(CACHE_UPDATER)
- private static Runnable sCacheUpdater;
+ private static ProtoLogCacheUpdater sCacheUpdater;
/** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
public static void d(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
@@ -93,7 +93,12 @@ public class ProtoLogImpl {
* and log level.
*/
public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
- return getSingleInstance().isEnabled(group, level);
+ return isEnabled(getSingleInstance(), group, level);
+ }
+
+ private static boolean isEnabled(
+ IProtoLog protoLogInstance, IProtoLogGroup group, LogLevel level) {
+ return protoLogInstance.isEnabled(group, level);
}
/**
@@ -106,36 +111,37 @@ public class ProtoLogImpl {
final var groups = sLogGroups.values().toArray(new IProtoLogGroup[0]);
if (android.tracing.Flags.perfettoProtologTracing()) {
- sServiceInstance = createProtoLogImpl(groups);
+ var viewerConfigFile = new File(sViewerConfigPath);
+ if (!viewerConfigFile.exists()) {
+ // TODO(b/353530422): Remove - temporary fix to unblock b/352290057
+ // In robolectric tests the viewer config file isn't current available, so we
+ // cannot use the ProcessedPerfettoProtoLogImpl.
+ Log.e(LOG_TAG, "Failed to find viewer config file " + sViewerConfigPath
+ + " when setting up " + ProtoLogImpl.class.getSimpleName() + ". "
+ + "ProtoLog will not work here!");
+
+ sServiceInstance = new NoViewerConfigProtoLogImpl();
+ } else {
+ var datasource = ProtoLog.getSharedSingleInstanceDataSource();
+ try {
+ var processedProtoLogImpl =
+ new ProcessedPerfettoProtoLogImpl(datasource, sViewerConfigPath,
+ sCacheUpdater, groups);
+ sServiceInstance = processedProtoLogImpl;
+ processedProtoLogImpl.enable();
+ } catch (ServiceManager.ServiceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
} else {
sServiceInstance = createLegacyProtoLogImpl(groups);
}
- sCacheUpdater.run();
+ sCacheUpdater.update(sServiceInstance);
}
return sServiceInstance;
}
- private static IProtoLog createProtoLogImpl(IProtoLogGroup[] groups) {
- try {
- File f = new File(sViewerConfigPath);
- if (!f.exists()) {
- // TODO(b/353530422): Remove - temporary fix to unblock b/352290057
- // In robolectric tests the viewer config file isn't current available, so we cannot
- // use the ProcessedPerfettoProtoLogImpl.
- Log.e(LOG_TAG, "Failed to find viewer config file " + sViewerConfigPath
- + " when setting up " + ProtoLogImpl.class.getSimpleName() + ". "
- + "ProtoLog will not work here!");
-
- return new NoViewerConfigProtoLogImpl();
- } else {
- return new ProcessedPerfettoProtoLogImpl(sViewerConfigPath, sCacheUpdater, groups);
- }
- } catch (ServiceManager.ServiceNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
-
private static LegacyProtoLogImpl createLegacyProtoLogImpl(IProtoLogGroup[] groups) {
var protologImpl = new LegacyProtoLogImpl(
sLegacyOutputFilePath, sLegacyViewerConfigPath, sCacheUpdater);
diff --git a/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java
index f3fe58070fa9..ebb07a04270d 100644
--- a/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/UnprocessedPerfettoProtoLogImpl.java
@@ -23,14 +23,10 @@ import com.android.internal.protolog.ProtoLogConfigurationServiceImpl.RegisterCl
import com.android.internal.protolog.common.IProtoLogGroup;
public class UnprocessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl {
- public UnprocessedPerfettoProtoLogImpl(@NonNull IProtoLogGroup[] groups)
+ public UnprocessedPerfettoProtoLogImpl(
+ @NonNull ProtoLogDataSource dataSource, @NonNull IProtoLogGroup[] groups)
throws ServiceManager.ServiceNotFoundException {
- this(() -> {}, groups);
- }
-
- public UnprocessedPerfettoProtoLogImpl(@NonNull Runnable cacheUpdater,
- @NonNull IProtoLogGroup[] groups) throws ServiceManager.ServiceNotFoundException {
- super(cacheUpdater, groups);
+ super(dataSource, (instance) -> {}, groups);
readyToLogToLogcat();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java
index 244bb3d6380b..b5d389540185 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CompanionOperation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
import java.util.List;
/** Interface for the companion operations */
@@ -25,5 +27,5 @@ public interface CompanionOperation {
* @param buffer data to read to create operation
* @param operations command is to be added
*/
- void read(WireBuffer buffer, List<Operation> operations);
+ void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 0761a244b9f2..370289a84502 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -19,6 +19,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.operations.ComponentValue;
+import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
import com.android.internal.widget.remotecompose.core.operations.IntegerExpression;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
@@ -53,15 +54,16 @@ public class CoreDocument {
private static final boolean DEBUG = false;
- ArrayList<Operation> mOperations;
+ @NonNull ArrayList<Operation> mOperations = new ArrayList<>();
@Nullable RootLayoutComponent mRootLayoutComponent = null;
- RemoteComposeState mRemoteComposeState = new RemoteComposeState();
+ @NonNull RemoteComposeState mRemoteComposeState = new RemoteComposeState();
@NonNull TimeVariables mTimeVariables = new TimeVariables();
// Semantic version of the document
@NonNull Version mVersion = new Version(0, 1, 0);
+ @Nullable
String mContentDescription; // text description of the document (used for accessibility)
long mRequiredCapabilities = 0L; // bitmask indicating needed capabilities of the player(unused)
@@ -74,19 +76,22 @@ public class CoreDocument {
int mContentAlignment = RootContentBehavior.ALIGNMENT_CENTER;
- RemoteComposeBuffer mBuffer = new RemoteComposeBuffer(mRemoteComposeState);
+ @NonNull RemoteComposeBuffer mBuffer = new RemoteComposeBuffer(mRemoteComposeState);
private final HashMap<Long, IntegerExpression> mIntegerExpressions = new HashMap<>();
+ private final HashMap<Integer, FloatExpression> mFloatExpressions = new HashMap<>();
+
private HashSet<Component> mAppliedTouchOperations = new HashSet<>();
private int mLastId = 1; // last component id when inflating the file
+ @Nullable
public String getContentDescription() {
return mContentDescription;
}
- public void setContentDescription(String contentDescription) {
+ public void setContentDescription(@Nullable String contentDescription) {
this.mContentDescription = contentDescription;
}
@@ -116,19 +121,21 @@ public class CoreDocument {
mRemoteComposeState.setWindowHeight(height);
}
+ @NonNull
public RemoteComposeBuffer getBuffer() {
return mBuffer;
}
- public void setBuffer(RemoteComposeBuffer buffer) {
+ public void setBuffer(@NonNull RemoteComposeBuffer buffer) {
this.mBuffer = buffer;
}
+ @NonNull
public RemoteComposeState getRemoteComposeState() {
return mRemoteComposeState;
}
- public void setRemoteComposeState(RemoteComposeState remoteComposeState) {
+ public void setRemoteComposeState(@NonNull RemoteComposeState remoteComposeState) {
this.mRemoteComposeState = remoteComposeState;
}
@@ -171,7 +178,7 @@ public class CoreDocument {
* @param h vertical dimension of the rendering area
* @param scaleOutput will contain the computed scale factor
*/
- public void computeScale(float w, float h, float[] scaleOutput) {
+ public void computeScale(float w, float h, @NonNull float[] scaleOutput) {
float contentScaleX = 1f;
float contentScaleY = 1f;
if (mContentSizing == RootContentBehavior.SIZING_SCALE) {
@@ -236,7 +243,11 @@ public class CoreDocument {
* @param translateOutput will contain the computed translation
*/
private void computeTranslate(
- float w, float h, float contentScaleX, float contentScaleY, float[] translateOutput) {
+ float w,
+ float h,
+ float contentScaleX,
+ float contentScaleY,
+ @NonNull float[] translateOutput) {
int horizontalContentAlignment = mContentAlignment & 0xF0;
int verticalContentAlignment = mContentAlignment & 0xF;
float translateX = 0f;
@@ -350,6 +361,22 @@ public class CoreDocument {
}
}
+ /**
+ * Execute an integer expression with the given id and put its value on the targetId
+ *
+ * @param expressionId the id of the integer expression
+ * @param targetId the id of the value to update with the expression
+ * @param context the current context
+ */
+ public void evaluateFloatExpression(
+ int expressionId, int targetId, @NonNull RemoteContext context) {
+ FloatExpression expression = mFloatExpressions.get(expressionId);
+ if (expression != null) {
+ float v = expression.evaluate(context);
+ context.overrideFloat(targetId, v);
+ }
+ }
+
// ============== Haptic support ==================
public interface HapticEngine {
void haptic(int type);
@@ -375,7 +402,7 @@ public class CoreDocument {
/** Callback interface for host actions */
public interface ActionCallback {
- void onAction(String name, Object value);
+ void onAction(@NonNull String name, Object value);
}
@NonNull HashSet<ActionCallback> mActionListeners = new HashSet<ActionCallback>();
@@ -386,7 +413,7 @@ public class CoreDocument {
* @param name the action name
* @param value a parameter to the action
*/
- public void runNamedAction(String name, Object value) {
+ public void runNamedAction(@NonNull String name, Object value) {
// TODO: we might add an interface to group all valid parameter types
for (ActionCallback callback : mActionListeners) {
callback.onAction(name, value);
@@ -398,7 +425,7 @@ public class CoreDocument {
*
* @param callback
*/
- public void addActionCallback(ActionCallback callback) {
+ public void addActionCallback(@NonNull ActionCallback callback) {
mActionListeners.add(callback);
}
@@ -408,7 +435,7 @@ public class CoreDocument {
}
public interface ClickCallbacks {
- void click(int id, String metadata);
+ void click(int id, @Nullable String metadata);
}
@NonNull HashSet<ClickCallbacks> mClickListeners = new HashSet<>();
@@ -429,21 +456,21 @@ public class CoreDocument {
public static class ClickAreaRepresentation {
int mId;
- String mContentDescription;
+ @Nullable final String mContentDescription;
float mLeft;
float mTop;
float mRight;
float mBottom;
- String mMetadata;
+ @Nullable final String mMetadata;
public ClickAreaRepresentation(
int id,
- String contentDescription,
+ @Nullable String contentDescription,
float left,
float top,
float right,
float bottom,
- String metadata) {
+ @Nullable String metadata) {
this.mId = id;
this.mContentDescription = contentDescription;
this.mLeft = left;
@@ -484,10 +511,11 @@ public class CoreDocument {
return mId;
}
- public String getContentDescription() {
+ public @Nullable String getContentDescription() {
return mContentDescription;
}
+ @Nullable
public String getMetadata() {
return mMetadata;
}
@@ -502,6 +530,10 @@ public class CoreDocument {
IntegerExpression expression = (IntegerExpression) op;
mIntegerExpressions.put((long) expression.mId, expression);
}
+ if (op instanceof FloatExpression) {
+ FloatExpression expression = (FloatExpression) op;
+ mFloatExpressions.put(expression.mId, expression);
+ }
}
mOperations = inflateComponents(mOperations);
mBuffer = buffer;
@@ -605,7 +637,8 @@ public class CoreDocument {
@NonNull private HashMap<Integer, Component> mComponentMap = new HashMap<Integer, Component>();
- private void registerVariables(RemoteContext context, @NonNull ArrayList<Operation> list) {
+ private void registerVariables(
+ @NonNull RemoteContext context, @NonNull ArrayList<Operation> list) {
for (Operation op : list) {
if (op instanceof VariableSupport) {
((VariableSupport) op).updateVariables(context);
@@ -701,12 +734,12 @@ public class CoreDocument {
*/
public void addClickArea(
int id,
- String contentDescription,
+ @Nullable String contentDescription,
float left,
float top,
float right,
float bottom,
- String metadata) {
+ @Nullable String metadata) {
mClickAreas.add(
new ClickAreaRepresentation(
id, contentDescription, left, top, right, bottom, metadata));
@@ -726,7 +759,7 @@ public class CoreDocument {
*
* @param callback called when a click area has been hit, passing the click are id and metadata.
*/
- public void addClickListener(ClickCallbacks callback) {
+ public void addClickListener(@NonNull ClickCallbacks callback) {
mClickListeners.add(callback);
}
@@ -744,7 +777,7 @@ public class CoreDocument {
* Passing a click event to the document. This will possibly result in calling the click
* listeners.
*/
- public void onClick(RemoteContext context, float x, float y) {
+ public void onClick(@NonNull RemoteContext context, float x, float y) {
for (ClickAreaRepresentation clickArea : mClickAreas) {
if (clickArea.contains(x, y)) {
warnClickListeners(clickArea);
@@ -802,6 +835,14 @@ public class CoreDocument {
for (TouchListener clickArea : mTouchListeners) {
clickArea.touchDrag(context, x, y);
}
+ if (mRootLayoutComponent != null) {
+ for (Component component : mAppliedTouchOperations) {
+ component.onTouchDrag(context, this, x, y, true);
+ }
+ if (!mAppliedTouchOperations.isEmpty()) {
+ return true;
+ }
+ }
if (!mTouchListeners.isEmpty()) {
return true;
}
@@ -940,6 +981,7 @@ public class CoreDocument {
*/
public void paint(@NonNull RemoteContext context, int theme) {
context.getPaintContext().clearNeedsRepaint();
+ context.loadFloat(RemoteContext.ID_DENSITY, context.getDensity());
context.mMode = RemoteContext.ContextMode.UNSET;
// current theme starts as UNSPECIFIED, until a Theme setter
// operation gets executed and modify it.
@@ -1097,6 +1139,7 @@ public class CoreDocument {
}
}
+ @NonNull
public List<Operation> getOperations() {
return mOperations;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
index f1885f942ee1..102003e2e371 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
@@ -15,22 +15,22 @@
*/
package com.android.internal.widget.remotecompose.core;
-import android.annotation.Nullable;
+import android.annotation.NonNull;
/** Base interface for RemoteCompose operations */
public interface Operation {
/** add the operation to the buffer */
- void write(WireBuffer buffer);
+ void write(@NonNull WireBuffer buffer);
/**
* paint an operation
*
* @param context the paint context used to paint the operation
*/
- void apply(RemoteContext context);
+ void apply(@NonNull RemoteContext context);
/** Debug utility to display an operation + indentation */
- @Nullable
- String deepToString(String indent);
+ @NonNull
+ String deepToString(@NonNull String indent);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index 53c45fac826c..687a99baff83 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -98,7 +98,9 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.OffsetModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueFloatChangeActionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueFloatExpressionChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueIntegerChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueIntegerExpressionChangeActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueStringChangeActionOperation;
@@ -214,6 +216,7 @@ public class Operations {
public static final int MODIFIER_OFFSET = 221;
public static final int MODIFIER_ZINDEX = 223;
public static final int MODIFIER_GRAPHICS_LAYER = 224;
+ public static final int MODIFIER_SCROLL = 226;
public static final int LOOP_START = 215;
public static final int LOOP_END = 216;
@@ -226,6 +229,7 @@ public class Operations {
public static final int VALUE_STRING_CHANGE_ACTION = 213;
public static final int VALUE_INTEGER_EXPRESSION_CHANGE_ACTION = 218;
public static final int VALUE_FLOAT_CHANGE_ACTION = 222;
+ public static final int VALUE_FLOAT_EXPRESSION_CHANGE_ACTION = 227;
public static final int ANIMATION_SPEC = 14;
@@ -235,7 +239,7 @@ public class Operations {
static class UniqueIntMap<T> extends IntMap<T> {
@Override
- public T put(int key, T value) {
+ public T put(int key, @NonNull T value) {
assert null == get(key) : "Opcode " + key + " already used in Operations !";
return super.put(key, value);
}
@@ -316,6 +320,7 @@ public class Operations {
map.put(MODIFIER_OFFSET, OffsetModifierOperation::read);
map.put(MODIFIER_ZINDEX, ZIndexModifierOperation::read);
map.put(MODIFIER_GRAPHICS_LAYER, GraphicsLayerModifierOperation::read);
+ map.put(MODIFIER_SCROLL, ScrollModifierOperation::read);
map.put(OPERATIONS_LIST_END, OperationsListEnd::read);
@@ -327,6 +332,9 @@ public class Operations {
ValueIntegerExpressionChangeActionOperation::read);
map.put(VALUE_STRING_CHANGE_ACTION, ValueStringChangeActionOperation::read);
map.put(VALUE_FLOAT_CHANGE_ACTION, ValueFloatChangeActionOperation::read);
+ map.put(
+ VALUE_FLOAT_EXPRESSION_CHANGE_ACTION,
+ ValueFloatExpressionChangeActionOperation::read);
map.put(LAYOUT_ROOT, RootLayoutComponent::read);
map.put(LAYOUT_CONTENT, LayoutComponentContent::read);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
index 1a71afe068bd..38b08e9b0ab3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
/** Specify an abstract paint context used by RemoteCompose commands to draw */
@@ -22,9 +24,10 @@ public abstract class PaintContext {
public static final int TEXT_MEASURE_MONOSPACE_WIDTH = 0x01;
public static final int TEXT_MEASURE_FONT_HEIGHT = 0x02;
- protected RemoteContext mContext;
+ protected @NonNull RemoteContext mContext;
private boolean mNeedsRepaint = false;
+ @NonNull
public RemoteContext getContext() {
return mContext;
}
@@ -37,11 +40,11 @@ public abstract class PaintContext {
mNeedsRepaint = false;
}
- public PaintContext(RemoteContext context) {
+ public PaintContext(@NonNull RemoteContext context) {
this.mContext = context;
}
- public void setContext(RemoteContext context) {
+ public void setContext(@NonNull RemoteContext context) {
this.mContext = context;
}
@@ -117,7 +120,8 @@ public abstract class PaintContext {
* descent of the font (not just of the measured text)
* @param bounds the bounds (left, top, right, bottom)
*/
- public abstract void getTextBounds(int textId, int start, int end, int flags, float[] bounds);
+ public abstract void getTextBounds(
+ int textId, int start, int end, int flags, @NonNull float[] bounds);
/**
* Draw a text starting ast x,y
@@ -158,7 +162,7 @@ public abstract class PaintContext {
*
* @param mPaintData the list of changes
*/
- public abstract void applyPaint(PaintBundle mPaintData);
+ public abstract void applyPaint(@NonNull PaintBundle mPaintData);
/**
* Scale the rendering by scaleX and saleY (1.0 = no scale). Scaling is done about
@@ -264,7 +268,7 @@ public abstract class PaintContext {
*
* @param content the content to log
*/
- public void log(String content) {
+ public void log(@NonNull String content) {
System.out.println("[LOG] " + content);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
index 049e47744ce8..9999182b53fc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
@@ -35,17 +35,17 @@ public abstract class PaintOperation implements Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
- public abstract void paint(PaintContext context);
+ public abstract void paint(@NonNull PaintContext context);
/**
* Will return true if the operation is similar enough to the current one, in the context of an
* animated transition.
*/
- public boolean suitableForTransition(Operation op) {
+ public boolean suitableForTransition(@NonNull Operation op) {
// by default expects the op to not be suitable
return false;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Platform.java b/core/java/com/android/internal/widget/remotecompose/core/Platform.java
index 7fbcfae54bcb..dcb8efebeecc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Platform.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Platform.java
@@ -15,19 +15,20 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
import android.annotation.Nullable;
/** Services that are needed to be provided by the platform during encoding. */
public interface Platform {
@Nullable
- byte[] imageToByteArray(Object image);
+ byte[] imageToByteArray(@NonNull Object image);
- int getImageWidth(Object image);
+ int getImageWidth(@NonNull Object image);
- int getImageHeight(Object image);
+ int getImageHeight(@NonNull Object image);
@Nullable
- float[] pathToFloatArray(Object path);
+ float[] pathToFloatArray(@NonNull Object path);
enum LogCategory {
DEBUG,
@@ -42,22 +43,22 @@ public interface Platform {
Platform None =
new Platform() {
@Override
- public byte[] imageToByteArray(Object image) {
+ public byte[] imageToByteArray(@NonNull Object image) {
throw new UnsupportedOperationException();
}
@Override
- public int getImageWidth(Object image) {
+ public int getImageWidth(@NonNull Object image) {
throw new UnsupportedOperationException();
}
@Override
- public int getImageHeight(Object image) {
+ public int getImageHeight(@NonNull Object image) {
throw new UnsupportedOperationException();
}
@Override
- public float[] pathToFloatArray(Object path) {
+ public float[] pathToFloatArray(@NonNull Object path) {
throw new UnsupportedOperationException();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 7d9439dd186b..c05079e34505 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core;
+import static com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression.ADD;
+import static com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression.MUL;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -89,6 +92,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.OffsetModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ZIndexModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle;
import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
@@ -117,9 +121,9 @@ public class RemoteComposeBuffer {
public static final int EASING_SPLINE_CUSTOM = FloatAnimation.SPLINE_CUSTOM;
public static final int EASING_EASE_OUT_BOUNCE = FloatAnimation.EASE_OUT_BOUNCE;
public static final int EASING_EASE_OUT_ELASTIC = FloatAnimation.EASE_OUT_ELASTIC;
- WireBuffer mBuffer = new WireBuffer();
- @Nullable Platform mPlatform = null;
- RemoteComposeState mRemoteComposeState;
+ private @NonNull WireBuffer mBuffer = new WireBuffer();
+ @Nullable private Platform mPlatform = null;
+ @NonNull private final RemoteComposeState mRemoteComposeState;
private static final boolean DEBUG = false;
private int mLastComponentId = 0;
@@ -130,7 +134,7 @@ public class RemoteComposeBuffer {
*
* @param remoteComposeState the state used while encoding on the buffer
*/
- public RemoteComposeBuffer(RemoteComposeState remoteComposeState) {
+ public RemoteComposeBuffer(@NonNull RemoteComposeState remoteComposeState) {
this.mRemoteComposeState = remoteComposeState;
}
@@ -155,15 +159,15 @@ public class RemoteComposeBuffer {
return mPlatform;
}
- public void setPlatform(Platform platform) {
+ public void setPlatform(@NonNull Platform platform) {
this.mPlatform = platform;
}
- public WireBuffer getBuffer() {
+ public @NonNull WireBuffer getBuffer() {
return mBuffer;
}
- public void setBuffer(WireBuffer buffer) {
+ public void setBuffer(@NonNull WireBuffer buffer) {
this.mBuffer = buffer;
}
@@ -200,7 +204,7 @@ public class RemoteComposeBuffer {
* @param height the height of the document in pixels
* @param contentDescription content description of the document
*/
- public void header(int width, int height, String contentDescription) {
+ public void header(int width, int height, @Nullable String contentDescription) {
header(width, height, contentDescription, 1f, 0);
}
@@ -220,7 +224,7 @@ public class RemoteComposeBuffer {
* @param dstBottom bottom coordinate of the destination area
*/
public void drawBitmap(
- Object image,
+ @NonNull Object image,
int imageWidth,
int imageHeight,
int srcLeft,
@@ -235,8 +239,9 @@ public class RemoteComposeBuffer {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
- byte[] data = mPlatform.imageToByteArray(image);
- BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data);
+ byte[] data = mPlatform.imageToByteArray(image); // todo: potential npe
+ BitmapData.apply(
+ mBuffer, imageId, imageWidth, imageHeight, data); // todo: potential npe
}
int contentDescriptionId = 0;
if (contentDescription != null) {
@@ -387,7 +392,7 @@ public class RemoteComposeBuffer {
* @param contentDescription content description of the image
*/
public void addDrawBitmap(
- Object image,
+ @NonNull Object image,
float left,
float top,
float right,
@@ -396,11 +401,12 @@ public class RemoteComposeBuffer {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
- byte[] data = mPlatform.imageToByteArray(image);
+ byte[] data = mPlatform.imageToByteArray(image); // todo: potential npe
int imageWidth = mPlatform.getImageWidth(image);
int imageHeight = mPlatform.getImageHeight(image);
- BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data);
+ BitmapData.apply(
+ mBuffer, imageId, imageWidth, imageHeight, data); // todo: potential npe
}
int contentDescriptionId = 0;
if (contentDescription != null) {
@@ -446,7 +452,7 @@ public class RemoteComposeBuffer {
* @param contentDescription associate a string with image for accessibility
*/
public void drawScaledBitmap(
- Object image,
+ @NonNull Object image,
float srcLeft,
float srcTop,
float srcRight,
@@ -461,11 +467,11 @@ public class RemoteComposeBuffer {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
- byte[] data = mPlatform.imageToByteArray(image);
+ byte[] data = mPlatform.imageToByteArray(image); // todo: potential npe
int imageWidth = mPlatform.getImageWidth(image);
int imageHeight = mPlatform.getImageHeight(image);
- BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data);
+ BitmapData.apply(mBuffer, imageId, imageWidth, imageHeight, data); // todo: potential pe
}
int contentDescriptionId = 0;
if (contentDescription != null) {
@@ -493,11 +499,11 @@ public class RemoteComposeBuffer {
* @param image drawScaledBitmap
* @return id of the image useful with
*/
- public int addBitmap(Object image) {
+ public int addBitmap(@NonNull Object image) {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
- byte[] data = mPlatform.imageToByteArray(image);
+ byte[] data = mPlatform.imageToByteArray(image); // tODO: potential npe
int imageWidth = mPlatform.getImageWidth(image);
int imageHeight = mPlatform.getImageHeight(image);
@@ -512,11 +518,11 @@ public class RemoteComposeBuffer {
* @param image drawScaledBitmap
* @return id of the image useful with
*/
- public int addBitmap(Object image, @NonNull String name) {
+ public int addBitmap(@NonNull Object image, @NonNull String name) {
int imageId = mRemoteComposeState.dataGetId(image);
if (imageId == -1) {
imageId = mRemoteComposeState.cacheData(image);
- byte[] data = mPlatform.imageToByteArray(image);
+ byte[] data = mPlatform.imageToByteArray(image); // todo: potential npe
int imageWidth = mPlatform.getImageWidth(image);
int imageHeight = mPlatform.getImageHeight(image);
@@ -629,7 +635,7 @@ public class RemoteComposeBuffer {
*
* @param path The path to be drawn
*/
- public void addDrawPath(Object path) {
+ public void addDrawPath(@NonNull Object path) {
int id = mRemoteComposeState.dataGetId(path);
if (id == -1) { // never been seen before
id = addPathData(path);
@@ -681,7 +687,8 @@ public class RemoteComposeBuffer {
* @param hOffset The distance along the path to add to the text's starting position
* @param vOffset The distance above(-) or below(+) the path to position the text
*/
- public void addDrawTextOnPath(@NonNull String text, Object path, float hOffset, float vOffset) {
+ public void addDrawTextOnPath(
+ @NonNull String text, @NonNull Object path, float hOffset, float vOffset) {
int pathId = mRemoteComposeState.dataGetId(path);
if (pathId == -1) { // never been seen before
pathId = addPathData(path);
@@ -752,7 +759,7 @@ public class RemoteComposeBuffer {
* <li>Panning of 1.0, 0.0 - the test is centered & to the right of x,y
* </ul>
*
- * Setting panY to NaN results in y being the baseline of the text.
+ * <p>Setting panY to NaN results in y being the baseline of the text.
*
* @param text text to draw
* @param x Coordinate of the Anchor
@@ -836,7 +843,7 @@ public class RemoteComposeBuffer {
* <li>Panning of 1.0, 0.0 - the test is centered & to the right of x,y
* </ul>
*
- * Setting panY to NaN results in y being the baseline of the text.
+ * <p>Setting panY to NaN results in y being the baseline of the text.
*
* @param textId text to draw
* @param x Coordinate of the Anchor
@@ -861,7 +868,8 @@ public class RemoteComposeBuffer {
* @param start The start of the subrange of paths to draw 0 = start form start 0.5 is half way
* @param stop The end of the subrange of paths to draw 1 = end at the end 0.5 is end half way
*/
- public void addDrawTweenPath(Object path1, Object path2, float tween, float start, float stop) {
+ public void addDrawTweenPath(
+ @NonNull Object path1, @NonNull Object path2, float tween, float start, float stop) {
int path1Id = mRemoteComposeState.dataGetId(path1);
if (path1Id == -1) { // never been seen before
path1Id = addPathData(path1);
@@ -892,7 +900,7 @@ public class RemoteComposeBuffer {
* @param path
* @return the id of the path on the wire
*/
- public int addPathData(Object path) {
+ public int addPathData(@NonNull Object path) {
float[] pathData = mPlatform.pathToFloatArray(path);
int id = mRemoteComposeState.cacheData(path);
PathData.apply(mBuffer, id, pathData);
@@ -910,7 +918,7 @@ public class RemoteComposeBuffer {
///////////////////////////////////////////////////////////////////////////////////////////////
- public void inflateFromBuffer(ArrayList<Operation> operations) {
+ public void inflateFromBuffer(@NonNull ArrayList<Operation> operations) {
mBuffer.setIndex(0);
while (mBuffer.available()) {
int opId = mBuffer.readByte();
@@ -926,7 +934,7 @@ public class RemoteComposeBuffer {
}
public static void readNextOperation(
- @NonNull WireBuffer buffer, ArrayList<Operation> operations) {
+ @NonNull WireBuffer buffer, @NonNull ArrayList<Operation> operations) {
int opId = buffer.readByte();
if (DEBUG) {
Utils.log(">> " + opId);
@@ -957,15 +965,16 @@ public class RemoteComposeBuffer {
@NonNull
public static RemoteComposeBuffer fromFile(
- @NonNull String path, RemoteComposeState remoteComposeState) throws IOException {
+ @NonNull String path, @NonNull RemoteComposeState remoteComposeState)
+ throws IOException {
RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState);
read(new File(path), buffer);
return buffer;
}
@NonNull
- public RemoteComposeBuffer fromFile(@NonNull File file, RemoteComposeState remoteComposeState)
- throws IOException {
+ public RemoteComposeBuffer fromFile(
+ @NonNull File file, @NonNull RemoteComposeState remoteComposeState) throws IOException {
RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState);
read(file, buffer);
return buffer;
@@ -973,7 +982,7 @@ public class RemoteComposeBuffer {
@NonNull
public static RemoteComposeBuffer fromInputStream(
- @NonNull InputStream inputStream, RemoteComposeState remoteComposeState) {
+ @NonNull InputStream inputStream, @NonNull RemoteComposeState remoteComposeState) {
RemoteComposeBuffer buffer = new RemoteComposeBuffer(remoteComposeState);
read(inputStream, buffer);
return buffer;
@@ -1205,6 +1214,7 @@ public class RemoteComposeBuffer {
/**
* Add a touch handle system
*
+ * @param id the float NaN id used for the returned position
* @param value the default value
* @param min the minimum value
* @param max the maximum value
@@ -1213,9 +1223,9 @@ public class RemoteComposeBuffer {
* @param touchMode the touch up handling behaviour
* @param touchSpec the touch up handling parameters
* @param easingSpec the easing parameter TODO support in v2
- * @return id of the variable to be used controlled by touch handling
*/
- public float addTouchExpression(
+ public void addTouchExpression(
+ float id,
float value,
float min,
float max,
@@ -1225,9 +1235,45 @@ public class RemoteComposeBuffer {
int touchMode,
float[] touchSpec,
float[] easingSpec) {
- int id = mRemoteComposeState.nextId();
TouchExpression.apply(
mBuffer,
+ Utils.idFromNan(id),
+ value,
+ min,
+ max,
+ velocityId,
+ touchEffects,
+ exp,
+ touchMode,
+ touchSpec,
+ easingSpec);
+ }
+
+ /**
+ * Add a touch handle system
+ *
+ * @param value the default value
+ * @param min the minimum value
+ * @param max the maximum value
+ * @param velocityId the id for the velocity TODO support in v2
+ * @param exp The Float Expression
+ * @param touchMode the touch up handling behaviour
+ * @param touchSpec the touch up handling parameters
+ * @param easingSpec the easing parameter TODO support in v2
+ * @return id of the variable to be used controlled by touch handling
+ */
+ public float addTouchExpression(
+ float value,
+ float min,
+ float max,
+ float velocityId,
+ int touchEffects,
+ float[] exp,
+ int touchMode,
+ float[] touchSpec,
+ float[] easingSpec) {
+ float id = Utils.asNan(mRemoteComposeState.nextId());
+ addTouchExpression(
id,
value,
min,
@@ -1238,7 +1284,7 @@ public class RemoteComposeBuffer {
touchMode,
touchSpec,
easingSpec);
- return Utils.asNan(id);
+ return id;
}
/**
@@ -1248,7 +1294,7 @@ public class RemoteComposeBuffer {
* @param animation Array of floats that represents animation
* @return NaN id of the result of the calculation
*/
- public float addAnimatedFloat(@NonNull float[] value, float[] animation) {
+ public float addAnimatedFloat(@NonNull float[] value, @Nullable float[] animation) {
int id = mRemoteComposeState.cacheData(value);
FloatExpression.apply(mBuffer, id, value, animation);
return Utils.asNan(id);
@@ -1345,7 +1391,7 @@ public class RemoteComposeBuffer {
* @param listId
* @return the id of the map, encoded as a float NaN
*/
- public int addMap(@NonNull String[] keys, byte[] types, int[] listId) {
+ public int addMap(@NonNull String[] keys, @Nullable byte[] types, @NonNull int[] listId) {
int id = mRemoteComposeState.cacheData(listId, NanMap.TYPE_ARRAY);
DataMapIds.apply(mBuffer, id, keys, types, listId);
return id;
@@ -1354,14 +1400,18 @@ public class RemoteComposeBuffer {
/**
* This provides access to text in RemoteList
*
+ * <p>TODO: do we want both a float and an int index version of this method? bbade@ TODO
+ * for @hoford - add a unit test for this method
+ *
* @param dataSet
* @param index index as a float variable
* @return
*/
public int textLookup(float dataSet, float index) {
long hash =
- ((long) Float.floatToRawIntBits(dataSet))
- << (32 + Float.floatToRawIntBits(index)); // TODO: is this the correct ()s?
+ (((long) Float.floatToRawIntBits(dataSet)) << 32)
+ + Float.floatToRawIntBits(
+ index); // TODO: is this the correct ()s? -- bbade@
int id = mRemoteComposeState.cacheData(hash);
TextLookup.apply(mBuffer, id, Utils.idFromNan(dataSet), index);
return id;
@@ -1370,14 +1420,16 @@ public class RemoteComposeBuffer {
/**
* This provides access to text in RemoteList
*
+ * <p>TODO for hoford - add a unit test for this method
+ *
* @param dataSet
* @param index index as an int variable
* @return
*/
public int textLookup(float dataSet, int index) {
long hash =
- ((long) Float.floatToRawIntBits(dataSet))
- << (32 + Float.floatToRawIntBits(index)); // TODO: is this the correct ()s?
+ (((long) Float.floatToRawIntBits(dataSet)) << 32)
+ + Float.floatToRawIntBits(index); // TODO: is this the correct ()s?
int id = mRemoteComposeState.cacheData(hash);
TextLookupInt.apply(mBuffer, id, Utils.idFromNan(dataSet), index);
return id;
@@ -1521,8 +1573,8 @@ public class RemoteComposeBuffer {
* @param wrap the wraps value so (e.g 360 so angles 355 would animate to 5)
* @return
*/
- public static float[] packAnimation(
- float duration, int type, float[] spec, float initialValue, float wrap) {
+ public static @NonNull float[] packAnimation(
+ float duration, int type, @Nullable float[] spec, float initialValue, float wrap) {
return FloatAnimation.packToFloatArray(duration, type, spec, initialValue, wrap);
}
@@ -1591,6 +1643,43 @@ public class RemoteComposeBuffer {
}
/**
+ * Add a scroll modifier
+ *
+ * @param direction HORIZONTAL(0) or VERTICAL(1)
+ * @param positionId the position id as a NaN
+ * @param notches
+ */
+ public void addModifierScroll(int direction, float positionId, int notches) {
+ // TODO: add support for non-notch behaviors etc.
+ float max = this.addFloat(0f);
+ float notchMax = this.addFloat(0f);
+ float touchExpressionDirection =
+ direction != 0 ? RemoteContext.FLOAT_TOUCH_POS_X : RemoteContext.FLOAT_TOUCH_POS_Y;
+ this.addTouchExpression(
+ positionId,
+ 0f,
+ 0f,
+ max,
+ 0f,
+ 3,
+ new float[] {
+ touchExpressionDirection,
+ -1,
+ // TODO: remove this CONTINUOUS_SEC hack...
+ MUL,
+ RemoteContext.FLOAT_CONTINUOUS_SEC,
+ 0f,
+ MUL,
+ ADD
+ },
+ TouchExpression.STOP_NOTCHES_EVEN,
+ new float[] {notches, notchMax},
+ null);
+
+ ScrollModifierOperation.apply(mBuffer, direction, positionId, max, notchMax);
+ }
+
+ /**
* Add a background modifier of provided color
*
* @param color the color of the background
@@ -1869,4 +1958,8 @@ public class RemoteComposeBuffer {
public int createID(int type) {
return mRemoteComposeState.nextId(type);
}
+
+ public int nextId() {
+ return mRemoteComposeState.nextId();
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index 303932814909..a903e6ee1f27 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -49,7 +49,7 @@ public class RemoteComposeState implements CollectionsAccess {
private final IntMap<Object> mObjectMap = new IntMap<>();
private final boolean[] mColorOverride = new boolean[MAX_COLORS];
- private final IntMap<ArrayAccess> mCollectionMap = new IntMap<>();
+ @NonNull private final IntMap<ArrayAccess> mCollectionMap = new IntMap<>();
private final boolean[] mDataOverride = new boolean[MAX_DATA];
private final boolean[] mIntegerOverride = new boolean[MAX_DATA];
@@ -82,7 +82,7 @@ public class RemoteComposeState implements CollectionsAccess {
}
/** Return the id of an item from the cache. */
- public int dataGetId(Object data) {
+ public int dataGetId(@NonNull Object data) {
Integer res = mDataIntMap.get(data);
if (res == null) {
return -1;
@@ -94,7 +94,7 @@ public class RemoteComposeState implements CollectionsAccess {
* Add an item to the cache. Generates an id for the item and adds it to the cache based on that
* id.
*/
- public int cacheData(Object item) {
+ public int cacheData(@NonNull Object item) {
int id = nextId();
mDataIntMap.put(item, id);
mIntDataMap.put(id, item);
@@ -105,7 +105,7 @@ public class RemoteComposeState implements CollectionsAccess {
* Add an item to the cache. Generates an id for the item and adds it to the cache based on that
* id.
*/
- public int cacheData(Object item, int type) {
+ public int cacheData(@NonNull Object item, int type) {
int id = nextId(type);
mDataIntMap.put(item, id);
mIntDataMap.put(id, item);
@@ -113,13 +113,13 @@ public class RemoteComposeState implements CollectionsAccess {
}
/** Insert an item in the cache */
- public void cacheData(int id, Object item) {
+ public void cacheData(int id, @NonNull Object item) {
mDataIntMap.put(item, id);
mIntDataMap.put(id, item);
}
/** Insert an item in the cache */
- public void updateData(int id, Object item) {
+ public void updateData(int id, @NonNull Object item) {
if (!mDataOverride[id]) {
Object previous = mIntDataMap.get(id);
if (previous != item) {
@@ -137,7 +137,7 @@ public class RemoteComposeState implements CollectionsAccess {
* @param id
* @param item the new value
*/
- public void overrideData(int id, Object item) {
+ public void overrideData(int id, @NonNull Object item) {
Object previous = mIntDataMap.get(id);
if (previous != item) {
mDataIntMap.remove(previous);
@@ -379,7 +379,7 @@ public class RemoteComposeState implements CollectionsAccess {
@NonNull IntMap<ArrayList<VariableSupport>> mVarListeners = new IntMap<>();
@NonNull ArrayList<VariableSupport> mAllVarListeners = new ArrayList<>();
- private void add(int id, VariableSupport variableSupport) {
+ private void add(int id, @NonNull VariableSupport variableSupport) {
ArrayList<VariableSupport> v = mVarListeners.get(id);
if (v == null) {
v = new ArrayList<VariableSupport>();
@@ -395,17 +395,27 @@ public class RemoteComposeState implements CollectionsAccess {
* @param id
* @param variableSupport
*/
- public void listenToVar(int id, VariableSupport variableSupport) {
+ public void listenToVar(int id, @NonNull VariableSupport variableSupport) {
add(id, variableSupport);
}
/**
+ * Is any command listening to this variable
+ *
+ * @param id
+ * @return
+ */
+ public boolean hasListener(int id) {
+ return mVarListeners.get(id) != null;
+ }
+
+ /**
* List of Commands that need to be updated
*
* @param context
* @return
*/
- public int getOpsToUpdate(RemoteContext context) {
+ public int getOpsToUpdate(@NonNull RemoteContext context) {
for (VariableSupport vs : mAllVarListeners) {
vs.updateVariables(context);
}
@@ -439,18 +449,18 @@ public class RemoteComposeState implements CollectionsAccess {
updateFloat(RemoteContext.ID_WINDOW_HEIGHT, height);
}
- public void addCollection(int id, ArrayAccess collection) {
+ public void addCollection(int id, @NonNull ArrayAccess collection) {
mCollectionMap.put(id & 0xFFFFF, collection);
}
@Override
public float getFloatValue(int id, int index) {
- return mCollectionMap.get(id & 0xFFFFF).getFloatValue(index);
+ return mCollectionMap.get(id & 0xFFFFF).getFloatValue(index); // TODO: potential npe
}
@Override
- public float[] getFloats(int id) {
- return mCollectionMap.get(id & 0xFFFFF).getFloats();
+ public @Nullable float[] getFloats(int id) {
+ return mCollectionMap.get(id & 0xFFFFF).getFloats(); // TODO: potential npe
}
@Override
@@ -458,11 +468,11 @@ public class RemoteComposeState implements CollectionsAccess {
return mCollectionMap.get(id & 0xFFFFF).getId(index);
}
- public void putDataMap(int id, DataMap map) {
+ public void putDataMap(int id, @NonNull DataMap map) {
mDataMapMap.put(id, map);
}
- public DataMap getDataMap(int id) {
+ public @Nullable DataMap getDataMap(int id) {
return mDataMapMap.get(id);
}
@@ -471,15 +481,15 @@ public class RemoteComposeState implements CollectionsAccess {
return mCollectionMap.get(id & 0xFFFFF).getLength();
}
- public void setContext(RemoteContext context) {
+ public void setContext(@NonNull RemoteContext context) {
mRemoteContext = context;
}
- public void updateObject(int id, Object value) {
+ public void updateObject(int id, @NonNull Object value) {
mObjectMap.put(id, value);
}
- public Object getObject(int id) {
+ public @Nullable Object getObject(int id) {
return mObjectMap.get(id);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 23cc5b89d916..26305bf124f7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -15,6 +15,7 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
@@ -39,13 +40,15 @@ import java.time.ZoneOffset;
* <p>We also contain a PaintContext, so that any operation can draw as needed.
*/
public abstract class RemoteContext {
- protected CoreDocument mDocument;
- public RemoteComposeState mRemoteComposeState;
+ protected @NonNull CoreDocument mDocument =
+ new CoreDocument(); // todo: is this a valid way to initialize? bbade@
+ public @NonNull RemoteComposeState mRemoteComposeState =
+ new RemoteComposeState(); // todo, is this a valid use of RemoteComposeState -- bbade@
long mStart = System.nanoTime(); // todo This should be set at a hi level
@Nullable protected PaintContext mPaintContext = null;
protected float mDensity = 2.75f;
- ContextMode mMode = ContextMode.UNSET;
+ @NonNull ContextMode mMode = ContextMode.UNSET;
int mDebug = 0;
@@ -57,7 +60,7 @@ public abstract class RemoteContext {
private boolean mAnimate = true;
- public Component lastComponent;
+ public @Nullable Component mLastComponent;
public long currentTime = 0L;
public float getDensity() {
@@ -65,7 +68,9 @@ public abstract class RemoteContext {
}
public void setDensity(float density) {
- mDensity = density;
+ if (density > 0) {
+ mDensity = density;
+ }
}
public boolean isAnimationEnabled() {
@@ -81,7 +86,7 @@ public abstract class RemoteContext {
*
* @return the CollectionsAccess implementation
*/
- public CollectionsAccess getCollectionsAccess() {
+ public @Nullable CollectionsAccess getCollectionsAccess() {
return mRemoteComposeState;
}
@@ -91,7 +96,7 @@ public abstract class RemoteContext {
* @param instanceId
* @param floatPath
*/
- public abstract void loadPathData(int instanceId, float[] floatPath);
+ public abstract void loadPathData(int instanceId, @NonNull float[] floatPath);
/**
* Associate a name with a give id.
@@ -100,7 +105,7 @@ public abstract class RemoteContext {
* @param varId the id (color,integer,float etc.)
* @param varType thetype
*/
- public abstract void loadVariableName(String varName, int varId, int varType);
+ public abstract void loadVariableName(@NonNull String varName, int varId, int varType);
/**
* Save a color under a given id
@@ -135,7 +140,7 @@ public abstract class RemoteContext {
* @param colorName the name of the color to override
* @param color Override the default color
*/
- public abstract void setNamedColorOverride(String colorName, int color);
+ public abstract void setNamedColorOverride(@NonNull String colorName, int color);
/**
* Set the value of a named String. This overrides the string in the document
@@ -143,7 +148,7 @@ public abstract class RemoteContext {
* @param stringName the name of the string to override
* @param value Override the default string
*/
- public abstract void setNamedStringOverride(String stringName, String value);
+ public abstract void setNamedStringOverride(@NonNull String stringName, @NonNull String value);
/**
* Allows to clear a named String.
@@ -152,7 +157,7 @@ public abstract class RemoteContext {
*
* @param stringName the name of the string to override
*/
- public abstract void clearNamedStringOverride(String stringName);
+ public abstract void clearNamedStringOverride(@NonNull String stringName);
/**
* Set the value of a named Integer. This overrides the integer in the document
@@ -160,7 +165,7 @@ public abstract class RemoteContext {
* @param integerName the name of the integer to override
* @param value Override the default integer
*/
- public abstract void setNamedIntegerOverride(String integerName, int value);
+ public abstract void setNamedIntegerOverride(@NonNull String integerName, int value);
/**
* Allows to clear a named Integer.
@@ -169,7 +174,7 @@ public abstract class RemoteContext {
*
* @param integerName the name of the integer to override
*/
- public abstract void clearNamedIntegerOverride(String integerName);
+ public abstract void clearNamedIntegerOverride(@NonNull String integerName);
/**
* Support Collections by registering this collection
@@ -177,20 +182,20 @@ public abstract class RemoteContext {
* @param id id of the collection
* @param collection the collection under this id
*/
- public abstract void addCollection(int id, ArrayAccess collection);
+ public abstract void addCollection(int id, @NonNull ArrayAccess collection);
- public abstract void putDataMap(int id, DataMap map);
+ public abstract void putDataMap(int id, @NonNull DataMap map);
- public abstract DataMap getDataMap(int id);
+ public abstract @Nullable DataMap getDataMap(int id);
- public abstract void runAction(int id, String metadata);
+ public abstract void runAction(int id, @NonNull String metadata);
// TODO: we might add an interface to group all valid parameter types
public abstract void runNamedAction(int textId, Object value);
- public abstract void putObject(int mId, Object command);
+ public abstract void putObject(int mId, @NonNull Object command);
- public abstract Object getObject(int mId);
+ public abstract @Nullable Object getObject(int mId);
public void addTouchListener(TouchListener touchExpression) {}
@@ -220,11 +225,11 @@ public abstract class RemoteContext {
this.mTheme = theme;
}
- public ContextMode getMode() {
+ public @NonNull ContextMode getMode() {
return mMode;
}
- public void setMode(ContextMode mode) {
+ public void setMode(@NonNull ContextMode mode) {
this.mMode = mode;
}
@@ -233,11 +238,11 @@ public abstract class RemoteContext {
return mPaintContext;
}
- public void setPaintContext(PaintContext paintContext) {
+ public void setPaintContext(@NonNull PaintContext paintContext) {
this.mPaintContext = paintContext;
}
- public CoreDocument getDocument() {
+ public @Nullable CoreDocument getDocument() {
return mDocument;
}
@@ -253,7 +258,7 @@ public abstract class RemoteContext {
this.mDebug = debug;
}
- public void setDocument(CoreDocument document) {
+ public void setDocument(@NonNull CoreDocument document) {
this.mDocument = document;
}
@@ -310,11 +315,14 @@ public abstract class RemoteContext {
* Save a bitmap under an imageId
*
* @param imageId the id of the image
+ * @param encoding how the data is encoded 0 = png, 1 = raw, 2 = url
+ * @param type the type of the data 0 = RGBA 8888, 1 = 888, 2 = 8 gray
* @param width the width of the image
* @param height the height of the image
* @param bitmap the bytes that represent the image
*/
- public abstract void loadBitmap(int imageId, int width, int height, byte[] bitmap);
+ public abstract void loadBitmap(
+ int imageId, short encoding, short type, int width, int height, @NonNull byte[] bitmap);
/**
* Save a string under a given id
@@ -322,7 +330,7 @@ public abstract class RemoteContext {
* @param id the id of the string
* @param text the value to set
*/
- public abstract void loadText(int id, String text);
+ public abstract void loadText(int id, @NonNull String text);
/**
* Get a string given an id
@@ -330,7 +338,7 @@ public abstract class RemoteContext {
* @param id the id of the string
* @return
*/
- public abstract String getText(int id);
+ public abstract @Nullable String getText(int id);
/**
* Load a float
@@ -373,12 +381,12 @@ public abstract class RemoteContext {
public abstract void overrideText(int id, int valueId);
/**
- * Load an animated float associated with an id Todo: Remove?
+ * Load an animated float associated with an id Todo: Remove? cc @hoford
*
* @param id the id of the float
* @param animatedFloat The animated float
*/
- public abstract void loadAnimatedFloat(int id, FloatExpression animatedFloat);
+ public abstract void loadAnimatedFloat(int id, @NonNull FloatExpression animatedFloat);
/**
* Save a shader under and ID
@@ -386,7 +394,7 @@ public abstract class RemoteContext {
* @param id the id of the Shader
* @param value the shader
*/
- public abstract void loadShader(int id, ShaderData value);
+ public abstract void loadShader(int id, @NonNull ShaderData value);
/**
* Get a float given an id
@@ -418,7 +426,7 @@ public abstract class RemoteContext {
* @param id track when this id changes value
* @param variableSupport call back when value changes
*/
- public abstract void listensTo(int id, VariableSupport variableSupport);
+ public abstract void listensTo(int id, @NonNull VariableSupport variableSupport);
/**
* Notify commands with variables have changed
@@ -433,6 +441,7 @@ public abstract class RemoteContext {
* @param id get a shader given the id
* @return The shader
*/
+ @Nullable
public abstract ShaderData getShader(int id);
public static final int ID_CONTINUOUS_SEC = 1;
@@ -467,6 +476,10 @@ public abstract class RemoteContext {
public static final int ID_LIGHT = 26;
+ public static final int ID_DENSITY = 27;
+
+ public static final float FLOAT_DENSITY = Utils.asNan(ID_DENSITY);
+
/** CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 */
public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java b/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java
index 8f9741dd4195..79ac789a454e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java
@@ -15,8 +15,10 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
public interface SerializableToString {
- void serializeToString(int indent, StringSerializer serializer);
+ void serializeToString(int indent, @NonNull StringSerializer serializer);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java b/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java
index 51e58a1aeddd..e9fa8976637e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/VariableSupport.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import android.annotation.NonNull;
+
/**
* Interface for operators that interact with variables Through this they register to listen to
* particular variables and are notified when they change
@@ -26,12 +28,12 @@ public interface VariableSupport {
*
* @param context
*/
- void registerListening(RemoteContext context);
+ void registerListening(@NonNull RemoteContext context);
/**
* Called to be notified that the variables you are interested have changed.
*
* @param context
*/
- void updateVariables(RemoteContext context);
+ void updateVariables(@NonNull RemoteContext context);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
index 738e42baae0b..a64b706fea3b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/WireBuffer.java
@@ -23,7 +23,7 @@ import java.util.Arrays;
public class WireBuffer {
private static final int BUFFER_SIZE = 1024 * 1024 * 1;
int mMaxSize;
- byte[] mBuffer;
+ @NonNull byte[] mBuffer;
int mIndex = 0;
int mStartingIndex = 0;
int mSize = 0;
@@ -44,7 +44,7 @@ public class WireBuffer {
}
}
- public byte[] getBuffer() {
+ public @NonNull byte[] getBuffer() {
return mBuffer;
}
@@ -168,14 +168,14 @@ public class WireBuffer {
return java.lang.Double.longBitsToDouble(readLong());
}
- public byte[] readBuffer() {
+ public @NonNull byte[] readBuffer() {
int count = readInt();
byte[] b = Arrays.copyOfRange(mBuffer, mIndex, mIndex + count);
mIndex += count;
return b;
}
- public byte[] readBuffer(int maxSize) {
+ public @NonNull byte[] readBuffer(int maxSize) {
int count = readInt();
if (count < 0 || count > maxSize) {
throw new RuntimeException(
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
index f6dfe2ebe171..0174ce531d3f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
@@ -15,10 +15,14 @@
*/
package com.android.internal.widget.remotecompose.core.documentation;
+import android.annotation.NonNull;
+
public interface DocumentationBuilder {
- void add(String value);
+ void add(@NonNull String value);
- DocumentedOperation operation(String category, int id, String name);
+ @NonNull
+ DocumentedOperation operation(@NonNull String category, int id, @NonNull String name);
- DocumentedOperation wipOperation(String category, int id, String name);
+ @NonNull
+ DocumentedOperation wipOperation(@NonNull String category, int id, @NonNull String name);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
index 4b84291aa5fe..2806a5e1ad1d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.documentation;
+import android.annotation.NonNull;
+
public interface DocumentedCompanionOperation {
- void documentation(DocumentationBuilder doc);
+ void documentation(@NonNull DocumentationBuilder doc);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
index 5edecaa01f82..bfab62365736 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
@@ -16,6 +16,7 @@
package com.android.internal.widget.remotecompose.core.documentation;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import java.util.ArrayList;
@@ -34,13 +35,13 @@ public class DocumentedOperation {
public static final int FLOAT_ARRAY = 10;
public static final int INT_ARRAY = 11;
- String mCategory;
+ @NonNull final String mCategory;
int mId;
- String mName;
- String mDescription;
+ @NonNull final String mName;
+ @NonNull String mDescription = "";
boolean mWIP;
- String mTextExamples;
+ @Nullable String mTextExamples;
@NonNull ArrayList<StringPair> mExamples = new ArrayList<>();
@NonNull ArrayList<OperationField> mFields = new ArrayList<>();
@@ -77,14 +78,15 @@ public class DocumentedOperation {
return "UNKNOWN";
}
- public DocumentedOperation(String category, int id, String name, boolean wip) {
+ public DocumentedOperation(
+ @NonNull String category, int id, @NonNull String name, boolean wip) {
mCategory = category;
mId = id;
mName = name;
mWIP = wip;
}
- public DocumentedOperation(String category, int id, String name) {
+ public DocumentedOperation(@NonNull String category, int id, @NonNull String name) {
this(category, id, name, false);
}
@@ -93,7 +95,7 @@ public class DocumentedOperation {
return mFields;
}
- public String getCategory() {
+ public @NonNull String getCategory() {
return mCategory;
}
@@ -101,6 +103,7 @@ public class DocumentedOperation {
return mId;
}
+ @NonNull
public String getName() {
return mName;
}
@@ -126,10 +129,12 @@ public class DocumentedOperation {
return size;
}
+ @Nullable
public String getDescription() {
return mDescription;
}
+ @Nullable
public String getTextExamples() {
return mTextExamples;
}
@@ -148,19 +153,20 @@ public class DocumentedOperation {
}
@NonNull
- public DocumentedOperation field(int type, String name, String description) {
+ public DocumentedOperation field(int type, @NonNull String name, @NonNull String description) {
mFields.add(new OperationField(type, name, description));
return this;
}
@NonNull
- public DocumentedOperation field(int type, String name, String varSize, String description) {
+ public DocumentedOperation field(
+ int type, @NonNull String name, @NonNull String varSize, @NonNull String description) {
mFields.add(new OperationField(type, name, varSize, description));
return this;
}
@NonNull
- public DocumentedOperation possibleValues(String name, int value) {
+ public DocumentedOperation possibleValues(@NonNull String name, int value) {
if (!mFields.isEmpty()) {
mFields.get(mFields.size() - 1).possibleValue(name, "" + value);
}
@@ -168,19 +174,19 @@ public class DocumentedOperation {
}
@NonNull
- public DocumentedOperation description(String description) {
+ public DocumentedOperation description(@NonNull String description) {
mDescription = description;
return this;
}
@NonNull
- public DocumentedOperation examples(String examples) {
+ public DocumentedOperation examples(@NonNull String examples) {
mTextExamples = examples;
return this;
}
@NonNull
- public DocumentedOperation exampleImage(String name, String imagePath) {
+ public DocumentedOperation exampleImage(@NonNull String name, @NonNull String imagePath) {
mExamples.add(new StringPair(name, imagePath));
return this;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
index cbb5ca9821c3..9febcfe57047 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
@@ -21,20 +21,21 @@ import android.annotation.Nullable;
import java.util.ArrayList;
public class OperationField {
- int mType;
- String mName;
- String mDescription;
+ final int mType;
+ @NonNull final String mName;
+ @NonNull final String mDescription;
@Nullable String mVarSize = null;
@NonNull ArrayList<StringPair> mPossibleValues = new ArrayList<>();
- public OperationField(int type, String name, String description) {
+ public OperationField(int type, @NonNull String name, @NonNull String description) {
mType = type;
mName = name;
mDescription = description;
}
- public OperationField(int type, String name, String varSize, String description) {
+ public OperationField(
+ int type, @NonNull String name, @Nullable String varSize, @NonNull String description) {
mType = type;
mName = name;
mDescription = description;
@@ -45,10 +46,12 @@ public class OperationField {
return mType;
}
+ @NonNull
public String getName() {
return mName;
}
+ @NonNull
public String getDescription() {
return mDescription;
}
@@ -58,7 +61,7 @@ public class OperationField {
return mPossibleValues;
}
- public void possibleValue(String name, String value) {
+ public void possibleValue(@NonNull String name, @NonNull String value) {
mPossibleValues.add(new StringPair(name, value));
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java
index 5b0cedbaf6af..c1d885806b44 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/StringPair.java
@@ -15,20 +15,22 @@
*/
package com.android.internal.widget.remotecompose.core.documentation;
+import android.annotation.NonNull;
+
public class StringPair {
- String mName;
- String mValue;
+ final @NonNull String mName;
+ final @NonNull String mValue;
- StringPair(String name, String value) {
+ StringPair(@NonNull String name, @NonNull String value) {
mName = name;
mValue = value;
}
- public String getName() {
+ public @NonNull String getName() {
return mName;
}
- public String getValue() {
+ public @NonNull String getValue() {
return mValue;
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
index 8da0e184cbe7..948007699b80 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/BitmapData.java
@@ -17,6 +17,7 @@ package com.android.internal.widget.remotecompose.core.operations;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT;
import android.annotation.NonNull;
@@ -41,10 +42,19 @@ public class BitmapData implements Operation, SerializableToString {
int mImageId;
int mImageWidth;
int mImageHeight;
- byte[] mBitmap;
+ short mType;
+ short mEncoding;
+ @NonNull final byte[] mBitmap;
public static final int MAX_IMAGE_DIMENSION = 8000;
-
- public BitmapData(int imageId, int width, int height, byte[] bitmap) {
+ public static final short ENCODING_INLINE = 0;
+ public static final short ENCODING_URL = 1;
+ public static final short ENCODING_FILE = 2;
+ public static final short TYPE_PNG_8888 = 0;
+ public static final short TYPE_PNG = 1;
+ public static final short TYPE_RAW8 = 2;
+ public static final short TYPE_RAW8888 = 3;
+
+ public BitmapData(int imageId, int width, int height, @NonNull byte[] bitmap) {
this.mImageId = imageId;
this.mImageWidth = width;
this.mImageHeight = height;
@@ -92,6 +102,23 @@ public class BitmapData implements Operation, SerializableToString {
buffer.writeBuffer(bitmap);
}
+ public static void apply(
+ @NonNull WireBuffer buffer,
+ int imageId,
+ short type,
+ short width,
+ short encoding,
+ short height,
+ @NonNull byte[] bitmap) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(imageId);
+ int w = (((int) type) << 16) | width;
+ int h = (((int) encoding) << 16) | height;
+ buffer.writeInt(w);
+ buffer.writeInt(h);
+ buffer.writeBuffer(bitmap);
+ }
+
public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int imageId = buffer.readInt();
int width = buffer.readInt();
@@ -110,19 +137,22 @@ public class BitmapData implements Operation, SerializableToString {
doc.operation("Data Operations", OP_CODE, CLASS_NAME)
.description("Bitmap data")
.field(DocumentedOperation.INT, "id", "id of bitmap data")
+ .field(SHORT, "type", "width of the image")
+ .field(SHORT, "width", "width of the image")
+ .field(SHORT, "encoding", "height of the image")
.field(INT, "width", "width of the image")
- .field(INT, "height", "height of the image")
+ .field(SHORT, "height", "height of the image")
.field(INT_ARRAY, "values", "length", "Array of ints");
}
@Override
public void apply(@NonNull RemoteContext context) {
- context.loadBitmap(mImageId, mImageWidth, mImageHeight, mBitmap);
+ context.loadBitmap(mImageId, mEncoding, mType, mImageWidth, mImageHeight, mBitmap);
}
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
index 83d0ac7a1eb2..310b194ec486 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ClickArea.java
@@ -109,7 +109,7 @@ public class ClickArea implements RemoteComposeOperation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
index 929c9a603079..34e93f590dbe 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
@@ -93,7 +93,7 @@ public class ColorConstant implements Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
index 3d840c5b8203..c947d1139a2e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorExpression.java
@@ -255,7 +255,7 @@ public class ColorExpression implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
index 142c97b24d2e..b0ccd1871fd2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ComponentValue.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -75,7 +74,7 @@ public class ComponentValue implements Operation, SerializableToString {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
// Nothing
}
@@ -123,9 +122,9 @@ public class ComponentValue implements Operation, SerializableToString {
buffer.writeInt(valueId);
}
- @Nullable
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return null;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
index ba02b91b36ed..bfaf139da21b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListFloat.java
@@ -35,17 +35,17 @@ import java.util.List;
public class DataListFloat implements VariableSupport, ArrayAccess, Operation {
private static final int OP_CODE = Operations.FLOAT_LIST;
private static final String CLASS_NAME = "IdListData";
- int mId;
- float[] mValues;
+ private final int mId;
+ @NonNull private final float[] mValues;
private static final int MAX_FLOAT_ARRAY = 2000;
- public DataListFloat(int id, float[] values) {
+ public DataListFloat(int id, @NonNull float[] values) {
mId = id;
mValues = values;
}
@Override
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
// TODO add support for variables in arrays
}
@@ -103,7 +103,7 @@ public class DataListFloat implements VariableSupport, ArrayAccess, Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
@@ -117,6 +117,7 @@ public class DataListFloat implements VariableSupport, ArrayAccess, Operation {
return mValues[index];
}
+ @NonNull
@Override
public float[] getFloats() {
return mValues;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
index b9820f856a92..9b286b94d553 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataListIds.java
@@ -19,6 +19,7 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -35,20 +36,20 @@ import java.util.List;
public class DataListIds implements VariableSupport, ArrayAccess, Operation {
private static final int OP_CODE = Operations.ID_LIST;
private static final String CLASS_NAME = "IdListData";
- int mId;
- int[] mIds;
+ private final int mId;
+ @NonNull private final int[] mIds;
private static final int MAX_LIST = 2000;
- public DataListIds(int id, int[] ids) {
+ public DataListIds(int id, @NonNull int[] ids) {
mId = id;
mIds = ids;
}
@Override
- public void updateVariables(RemoteContext context) {}
+ public void updateVariables(@NonNull RemoteContext context) {}
@Override
- public void registerListening(RemoteContext context) {}
+ public void registerListening(@NonNull RemoteContext context) {}
@Override
public void write(@NonNull WireBuffer buffer) {
@@ -94,7 +95,7 @@ public class DataListIds implements VariableSupport, ArrayAccess, Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
@@ -113,6 +114,7 @@ public class DataListIds implements VariableSupport, ArrayAccess, Operation {
return mIds[index];
}
+ @Nullable
@Override
public float[] getFloats() {
return null;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
index fb559bbf1863..643afc85e69f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapIds.java
@@ -19,6 +19,7 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.UTF8;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -34,7 +35,7 @@ public class DataMapIds implements Operation {
private static final int OP_CODE = Operations.ID_MAP;
private static final String CLASS_NAME = "DataMapIds";
int mId;
- DataMap mDataMap;
+ final DataMap mDataMap;
private static final int MAX_MAP = 2000;
@@ -44,6 +45,7 @@ public class DataMapIds implements Operation {
public static final byte TYPE_LONG = 3;
public static final byte TYPE_BOOLEAN = 4;
+ @NonNull
private String typeString(byte type) {
switch (type) {
case TYPE_STRING:
@@ -60,7 +62,7 @@ public class DataMapIds implements Operation {
return "?";
}
- public DataMapIds(int id, String[] names, byte[] types, int[] ids) {
+ public DataMapIds(int id, @NonNull String[] names, @NonNull byte[] types, @NonNull int[] ids) {
mId = id;
mDataMap = new DataMap(names, types, ids);
}
@@ -88,7 +90,11 @@ public class DataMapIds implements Operation {
}
public static void apply(
- @NonNull WireBuffer buffer, int id, @NonNull String[] names, byte[] type, int[] ids) {
+ @NonNull WireBuffer buffer,
+ int id,
+ @NonNull String[] names,
+ @Nullable byte[] type, // todo: can we make this not nullable?
+ @NonNull int[] ids) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(names.length);
@@ -128,7 +134,7 @@ public class DataMapIds implements Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java
index fb5e5d1734e6..eae532c14344 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DataMapLookup.java
@@ -17,6 +17,8 @@ package com.android.internal.widget.remotecompose.core.operations;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -50,10 +52,11 @@ public class DataMapLookup implements Operation {
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mDataMapId, mStringId);
}
+ @NonNull
@Override
public String toString() {
return "DataMapLookup[" + mId + "] = " + Utils.idString(mDataMapId) + " " + mStringId;
@@ -64,6 +67,7 @@ public class DataMapLookup implements Operation {
*
* @return the name of the class
*/
+ @NonNull
public static String name() {
return CLASS_NAME;
}
@@ -85,7 +89,7 @@ public class DataMapLookup implements Operation {
* @param dataMapId the map to extract from
* @param keyStringId the map to extract from
*/
- public static void apply(WireBuffer buffer, int id, int dataMapId, int keyStringId) {
+ public static void apply(@NonNull WireBuffer buffer, int id, int dataMapId, int keyStringId) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(dataMapId);
@@ -98,14 +102,14 @@ public class DataMapLookup implements Operation {
* @param buffer buffer
* @param operations the created command is added to the list
*/
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int mapId = buffer.readInt();
int stringId = buffer.readInt();
operations.add(new DataMapLookup(id, mapId, stringId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("A float and its associated id")
.field(INT, "id", "id of float")
@@ -114,7 +118,7 @@ public class DataMapLookup implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
String str = context.getText(mStringId);
DataMap data = context.getDataMap(mDataMapId);
int pos = data.getPos(str);
@@ -141,8 +145,9 @@ public class DataMapLookup implements Operation {
}
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java
index 984599e09c19..c1e2e662ca80 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase2.java
@@ -60,11 +60,11 @@ public abstract class DrawBase2 extends PaintOperation implements VariableSuppor
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
write(buffer, mV1, mV2);
}
- protected abstract void write(WireBuffer buffer, float v1, float v2);
+ protected abstract void write(@NonNull WireBuffer buffer, float v1, float v2);
protected interface Maker {
DrawBase2 create(float v1, float v2);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java
index 825da5240032..6fedea3245a2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase3.java
@@ -70,11 +70,11 @@ public abstract class DrawBase3 extends PaintOperation implements VariableSuppor
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
write(buffer, mV1, mV2, mV3);
}
- protected abstract void write(WireBuffer buffer, float v1, float v2, float v3);
+ protected abstract void write(@NonNull WireBuffer buffer, float v1, float v2, float v3);
interface Maker {
DrawBase3 create(float v1, float v2, float v3);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
index a23bcb9dca78..aa9cc68e6552 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase4.java
@@ -77,11 +77,12 @@ public abstract class DrawBase4 extends PaintOperation implements VariableSuppor
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
write(buffer, mX1, mY1, mX2, mY2);
}
- protected abstract void write(WireBuffer buffer, float v1, float v2, float v3, float v4);
+ protected abstract void write(
+ @NonNull WireBuffer buffer, float v1, float v2, float v3, float v4);
protected interface Maker {
DrawBase4 create(float v1, float v2, float v3, float v4);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java
index 68c9f8cdc462..6c288a35621d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBase6.java
@@ -91,12 +91,12 @@ public abstract class DrawBase6 extends PaintOperation implements VariableSuppor
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
write(buffer, mV1, mV2, mV3, mV4, mV5, mV6);
}
protected abstract void write(
- WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6);
+ @NonNull WireBuffer buffer, float v1, float v2, float v3, float v4, float v5, float v6);
@NonNull
@Override
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
index e20bcd2d79b5..e9f81d52d67f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DrawBitmapScaled.java
@@ -46,6 +46,7 @@ public class DrawBitmapScaled extends PaintOperation implements VariableSupport
int mContentDescId;
float mScaleFactor, mOutScaleFactor;
int mScaleType;
+ int mMode;
@NonNull ImageScaling mScaling = new ImageScaling();
public static final int SCALE_NONE = ImageScaling.SCALE_NONE;
@@ -79,7 +80,8 @@ public class DrawBitmapScaled extends PaintOperation implements VariableSupport
mOutDstTop = mDstTop = dstTop;
mOutDstRight = mDstRight = dstRight;
mOutDstBottom = mDstBottom = dstBottom;
- mScaleType = type;
+ mScaleType = type & 0xFF;
+ mMode = type >> 8;
mOutScaleFactor = mScaleFactor = scale;
this.mContentDescId = cdId;
}
@@ -308,8 +310,14 @@ public class DrawBitmapScaled extends PaintOperation implements VariableSupport
mOutScaleFactor);
context.save();
context.clipRect(mOutDstLeft, mOutDstTop, mOutDstRight, mOutDstBottom);
+
+ int imageId = mImageId;
+ if ((mMode & 0x1) != 0) {
+ imageId = context.getContext().getInteger(imageId);
+ }
+
context.drawBitmap(
- mImageId,
+ imageId,
(int) mOutSrcLeft,
(int) mOutSrcTop,
(int) mOutSrcRight,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
index 89390acb8c50..17aaf3bb9cd8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatConstant.java
@@ -94,7 +94,7 @@ public class FloatConstant implements com.android.internal.widget.remotecompose.
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
index e1c6c2577860..eef9746ffaf6 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
@@ -33,6 +33,7 @@ import com.android.internal.widget.remotecompose.core.documentation.DocumentedOp
import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression;
import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
import com.android.internal.widget.remotecompose.core.operations.utilities.easing.FloatAnimation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.SpringStopEngine;
import java.util.List;
@@ -45,21 +46,26 @@ public class FloatExpression implements Operation, VariableSupport {
private static final int OP_CODE = Operations.ANIMATED_FLOAT;
private static final String CLASS_NAME = "FloatExpression";
public int mId;
- public float[] mSrcValue;
- public float[] mSrcAnimation;
- public FloatAnimation mFloatAnimation;
- public float[] mPreCalcValue;
+ @NonNull public float[] mSrcValue;
+ @Nullable public float[] mSrcAnimation;
+ @Nullable public FloatAnimation mFloatAnimation;
+ @Nullable private SpringStopEngine mSpring;
+ @Nullable public float[] mPreCalcValue;
private float mLastChange = Float.NaN;
private float mLastCalculatedValue = Float.NaN;
@NonNull AnimatedFloatExpression mExp = new AnimatedFloatExpression();
public static final int MAX_EXPRESSION_SIZE = 32;
- public FloatExpression(int id, float[] value, float[] animation) {
+ public FloatExpression(int id, @NonNull float[] value, @Nullable float[] animation) {
this.mId = id;
this.mSrcValue = value;
this.mSrcAnimation = animation;
if (mSrcAnimation != null) {
- mFloatAnimation = new FloatAnimation(mSrcAnimation);
+ if (mSrcAnimation.length > 4 && mSrcAnimation[0] == 0) {
+ mSpring = new SpringStopEngine(mSrcAnimation);
+ } else {
+ mFloatAnimation = new FloatAnimation(mSrcAnimation);
+ }
}
}
@@ -75,12 +81,23 @@ public class FloatExpression implements Operation, VariableSupport {
if (Float.isNaN(v)
&& !AnimatedFloatExpression.isMathOperator(v)
&& !NanMap.isDataVariable(v)) {
+ int id = Utils.idFromNan(v);
float newValue = context.getFloat(Utils.idFromNan(v));
+
+ // TODO: rethink the lifecycle for variable updates
+ if (id == RemoteContext.ID_DENSITY && newValue == 0f) {
+ newValue = 1f;
+ }
if (mFloatAnimation != null) {
if (mPreCalcValue[i] != newValue) {
value_changed = true;
mPreCalcValue[i] = newValue;
}
+ } else if (mSpring != null) {
+ if (mPreCalcValue[i] != newValue) {
+ value_changed = true;
+ mPreCalcValue[i] = newValue;
+ }
} else {
mPreCalcValue[i] = newValue;
}
@@ -106,6 +123,8 @@ public class FloatExpression implements Operation, VariableSupport {
mFloatAnimation.setInitialValue(mFloatAnimation.getTargetValue());
}
mFloatAnimation.setTargetValue(v);
+ } else if (value_changed && mSpring != null) {
+ mSpring.setTargetValue(v);
}
}
@@ -130,6 +149,9 @@ public class FloatExpression implements Operation, VariableSupport {
if (mFloatAnimation != null) {
float f = mFloatAnimation.get(t - mLastChange);
context.loadFloat(mId, f);
+ } else if (mSpring != null) {
+ float f = mSpring.get(t - mLastChange);
+ context.loadFloat(mId, f);
} else {
context.loadFloat(
mId,
@@ -137,6 +159,21 @@ public class FloatExpression implements Operation, VariableSupport {
}
}
+ /**
+ * Evaluate the expression
+ *
+ * @param context current context
+ * @return the resulting value
+ */
+ public float evaluate(@NonNull RemoteContext context) {
+ updateVariables(context);
+ float t = context.getAnimationTime();
+ if (Float.isNaN(mLastChange)) {
+ mLastChange = t;
+ }
+ return mExp.eval(context.getCollectionsAccess(), mPreCalcValue, mPreCalcValue.length);
+ }
+
@Override
public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mSrcValue, mSrcAnimation);
@@ -256,7 +293,7 @@ public class FloatExpression implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
index 1979bc5f4331..009aa0339625 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
@@ -111,7 +111,7 @@ public class Header implements RemoteComposeOperation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
index 6375f001c818..c49f74de7893 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/IntegerExpression.java
@@ -19,6 +19,7 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT_ARRAY;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -43,13 +44,13 @@ public class IntegerExpression implements Operation, VariableSupport {
public int mId;
private int mMask;
private int mPreMask;
- public int[] mSrcValue;
- public int[] mPreCalcValue;
+ @NonNull public final int[] mSrcValue;
+ @Nullable public int[] mPreCalcValue;
private float mLastChange = Float.NaN;
public static final int MAX_SIZE = 320;
@NonNull IntegerExpressionEvaluator mExp = new IntegerExpressionEvaluator();
- public IntegerExpression(int id, int mask, int[] value) {
+ public IntegerExpression(int id, int mask, @NonNull int[] value) {
this.mId = id;
this.mMask = mask;
this.mSrcValue = value;
@@ -188,7 +189,7 @@ public class IntegerExpression implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
index 6a620e58570a..4e7ee4d135ee 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixRestore.java
@@ -37,7 +37,7 @@ public class MatrixRestore extends PaintOperation {
apply(buffer);
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
MatrixRestore op = new MatrixRestore();
operations.add(op);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
index 1880b19be1a7..09f54a52e6a3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/MatrixSave.java
@@ -41,7 +41,7 @@ public class MatrixSave extends PaintOperation {
return "MatrixSave;";
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
MatrixSave op = new MatrixSave();
operations.add(op);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
index 6310521e4010..5ca91af91f86 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
@@ -33,16 +33,16 @@ import java.util.List;
public class NamedVariable implements Operation {
private static final int OP_CODE = Operations.NAMED_VARIABLE;
private static final String CLASS_NAME = "NamedVariable";
- public int mVarId;
- public String mVarName;
- public int mVarType;
+ public final int mVarId;
+ public final @NonNull String mVarName;
+ public final int mVarType;
public static final int MAX_STRING_SIZE = 4000;
public static final int COLOR_TYPE = 2;
public static final int FLOAT_TYPE = 1;
public static final int STRING_TYPE = 0;
public static final int IMAGE_TYPE = 3;
- public NamedVariable(int varId, int varType, String name) {
+ public NamedVariable(int varId, int varType, @NonNull String name) {
this.mVarId = varId;
this.mVarType = varType;
this.mVarName = name;
@@ -111,7 +111,7 @@ public class NamedVariable implements Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
index 527d5610788c..b24df8a6a91e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PaintData.java
@@ -90,7 +90,7 @@ public class PaintData extends PaintOperation implements VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
index 06a1fec36196..509f362c02ed 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
@@ -73,7 +73,7 @@ public class PathData implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return pathString(mFloatPath);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
index 6ff9ad73e35f..849412618c2c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
@@ -196,7 +196,7 @@ public class RootContentBehavior implements RemoteComposeOperation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
index c2d62a7b3ac4..109945f21ec5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
@@ -60,7 +60,7 @@ public class RootContentDescription implements RemoteComposeOperation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
index ae61c3aa01c9..e967ff4f4ff4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ShaderData.java
@@ -48,7 +48,7 @@ public class ShaderData implements Operation, VariableSupport {
int mShaderID; // allows shaders to be referenced by number
@Nullable HashMap<String, float[]> mUniformRawFloatMap = null;
@Nullable HashMap<String, float[]> mUniformFloatMap = null;
- @Nullable HashMap<String, int[]> mUniformIntMap = null;
+ @Nullable HashMap<String, int[]> mUniformIntMap;
@Nullable HashMap<String, Integer> mUniformBitmapMap = null;
public ShaderData(
@@ -104,8 +104,8 @@ public class ShaderData implements Operation, VariableSupport {
* @param name name of uniform
* @return value of uniform
*/
- public float[] getUniformFloats(String name) {
- return mUniformFloatMap.get(name);
+ public @NonNull float[] getUniformFloats(@NonNull String name) {
+ return mUniformFloatMap != null ? mUniformFloatMap.get(name) : new float[0];
}
/**
@@ -125,8 +125,8 @@ public class ShaderData implements Operation, VariableSupport {
* @param name Name of uniform
* @return value of uniform
*/
- public int[] getUniformInts(String name) {
- return mUniformIntMap.get(name);
+ public @NonNull int[] getUniformInts(@NonNull String name) {
+ return mUniformIntMap != null ? mUniformIntMap.get(name) : new int[0];
}
/**
@@ -146,8 +146,10 @@ public class ShaderData implements Operation, VariableSupport {
* @param name Name of bitmap uniform
* @return Bitmap ID
*/
- public int getUniformBitmapId(String name) {
- return mUniformBitmapMap.get(name);
+ public int getUniformBitmapId(@NonNull String name) {
+ return mUniformBitmapMap != null
+ ? mUniformBitmapMap.get(name)
+ : -1; // TODO: what is the proper return value here? -- bbade@
}
@Override
@@ -169,7 +171,7 @@ public class ShaderData implements Operation, VariableSupport {
@Override
public void updateVariables(@NonNull RemoteContext context) {
- for (String name : mUniformRawFloatMap.keySet()) {
+ for (String name : mUniformRawFloatMap.keySet()) { // TODO: potential npe
float[] value = mUniformRawFloatMap.get(name);
float[] out = null;
for (int i = 0; i < value.length; i++) {
@@ -186,7 +188,7 @@ public class ShaderData implements Operation, VariableSupport {
@Override
public void registerListening(@NonNull RemoteContext context) {
- for (String name : mUniformRawFloatMap.keySet()) {
+ for (String name : mUniformRawFloatMap.keySet()) { // TODO: potential npe
float[] value = mUniformRawFloatMap.get(name);
for (float v : value) {
if (Float.isNaN(v)) {
@@ -340,7 +342,7 @@ public class ShaderData implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
index dbaef7ef7ae1..ade008e3bdb4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextData.java
@@ -34,11 +34,11 @@ import java.util.List;
public class TextData implements Operation, SerializableToString {
private static final int OP_CODE = Operations.DATA_TEXT;
private static final String CLASS_NAME = "TextData";
- public int mTextId;
- public String mText;
+ public final int mTextId;
+ @NonNull public final String mText;
public static final int MAX_STRING_SIZE = 4000;
- public TextData(int textId, String text) {
+ public TextData(int textId, @NonNull String text) {
this.mTextId = textId;
this.mText = text;
}
@@ -90,7 +90,7 @@ public class TextData implements Operation, SerializableToString {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
index fb5087f3fee3..865ee81f2725 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextFromFloat.java
@@ -185,7 +185,7 @@ public class TextFromFloat implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java
index e148fb9849fc..6ff687b7494e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLength.java
@@ -17,6 +17,8 @@ package com.android.internal.widget.remotecompose.core.operations;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -38,16 +40,17 @@ public class TextLength implements Operation {
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mLengthId, mTextId);
}
+ @NonNull
@Override
public String toString() {
return CLASS_NAME + "[" + mLengthId + "] = " + mTextId;
}
- public static String name() {
+ public static @NonNull String name() {
return CLASS_NAME;
}
@@ -62,19 +65,19 @@ public class TextLength implements Operation {
* @param lengthId the id to output
* @param textId the id of the text to measure
*/
- public static void apply(WireBuffer buffer, int lengthId, int textId) {
+ public static void apply(@NonNull WireBuffer buffer, int lengthId, int textId) {
buffer.start(OP_CODE);
buffer.writeInt(lengthId);
buffer.writeInt(textId);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int lengthId = buffer.readInt();
int textId = buffer.readInt();
operations.add(new TextLength(lengthId, textId));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("get the length of the text and store in float table")
.field(INT, "id", "id of float length")
@@ -82,12 +85,13 @@ public class TextLength implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.loadFloat(mLengthId, context.getText(mTextId).length());
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
index 2129edde2f59..cc812a8e160e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookup.java
@@ -126,7 +126,7 @@ public class TextLookup implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
index ea550cbe010c..74be698872fa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextLookupInt.java
@@ -119,7 +119,7 @@ public class TextLookupInt implements Operation, VariableSupport {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java
index 0281d6980e0f..6d48f67ed8c8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMeasure.java
@@ -19,6 +19,8 @@ import static com.android.internal.widget.remotecompose.core.PaintContext.TEXT_M
import static com.android.internal.widget.remotecompose.core.PaintContext.TEXT_MEASURE_MONOSPACE_WIDTH;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -55,16 +57,16 @@ public class TextMeasure extends PaintOperation {
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
apply(buffer, mId, mTextId, mType);
}
@Override
- public String toString() {
+ public @NonNull String toString() {
return "FloatConstant[" + mId + "] = " + mTextId + " " + mType;
}
- public static String name() {
+ public static @NonNull String name() {
return CLASS_NAME;
}
@@ -80,21 +82,21 @@ public class TextMeasure extends PaintOperation {
* @param textId the id
* @param type the value of the float
*/
- public static void apply(WireBuffer buffer, int id, int textId, int type) {
+ public static void apply(@NonNull WireBuffer buffer, int id, int textId, int type) {
buffer.start(OP_CODE);
buffer.writeInt(id);
buffer.writeInt(textId);
buffer.writeInt(type);
}
- public static void read(WireBuffer buffer, List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
int id = buffer.readInt();
int textId = buffer.readInt();
int type = buffer.readInt();
operations.add(new TextMeasure(id, textId, type));
}
- public static void documentation(DocumentationBuilder doc) {
+ public static void documentation(@NonNull DocumentationBuilder doc) {
doc.operation("Expressions Operations", OP_CODE, CLASS_NAME)
.description("A float and its associated id")
.field(INT, "id", "id of float result of the measure")
@@ -102,15 +104,16 @@ public class TextMeasure extends PaintOperation {
.field(INT, "type", "type: measure 0=width,1=height");
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
- float[] mBounds = new float[4];
+ @NonNull float[] mBounds = new float[4];
@Override
- public void paint(PaintContext context) {
+ public void paint(@NonNull PaintContext context) {
int val = mType & 255;
int flags = mType >> 8;
context.getTextBounds(mTextId, 0, -1, flags, mBounds);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
index fa18b4ddb2a2..ecd5baaf0dd2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TextMerge.java
@@ -102,7 +102,7 @@ public class TextMerge implements Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
index 1e90ab128e93..d265070a50bf 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
@@ -68,7 +68,7 @@ public class Theme implements RemoteComposeOperation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
index b25a7f6ea09d..1bb7b2a183a2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
@@ -20,6 +20,8 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.SHORT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -71,6 +73,7 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
boolean mWrapMode = false;
float[] mNotches;
float[] mStopSpec;
+ float[] mOutStopSpec;
int mTouchEffects;
float mVelocityId;
@@ -98,6 +101,9 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
mOutDefValue = mDefValue = defValue;
mMode = STOP_ABSOLUTE_POS == stopMode ? 1 : 0;
mOutMax = mMax = max;
+ if (stopSpec != null) {
+ mOutStopSpec = Arrays.copyOf(stopSpec, stopSpec.length);
+ }
mTouchEffects = touchEffects;
mVelocityId = velocityId;
if (Float.isNaN(min) && Utils.idFromNan(min) == 0) {
@@ -108,10 +114,8 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
mStopMode = stopMode;
mStopSpec = stopSpec;
if (easingSpec != null) {
- Utils.log("easingSpec " + Arrays.toString(easingSpec));
if (easingSpec.length >= 4) {
if (Float.floatToRawIntBits(easingSpec[0]) == 0) {
- Utils.log("easingSpec[2] " + easingSpec[2]);
mMaxTime = easingSpec[1];
mMaxAcceleration = easingSpec[2];
mMaxVelocity = easingSpec[3];
@@ -126,6 +130,9 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
if (mPreCalcValue == null || mPreCalcValue.length != mSrcExp.length) {
mPreCalcValue = new float[mSrcExp.length];
}
+ if (mOutStopSpec == null || mOutStopSpec.length != mStopSpec.length) {
+ mOutStopSpec = new float[mStopSpec.length];
+ }
if (Float.isNaN(mMax)) {
mOutMax = context.getFloat(Utils.idFromNan(mMax));
}
@@ -150,6 +157,15 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
mPreCalcValue[i] = mSrcExp[i];
}
}
+ for (int i = 0; i < mStopSpec.length; i++) {
+ float v = mStopSpec[i];
+ if (Float.isNaN(v)) {
+ float newValue = context.getFloat(Utils.idFromNan(v));
+ mOutStopSpec[i] = newValue;
+ } else {
+ mOutStopSpec[i] = v;
+ }
+ }
float v = mLastCalculatedValue;
if (value_changed) { // inputs changed check if output changed
v = mExp.eval(mPreCalcValue, mPreCalcValue.length);
@@ -181,6 +197,11 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
context.listensTo(Utils.idFromNan(v), this);
}
}
+ for (float v : mStopSpec) {
+ if (Float.isNaN(v)) {
+ context.listensTo(Utils.idFromNan(v), this);
+ }
+ }
}
private float wrap(float pos) {
@@ -211,12 +232,14 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
case STOP_INSTANTLY:
return pos;
case STOP_NOTCHES_EVEN:
- int evenSpacing = (int) mStopSpec[0];
- float step = (mOutMax - min) / evenSpacing;
+ int evenSpacing = (int) mOutStopSpec[0];
+ float notchMax = (mOutStopSpec.length > 1) ? mOutStopSpec[1] : mOutMax;
+ float step = (notchMax - min) / evenSpacing;
float notch = min + step * (int) (0.5f + (target - mOutMin) / step);
-
- notch = Math.max(Math.min(notch, mOutMax), min);
+ if (!mWrapMode) {
+ notch = Math.max(Math.min(notch, mOutMax), min);
+ }
return notch;
case STOP_NOTCHES_PERCENTS:
positions = new float[mStopSpec.length];
@@ -265,7 +288,6 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
float next = mCurrentValue;
mLastValue = next;
- // System.out.println(mStopMode + " " + prev + " -> " + next);
float min = (mWrapMode) ? 0 : mOutMin;
float max = mOutMax;
@@ -309,7 +331,7 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
@Override
public void apply(RemoteContext context) {
- Component comp = context.lastComponent;
+ Component comp = context.mLastComponent;
if (comp != null) {
float x = comp.getX();
float y = comp.getY();
@@ -329,7 +351,6 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
updateVariables(context);
if (mUnmodified) {
mCurrentValue = mOutDefValue;
-
context.loadFloat(mId, wrap(mCurrentValue));
return;
}
@@ -337,7 +358,11 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
float time = context.getAnimationTime() - mTouchUpTime;
float value = mEasyTouch.getPos(time);
mCurrentValue = value;
- value = wrap(value);
+ if (mWrapMode) {
+ value = wrap(value);
+ } else {
+ value = Math.min(Math.max(value, mOutMin), mOutMax);
+ }
context.loadFloat(mId, value);
if (mEasyTouch.getDuration() < time) {
mEasingToStop = false;
@@ -410,7 +435,8 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
mTouchUpTime = context.getAnimationTime();
float dest = getStopPosition(value, slope);
- mEasyTouch.config(value, dest, slope, mMaxTime, mMaxAcceleration, mMaxVelocity, null);
+ float time = mMaxTime * Math.abs(dest - value) / (2 * mMaxVelocity);
+ mEasyTouch.config(value, dest, slope, time, mMaxAcceleration, mMaxVelocity, null);
mEasingToStop = true;
}
@@ -543,7 +569,6 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
int stopLen = stopLogic & 0xFFFF;
int stopMode = stopLogic >> 16;
- Utils.log("stopMode " + stopMode + " stopLen " + stopLen);
float[] stopsData = new float[stopLen];
for (int i = 0; i < stopsData.length; i++) {
stopsData[i] = buffer.readFloat();
@@ -592,8 +617,9 @@ public class TouchExpression implements Operation, VariableSupport, TouchListene
.field(FLOAT, "wrapValue", "> [Wrap value] ");
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return indent + toString();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
index 03f7e0563eeb..baca3e0dc99a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
@@ -69,7 +69,7 @@ public class Utils {
* @param value
* @return
*/
- public static String floatToString(float idvalue, float value) {
+ public static @NonNull String floatToString(float idvalue, float value) {
if (Float.isNaN(idvalue)) {
if (idFromNan(value) == 0) {
return "NaN";
@@ -85,7 +85,7 @@ public class Utils {
* @param value
* @return
*/
- public static String floatToString(float value) {
+ public static @NonNull String floatToString(float value) {
if (Float.isNaN(value)) {
if (idFromNan(value) == 0) {
return "NaN";
@@ -100,7 +100,7 @@ public class Utils {
*
* @param str
*/
- public static void log(String str) {
+ public static void log(@NonNull String str) {
StackTraceElement s = new Throwable().getStackTrace()[1];
System.out.println(
"("
@@ -119,7 +119,7 @@ public class Utils {
* @param str
* @param n
*/
- public static void logStack(String str, int n) {
+ public static void logStack(@NonNull String str, int n) {
StackTraceElement[] st = new Throwable().getStackTrace();
for (int i = 1; i < n + 1; i++) {
StackTraceElement s = st[i];
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java
index bdc2a886ffd6..7f1d101cff16 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ActionOperation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -22,8 +24,12 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.Strin
/** Operations representing actions on the document */
public interface ActionOperation extends Operation {
- void serializeToString(int indent, StringSerializer serializer);
+ void serializeToString(int indent, @NonNull StringSerializer serializer);
void runAction(
- RemoteContext context, CoreDocument document, Component component, float x, float y);
+ @NonNull RemoteContext context,
+ @NonNull CoreDocument document,
+ @NonNull Component component,
+ float x,
+ float y);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java
index e789710bb113..19f4c2b04956 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/AnimatableValue.java
@@ -77,4 +77,9 @@ public class AnimatableValue {
return mValue;
}
+
+ @Override
+ public String toString() {
+ return "AnimatableValue{mId=" + mId + "}";
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
index 988651895bae..aa8f75807141 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
@@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -35,7 +36,7 @@ public class CanvasContent extends Component implements ComponentStartOperation
float y,
float width,
float height,
- Component parent,
+ @Nullable Component parent,
int animationId) {
super(parent, componentId, animationId, x, y, width, height);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
index b567538b1c4e..f44e20ddcdac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
@@ -16,7 +16,6 @@
package com.android.internal.widget.remotecompose.core.operations.layout;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -80,7 +79,7 @@ public class ClickModifierOperation extends PaintOperation
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
for (Operation op : mList) {
if (op instanceof TextData) {
op.apply(context);
@@ -90,7 +89,7 @@ public class ClickModifierOperation extends PaintOperation
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -137,7 +136,7 @@ public class ClickModifierOperation extends PaintOperation
}
@Override
- public void layout(RemoteContext context, float width, float height) {
+ public void layout(@NonNull RemoteContext context, float width, float height) {
mWidth = width;
mHeight = height;
}
@@ -154,8 +153,8 @@ public class ClickModifierOperation extends PaintOperation
@Override
public void onClick(
- RemoteContext context,
- CoreDocument document,
+ @NonNull RemoteContext context,
+ @NonNull CoreDocument document,
@NonNull Component component,
float x,
float y) {
@@ -171,6 +170,7 @@ public class ClickModifierOperation extends PaintOperation
((ActionOperation) o).runAction(context, document, component, x, y);
}
}
+ context.hapticEffect(3);
}
@NonNull
@@ -182,7 +182,7 @@ public class ClickModifierOperation extends PaintOperation
buffer.start(OP_CODE);
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new ClickModifierOperation());
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index f4f4ee2a3416..fbfc796e092a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -50,12 +50,12 @@ public class Component extends PaintOperation implements Measurable, Serializabl
protected float mY;
protected float mWidth;
protected float mHeight;
- protected Component mParent;
+ @Nullable protected Component mParent;
protected int mAnimationId = -1;
- public Visibility mVisibility = Visibility.VISIBLE;
- public Visibility mScheduledVisibility = Visibility.VISIBLE;
+ @NonNull public Visibility mVisibility = Visibility.VISIBLE;
+ @NonNull public Visibility mScheduledVisibility = Visibility.VISIBLE;
@NonNull public ArrayList<Operation> mList = new ArrayList<>();
- public PaintOperation mPreTranslate;
+ public PaintOperation mPreTranslate; // todo, can we initialize this here and make it NonNull?
public boolean mNeedsMeasure = true;
public boolean mNeedsRepaint = false;
@Nullable public AnimateMeasure mAnimateMeasure;
@@ -99,6 +99,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
return mAnimationId;
}
+ @Nullable
public Component getParent() {
return mParent;
}
@@ -160,7 +161,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
}
public Component(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -177,7 +178,12 @@ public class Component extends PaintOperation implements Measurable, Serializabl
}
public Component(
- int componentId, float x, float y, float width, float height, Component parent) {
+ int componentId,
+ float x,
+ float y,
+ float width,
+ float height,
+ @Nullable Component parent) {
this(parent, componentId, -1, x, y, width, height);
}
@@ -211,7 +217,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
return mNeedsMeasure;
}
- public void setParent(Component parent) {
+ public void setParent(@Nullable Component parent) {
mParent = parent;
}
@@ -222,8 +228,8 @@ public class Component extends PaintOperation implements Measurable, Serializabl
* @param context the current context
*/
public void updateVariables(@NonNull RemoteContext context) {
- Component prev = context.lastComponent;
- context.lastComponent = this;
+ Component prev = context.mLastComponent;
+ context.mLastComponent = this;
if (!mComponentValues.isEmpty()) {
updateComponentValues(context);
@@ -236,13 +242,21 @@ public class Component extends PaintOperation implements Measurable, Serializabl
o.apply(context);
}
}
- context.lastComponent = prev;
+ context.mLastComponent = prev;
}
- public void addComponentValue(ComponentValue v) {
+ public void addComponentValue(@NonNull ComponentValue v) {
mComponentValues.add(v);
}
+ public float intrinsicWidth() {
+ return getWidth();
+ }
+
+ public float intrinsicHeight() {
+ return getHeight();
+ }
+
public enum Visibility {
GONE,
VISIBLE,
@@ -253,13 +267,13 @@ public class Component extends PaintOperation implements Measurable, Serializabl
if (mVisibility != Visibility.VISIBLE || mParent == null) {
return mVisibility == Visibility.VISIBLE;
}
- if (mParent != null) {
+ if (mParent != null) { // TODO: this is always true -- bbade@
return mParent.isVisible();
}
return true;
}
- public void setVisibility(Visibility visibility) {
+ public void setVisibility(@NonNull Visibility visibility) {
if (visibility != mVisibility || visibility != mScheduledVisibility) {
mScheduledVisibility = visibility;
invalidateMeasure();
@@ -267,7 +281,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
}
@Override
- public boolean suitableForTransition(Operation o) {
+ public boolean suitableForTransition(@NonNull Operation o) {
if (!(o instanceof Component)) {
return false;
}
@@ -291,7 +305,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
@Override
public void measure(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
@@ -358,16 +372,27 @@ public class Component extends PaintOperation implements Measurable, Serializabl
return x >= lx1 && x < lx2 && y >= ly1 && y < ly2;
}
- public void onClick(RemoteContext context, CoreDocument document, float x, float y) {
+ public float getScrollX() {
+ return 0;
+ }
+
+ public float getScrollY() {
+ return 0;
+ }
+
+ public void onClick(
+ @NonNull RemoteContext context, @NonNull CoreDocument document, float x, float y) {
if (!contains(x, y)) {
return;
}
+ float cx = x - getScrollX();
+ float cy = y - getScrollY();
for (Operation op : mList) {
if (op instanceof Component) {
- ((Component) op).onClick(context, document, x, y);
+ ((Component) op).onClick(context, document, cx, cy);
}
if (op instanceof ClickHandler) {
- ((ClickHandler) op).onClick(context, document, this, x, y);
+ ((ClickHandler) op).onClick(context, document, this, cx, cy);
}
}
}
@@ -376,12 +401,14 @@ public class Component extends PaintOperation implements Measurable, Serializabl
if (!contains(x, y)) {
return;
}
+ float cx = x - getScrollX();
+ float cy = y - getScrollY();
for (Operation op : mList) {
if (op instanceof Component) {
- ((Component) op).onTouchDown(context, document, x, y);
+ ((Component) op).onTouchDown(context, document, cx, cy);
}
if (op instanceof TouchHandler) {
- ((TouchHandler) op).onTouchDown(context, document, this, x, y);
+ ((TouchHandler) op).onTouchDown(context, document, this, cx, cy);
}
}
}
@@ -391,12 +418,14 @@ public class Component extends PaintOperation implements Measurable, Serializabl
if (!force && !contains(x, y)) {
return;
}
+ float cx = x - getScrollX();
+ float cy = y - getScrollY();
for (Operation op : mList) {
if (op instanceof Component) {
- ((Component) op).onTouchUp(context, document, x, y, force);
+ ((Component) op).onTouchUp(context, document, cx, cy, force);
}
if (op instanceof TouchHandler) {
- ((TouchHandler) op).onTouchUp(context, document, this, x, y);
+ ((TouchHandler) op).onTouchUp(context, document, this, cx, cy);
}
}
}
@@ -406,12 +435,31 @@ public class Component extends PaintOperation implements Measurable, Serializabl
if (!force && !contains(x, y)) {
return;
}
+ float cx = x - getScrollX();
+ float cy = y - getScrollY();
+ for (Operation op : mList) {
+ if (op instanceof Component) {
+ ((Component) op).onTouchCancel(context, document, cx, cy, force);
+ }
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchCancel(context, document, this, cx, cy);
+ }
+ }
+ }
+
+ public void onTouchDrag(
+ RemoteContext context, CoreDocument document, float x, float y, boolean force) {
+ if (!force && !contains(x, y)) {
+ return;
+ }
+ float cx = x - getScrollX();
+ float cy = y - getScrollY();
for (Operation op : mList) {
if (op instanceof Component) {
- ((Component) op).onTouchCancel(context, document, x, y, force);
+ ((Component) op).onTouchDrag(context, document, cx, cy, force);
}
if (op instanceof TouchHandler) {
- ((TouchHandler) op).onTouchCancel(context, document, this, x, y);
+ ((TouchHandler) op).onTouchDrag(context, document, this, cx, cy);
}
}
}
@@ -480,7 +528,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
// nothing
}
@@ -502,7 +550,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
StringBuilder builder = new StringBuilder();
builder.append(indent);
builder.append(toString());
@@ -602,8 +650,8 @@ public class Component extends PaintOperation implements Measurable, Serializabl
if (mPreTranslate != null) {
mPreTranslate.paint(context);
}
- Component prev = context.getContext().lastComponent;
- context.getContext().lastComponent = this;
+ Component prev = context.getContext().mLastComponent;
+ context.getContext().mLastComponent = this;
context.save();
context.translate(mX, mY);
if (context.isVisualDebug()) {
@@ -618,7 +666,7 @@ public class Component extends PaintOperation implements Measurable, Serializabl
}
}
context.restore();
- context.getContext().lastComponent = prev;
+ context.getContext().mLastComponent = prev;
}
public boolean applyAnimationAsNeeded(@NonNull PaintContext context) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
index f370e20677e8..476b73c8fe7d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentEnd.java
@@ -16,7 +16,6 @@
package com.android.internal.widget.remotecompose.core.operations.layout;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -40,13 +39,13 @@ public class ComponentEnd implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
// nothing
}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -67,7 +66,7 @@ public class ComponentEnd implements Operation {
return 1 + 4 + 4 + 4;
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new ComponentEnd());
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
index f250d9ac4a01..def9f780ba7f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
@@ -19,7 +19,6 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -96,12 +95,12 @@ public class ComponentStart implements ComponentStartOperation {
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
// nothing
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
index bb4311996df0..d6170074238a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/DecoratorComponent.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.RemoteContext;
/**
@@ -22,5 +24,5 @@ import com.android.internal.widget.remotecompose.core.RemoteContext;
* measured. Eg borders, background, clips, etc.
*/
public interface DecoratorComponent {
- void layout(RemoteContext context, float width, float height);
+ void layout(@NonNull RemoteContext context, float width, float height);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index e0923dfb48fb..0041582f7189 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -24,7 +24,9 @@ import com.android.internal.widget.remotecompose.core.operations.BitmapData;
import com.android.internal.widget.remotecompose.core.operations.MatrixRestore;
import com.android.internal.widget.remotecompose.core.operations.MatrixSave;
import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
+import com.android.internal.widget.remotecompose.core.operations.PaintData;
import com.android.internal.widget.remotecompose.core.operations.TextData;
+import com.android.internal.widget.remotecompose.core.operations.TouchExpression;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentVisibilityOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.DimensionModifierOperation;
@@ -57,12 +59,14 @@ public class LayoutComponent extends Component {
protected float mPaddingBottom = 0f;
@NonNull protected ComponentModifiers mComponentModifiers = new ComponentModifiers();
- @NonNull protected ArrayList<Component> mChildrenComponents = new ArrayList<>();
+
+ @NonNull
+ protected ArrayList<Component> mChildrenComponents = new ArrayList<>(); // members are not null
protected boolean mChildrenHaveZIndex = false;
public LayoutComponent(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -129,6 +133,9 @@ public class LayoutComponent extends Component {
public void inflate() {
ArrayList<TextData> data = new ArrayList<>();
+ ArrayList<TouchExpression> touchExpressions = new ArrayList<>();
+ ArrayList<PaintData> paintData = new ArrayList<>();
+
for (Operation op : mList) {
if (op instanceof LayoutComponentContent) {
mContent = (LayoutComponentContent) op;
@@ -172,6 +179,10 @@ public class LayoutComponent extends Component {
mComponentModifiers.add((ModifierOperation) op);
} else if (op instanceof TextData) {
data.add((TextData) op);
+ } else if (op instanceof TouchExpression) {
+ touchExpressions.add((TouchExpression) op);
+ } else if (op instanceof PaintData) {
+ paintData.add((PaintData) op);
} else {
// nothing
}
@@ -179,6 +190,8 @@ public class LayoutComponent extends Component {
mList.clear();
mList.addAll(data);
+ mList.addAll(touchExpressions);
+ mList.addAll(paintData);
mList.add(mComponentModifiers);
for (Component c : mChildrenComponents) {
c.mParent = this;
@@ -255,11 +268,24 @@ public class LayoutComponent extends Component {
}
@Override
+ public float getScrollX() {
+ return mComponentModifiers.getScrollX();
+ }
+
+ @Override
+ public float getScrollY() {
+ return mComponentModifiers.getScrollY();
+ }
+
+ @Override
public void paintingComponent(@NonNull PaintContext context) {
- Component prev = context.getContext().lastComponent;
- context.getContext().lastComponent = this;
+ Component prev = context.getContext().mLastComponent;
+ context.getContext().mLastComponent = this;
context.save();
context.translate(mX, mY);
+ if (context.isVisualDebug()) {
+ debugBox(this, context);
+ }
if (mGraphicsLayerModifier != null) {
context.startGraphicsLayer((int) getWidth(), (int) getHeight());
float scaleX = mGraphicsLayerModifier.getScaleX();
@@ -285,8 +311,8 @@ public class LayoutComponent extends Component {
renderEffectId);
}
mComponentModifiers.paint(context);
- float tx = mPaddingLeft;
- float ty = mPaddingTop;
+ float tx = mPaddingLeft + getScrollX();
+ float ty = mPaddingTop + getScrollY();
context.translate(tx, ty);
if (mChildrenHaveZIndex) {
// TODO -- should only sort when something has changed
@@ -305,7 +331,7 @@ public class LayoutComponent extends Component {
}
context.translate(-tx, -ty);
context.restore();
- context.getContext().lastComponent = prev;
+ context.getContext().mLastComponent = prev;
}
/** Traverse the modifiers to compute indicated dimension */
@@ -337,7 +363,7 @@ public class LayoutComponent extends Component {
* @param padding output start and end padding values
* @return padding width
*/
- public float computeModifierDefinedPaddingWidth(float[] padding) {
+ public float computeModifierDefinedPaddingWidth(@NonNull float[] padding) {
float s = 0f;
float e = 0f;
for (Operation c : mComponentModifiers.getList()) {
@@ -381,7 +407,7 @@ public class LayoutComponent extends Component {
* @param padding output top and bottom padding values
* @return padding height
*/
- public float computeModifierDefinedPaddingHeight(float[] padding) {
+ public float computeModifierDefinedPaddingHeight(@NonNull float[] padding) {
float t = 0f;
float b = 0f;
for (Operation c : mComponentModifiers.getList()) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
index 0a085b43401c..7eea885f6b6d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
@@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -35,7 +36,7 @@ public class LayoutComponentContent extends Component implements ComponentStartO
float y,
float width,
float height,
- Component parent,
+ @Nullable Component parent,
int animationId) {
super(parent, componentId, animationId, x, y, width, height);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
index c4df075bb9e8..df960e45736e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -59,8 +61,9 @@ public abstract class ListActionsOperation extends PaintOperation
}
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
index c90077b88782..71de2857258b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopEnd.java
@@ -16,7 +16,6 @@
package com.android.internal.widget.remotecompose.core.operations.layout;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -40,13 +39,13 @@ public class LoopEnd implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
// nothing
}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -63,7 +62,7 @@ public class LoopEnd implements Operation {
buffer.start(id());
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new LoopEnd());
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
index eeaeafd284c0..d88382dde7e0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
@@ -16,7 +16,6 @@
package com.android.internal.widget.remotecompose.core.operations.layout;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -70,7 +69,7 @@ public class LoopOperation extends PaintOperation {
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
index bd8d1f0ba9dd..ca79003448e7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/OperationsListEnd.java
@@ -16,7 +16,6 @@
package com.android.internal.widget.remotecompose.core.operations.layout;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -40,13 +39,13 @@ public class OperationsListEnd implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
// nothing
}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@@ -63,7 +62,7 @@ public class OperationsListEnd implements Operation {
buffer.start(id());
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new OperationsListEnd());
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
index 524ae59e70ec..85c71537540c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -45,13 +46,18 @@ public class RootLayoutComponent extends Component implements ComponentStartOper
float y,
float width,
float height,
- Component parent,
+ @Nullable Component parent,
int animationId) {
super(parent, componentId, animationId, x, y, width, height);
}
public RootLayoutComponent(
- int componentId, float x, float y, float width, float height, Component parent) {
+ int componentId,
+ float x,
+ float y,
+ float width,
+ float height,
+ @Nullable Component parent) {
super(parent, componentId, -1, x, y, width, height);
}
@@ -130,7 +136,7 @@ public class RootLayoutComponent extends Component implements ComponentStartOper
if (!mNeedsMeasure) {
return;
}
- context.lastComponent = this;
+ context.mLastComponent = this;
mWidth = context.mWidth;
mHeight = context.mHeight;
@@ -149,7 +155,7 @@ public class RootLayoutComponent extends Component implements ComponentStartOper
@Override
public void paint(@NonNull PaintContext context) {
mNeedsRepaint = false;
- context.getContext().lastComponent = this;
+ context.getContext().mLastComponent = this;
context.save();
if (mParent == null) { // root layout
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
index 486efbd6e00f..0316f96bfc3e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchCancelModifierOperation.java
@@ -70,6 +70,12 @@ public class TouchCancelModifierOperation extends ListActionsOperation implement
applyActions(context, document, component, x, y, true);
}
+ @Override
+ public void onTouchDrag(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
public static String name() {
return "TouchCancelModifier";
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java
index 5d379fe01d61..d98911f82060 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchDownModifierOperation.java
@@ -72,6 +72,12 @@ public class TouchDownModifierOperation extends ListActionsOperation implements
// nothing
}
+ @Override
+ public void onTouchDrag(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
public static String name() {
return "TouchModifier";
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java
index 5adfc33b5ef5..ac9dd908d6a4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchHandler.java
@@ -46,6 +46,18 @@ public interface TouchHandler {
RemoteContext context, CoreDocument document, Component component, float x, float y);
/**
+ * callback for a touch move event
+ *
+ * @param context the current context
+ * @param document the current document
+ * @param component the component on which the touch has been received
+ * @param x the x position of the click in document coordinates
+ * @param y the y position of the click in document coordinates
+ */
+ void onTouchDrag(
+ RemoteContext context, CoreDocument document, Component component, float x, float y);
+
+ /**
* callback for a touch cancel event
*
* @param context the current context
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java
index 263cc43d5e74..f6cb3750906f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/TouchUpModifierOperation.java
@@ -70,6 +70,12 @@ public class TouchUpModifierOperation extends ListActionsOperation implements To
// nothing
}
+ @Override
+ public void onTouchDrag(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // nothing
+ }
+
public static String name() {
return "TouchUpModifier";
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
index 6036b74efad3..b3430998a520 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
@@ -33,40 +33,40 @@ import com.android.internal.widget.remotecompose.core.operations.utilities.easin
* <p>Handles position, size and visibility
*/
public class AnimateMeasure {
- long mStartTime = System.currentTimeMillis();
- Component mComponent;
- ComponentMeasure mOriginal;
- ComponentMeasure mTarget;
- int mDuration;
- int mDurationVisibilityChange = mDuration;
- AnimationSpec.ANIMATION mEnterAnimation = AnimationSpec.ANIMATION.FADE_IN;
- AnimationSpec.ANIMATION mExitAnimation = AnimationSpec.ANIMATION.FADE_OUT;
- int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
- int mVisibilityEasingType = GeneralEasing.CUBIC_ACCELERATE;
+ private long mStartTime = System.currentTimeMillis();
+ private final @NonNull Component mComponent;
+ private final @NonNull ComponentMeasure mOriginal;
+ private final @NonNull ComponentMeasure mTarget;
+ private int mDuration;
+ private int mDurationVisibilityChange = mDuration;
+ private @NonNull AnimationSpec.ANIMATION mEnterAnimation = AnimationSpec.ANIMATION.FADE_IN;
+ private @NonNull AnimationSpec.ANIMATION mExitAnimation = AnimationSpec.ANIMATION.FADE_OUT;
+ private int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
+ private int mVisibilityEasingType = GeneralEasing.CUBIC_ACCELERATE;
- float mP = 0f;
- float mVp = 0f;
+ private float mP = 0f;
+ private float mVp = 0f;
@NonNull
- FloatAnimation mMotionEasing =
+ private FloatAnimation mMotionEasing =
new FloatAnimation(mMotionEasingType, mDuration / 1000f, null, 0f, Float.NaN);
@NonNull
- FloatAnimation mVisibilityEasing =
+ private FloatAnimation mVisibilityEasing =
new FloatAnimation(
mVisibilityEasingType, mDurationVisibilityChange / 1000f, null, 0f, Float.NaN);
- ParticleAnimation mParticleAnimation;
+ private ParticleAnimation mParticleAnimation;
public AnimateMeasure(
long startTime,
@NonNull Component component,
- ComponentMeasure original,
+ @NonNull ComponentMeasure original,
@NonNull ComponentMeasure target,
int duration,
int durationVisibilityChange,
- AnimationSpec.ANIMATION enterAnimation,
- AnimationSpec.ANIMATION exitAnimation,
+ @NonNull AnimationSpec.ANIMATION enterAnimation,
+ @NonNull AnimationSpec.ANIMATION exitAnimation,
int motionEasingType,
int visibilityEasingType) {
this.mStartTime = startTime;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
index 47abadeb70fa..6fb705985711 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimationSpec.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.animati
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -36,8 +35,8 @@ public class AnimationSpec implements Operation {
int mMotionEasingType = GeneralEasing.CUBIC_STANDARD;
int mVisibilityDuration = 300;
int mVisibilityEasingType = GeneralEasing.CUBIC_STANDARD;
- ANIMATION mEnterAnimation = ANIMATION.FADE_IN;
- ANIMATION mExitAnimation = ANIMATION.FADE_OUT;
+ @NonNull ANIMATION mEnterAnimation = ANIMATION.FADE_IN;
+ @NonNull ANIMATION mExitAnimation = ANIMATION.FADE_OUT;
public AnimationSpec(
int animationId,
@@ -45,8 +44,8 @@ public class AnimationSpec implements Operation {
int motionEasingType,
int visibilityDuration,
int visibilityEasingType,
- ANIMATION enterAnimation,
- ANIMATION exitAnimation) {
+ @NonNull ANIMATION enterAnimation,
+ @NonNull ANIMATION exitAnimation) {
this.mAnimationId = animationId;
this.mMotionDuration = motionDuration;
this.mMotionEasingType = motionEasingType;
@@ -87,10 +86,12 @@ public class AnimationSpec implements Operation {
return mVisibilityEasingType;
}
+ @NonNull
public ANIMATION getEnterAnimation() {
return mEnterAnimation;
}
+ @NonNull
public ANIMATION getExitAnimation() {
return mExitAnimation;
}
@@ -126,13 +127,13 @@ public class AnimationSpec implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
// nothing here
}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
index 37d20781f4fa..64e2f004cb65 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/ParticleAnimation.java
@@ -34,7 +34,7 @@ public class ParticleAnimation {
@NonNull PaintContext context,
@NonNull Component component,
@NonNull ComponentMeasure start,
- ComponentMeasure end,
+ @NonNull ComponentMeasure end,
float progress) {
ArrayList<Particle> particles = mAllParticles.get(component.getComponentId());
if (particles == null) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
index f3e550903a65..47a942187900 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/BoxLayout.java
@@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout.manager
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -45,7 +46,7 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation
int mVerticalPositioning;
public BoxLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -60,7 +61,7 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation
}
public BoxLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
int horizontalPositioning,
@@ -104,7 +105,7 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation
@Override
public void computeWrapSize(
- PaintContext context,
+ @NonNull PaintContext context,
float maxWidth,
float maxHeight,
@NonNull MeasurePass measure,
@@ -122,7 +123,7 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation
@Override
public void computeSize(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
@@ -134,7 +135,7 @@ public class BoxLayout extends LayoutManager implements ComponentStartOperation
}
@Override
- public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
+ public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
index 12ff969530b3..476b1a666fe9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CanvasLayout.java
@@ -18,6 +18,7 @@ package com.android.internal.widget.remotecompose.core.operations.layout.manager
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -32,7 +33,7 @@ import java.util.List;
public class CanvasLayout extends BoxLayout {
public CanvasLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -42,7 +43,7 @@ public class CanvasLayout extends BoxLayout {
super(parent, componentId, animationId, x, y, width, height, 0, 0);
}
- public CanvasLayout(Component parent, int componentId, int animationId) {
+ public CanvasLayout(@Nullable Component parent, int componentId, int animationId) {
this(parent, componentId, animationId, 0, 0, 0, 0);
}
@@ -103,7 +104,7 @@ public class CanvasLayout extends BoxLayout {
}
@Override
- public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
+ public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
float selfWidth = selfMeasure.getW() - mPaddingLeft - mPaddingRight;
float selfHeight = selfMeasure.getH() - mPaddingTop - mPaddingBottom;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
index 52bf4c54faf6..68e18c699539 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
@@ -19,6 +19,7 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -53,7 +54,7 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
float mSpacedBy = 0f;
public ColumnLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -70,7 +71,7 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
}
public ColumnLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
int horizontalPositioning,
@@ -121,7 +122,7 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
@Override
public void computeWrapSize(
- PaintContext context,
+ @NonNull PaintContext context,
float maxWidth,
float maxHeight,
@NonNull MeasurePass measure,
@@ -145,7 +146,7 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
@Override
public void computeSize(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
@@ -164,7 +165,17 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
}
@Override
- public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
+ public float intrinsicHeight() {
+ float height = computeModifierDefinedHeight();
+ float componentHeights = 0f;
+ for (Component c : mChildrenComponents) {
+ componentHeights += c.intrinsicHeight();
+ }
+ return Math.max(height, componentHeights);
+ }
+
+ @Override
+ public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
DebugLog.s(
() ->
@@ -188,6 +199,16 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
float childrenWidth = 0f;
float childrenHeight = 0f;
+ if (mComponentModifiers.hasHorizontalScroll()) {
+ selfWidth =
+ mComponentModifiers.getHorizontalScrollDimension()
+ - mPaddingLeft
+ - mPaddingRight;
+ }
+ if (mComponentModifiers.hasVerticalScroll()) {
+ selfHeight =
+ mComponentModifiers.getVerticalScrollDimension() - mPaddingTop - mPaddingBottom;
+ }
boolean hasWeights = false;
float totalWeights = 0f;
for (Component child : mChildrenComponents) {
@@ -286,6 +307,7 @@ public class ColumnLayout extends LayoutManager implements ComponentStartOperati
ty = verticalGap / 2f;
break;
}
+
for (Component child : mChildrenComponents) {
ComponentMeasure childMeasure = measure.get(child);
switch (mHorizontalPositioning) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
index 0c4d24a4561a..3b5aaf38fb5b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
@@ -16,6 +16,7 @@
package com.android.internal.widget.remotecompose.core.operations.layout.managers;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -32,7 +33,7 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
@NonNull Size mCachedWrapSize = new Size(0f, 0f);
public LayoutManager(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -43,24 +44,46 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
}
/** Implemented by subclasses to provide a layout/measure pass */
- public void internalLayoutMeasure(PaintContext context, MeasurePass measure) {
+ public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
// nothing here
}
/** Subclasses can implement this to provide wrap sizing */
public void computeWrapSize(
- PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) {
+ @NonNull PaintContext context,
+ float maxWidth,
+ float maxHeight,
+ @NonNull MeasurePass measure,
+ @NonNull Size size) {
// nothing here
}
+ @Override
+ public float intrinsicHeight() {
+ float height = computeModifierDefinedHeight();
+ for (Component c : mChildrenComponents) {
+ height = Math.max(c.intrinsicHeight(), height);
+ }
+ return height;
+ }
+
+ @Override
+ public float intrinsicWidth() {
+ float width = computeModifierDefinedWidth();
+ for (Component c : mChildrenComponents) {
+ width = Math.max(c.intrinsicWidth(), width);
+ }
+ return width;
+ }
+
/** Subclasses can implement this when not in wrap sizing */
public void computeSize(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
// nothing here
}
@@ -99,7 +122,7 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
/** Base implementation of the measure resolution */
@Override
public void measure(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
@@ -112,7 +135,13 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
Math.min(maxHeight, computeModifierDefinedHeight() - mMarginTop - mMarginBottom);
float insetMaxWidth = maxWidth - mMarginLeft - mMarginRight;
float insetMaxHeight = maxHeight - mMarginTop - mMarginBottom;
- if (mWidthModifier.isWrap() || mHeightModifier.isWrap()) {
+ if (mWidthModifier.isIntrinsicMin()) {
+ maxWidth = intrinsicWidth();
+ }
+ if (mHeightModifier.isIntrinsicMin()) {
+ maxHeight = intrinsicHeight();
+ }
+ if (mWidthModifier.isWrap() || mHeightModifier.isWrap()) { // TODO: potential npe -- bbade@
mCachedWrapSize.setWidth(0f);
mCachedWrapSize.setHeight(0f);
computeWrapSize(context, maxWidth, maxHeight, measure, mCachedWrapSize);
@@ -129,7 +158,7 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
measuredWidth = Math.max(measuredWidth, minWidth);
measuredWidth = Math.min(measuredWidth, insetMaxWidth);
}
- if (isInVerticalFill()) {
+ if (isInVerticalFill()) { // todo: potential npe -- bbade@
measuredHeight = insetMaxHeight;
} else if (mHeightModifier.hasWeight()) {
measuredHeight = Math.max(measuredHeight, computeModifierDefinedHeight());
@@ -146,7 +175,23 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
measuredWidth = Math.min(measuredWidth, insetMaxWidth);
measuredHeight = Math.min(measuredHeight, insetMaxHeight);
if (!hasWrap) {
- computeSize(context, 0f, measuredWidth, 0f, measuredHeight, measure);
+ if (hasHorizontalScroll()) {
+ mCachedWrapSize.setWidth(0f);
+ mCachedWrapSize.setHeight(0f);
+ computeWrapSize(context, Float.MAX_VALUE, maxHeight, measure, mCachedWrapSize);
+ float w = mCachedWrapSize.getWidth();
+ computeSize(context, 0f, w, 0, measuredHeight, measure);
+ mComponentModifiers.setHorizontalScrollDimension(measuredWidth, w);
+ } else if (hasVerticalScroll()) {
+ mCachedWrapSize.setWidth(0f);
+ mCachedWrapSize.setHeight(0f);
+ computeWrapSize(context, maxWidth, Float.MAX_VALUE, measure, mCachedWrapSize);
+ float h = mCachedWrapSize.getHeight();
+ computeSize(context, 0f, measuredWidth, 0, h, measure);
+ mComponentModifiers.setVerticalScrollDimension(measuredHeight, h);
+ } else {
+ computeSize(context, 0f, measuredWidth, 0f, measuredHeight, measure);
+ }
}
if (mContent != null) {
@@ -168,6 +213,14 @@ public abstract class LayoutManager extends LayoutComponent implements Measurabl
internalLayoutMeasure(context, measure);
}
+ private boolean hasHorizontalScroll() {
+ return mComponentModifiers.hasHorizontalScroll();
+ }
+
+ private boolean hasVerticalScroll() {
+ return mComponentModifiers.hasVerticalScroll();
+ }
+
/** basic layout of internal components */
@Override
public void layout(@NonNull RemoteContext context, @NonNull MeasurePass measure) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
index a366dc804758..0ce634f9c1ab 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
@@ -19,6 +19,7 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -51,7 +52,7 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation
float mSpacedBy = 0f;
public RowLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -68,7 +69,7 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation
}
public RowLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
int horizontalPositioning,
@@ -119,7 +120,7 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation
@Override
public void computeWrapSize(
- PaintContext context,
+ @NonNull PaintContext context,
float maxWidth,
float maxHeight,
@NonNull MeasurePass measure,
@@ -143,7 +144,7 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation
@Override
public void computeSize(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
@@ -162,7 +163,17 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation
}
@Override
- public void internalLayoutMeasure(PaintContext context, @NonNull MeasurePass measure) {
+ public float intrinsicWidth() {
+ float width = computeModifierDefinedWidth();
+ float componentWidths = 0f;
+ for (Component c : mChildrenComponents) {
+ componentWidths += c.intrinsicWidth();
+ }
+ return Math.max(width, componentWidths);
+ }
+
+ @Override
+ public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
ComponentMeasure selfMeasure = measure.get(this);
DebugLog.s(
() ->
@@ -186,6 +197,17 @@ public class RowLayout extends LayoutManager implements ComponentStartOperation
float childrenWidth = 0f;
float childrenHeight = 0f;
+ if (mComponentModifiers.hasHorizontalScroll()) {
+ selfWidth =
+ mComponentModifiers.getHorizontalScrollDimension()
+ - mPaddingLeft
+ - mPaddingRight;
+ }
+ if (mComponentModifiers.hasVerticalScroll()) {
+ selfHeight =
+ mComponentModifiers.getVerticalScrollDimension() - mPaddingTop - mPaddingBottom;
+ }
+
boolean hasWeights = false;
float totalWeights = 0f;
for (Component child : mChildrenComponents) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
index e47ffdebb253..73a104bcafa6 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/StateLayout.java
@@ -16,6 +16,7 @@
package com.android.internal.widget.remotecompose.core.operations.layout.managers;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -60,7 +61,7 @@ public class StateLayout extends LayoutManager implements ComponentStartOperatio
public boolean inTransition = false;
public StateLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -132,21 +133,21 @@ public class StateLayout extends LayoutManager implements ComponentStartOperatio
@Override
public void computeSize(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
LayoutManager layout = getLayout(currentLayoutIndex);
layout.computeSize(context, minWidth, maxWidth, minHeight, maxHeight, measure);
}
@Override
public void internalLayoutMeasure(
- PaintContext context,
+ @NonNull PaintContext context,
// layoutInfo: LayoutInfo,
- MeasurePass measure) {
+ @NonNull MeasurePass measure) {
LayoutManager layout = getLayout(currentLayoutIndex);
// layout.internalLayoutMeasure(context, layoutInfo, measure)
layout.internalLayoutMeasure(context, measure);
@@ -155,13 +156,18 @@ public class StateLayout extends LayoutManager implements ComponentStartOperatio
/** Subclasses can implement this to provide wrap sizing */
@Override
public void computeWrapSize(
- PaintContext context, float maxWidth, float maxHeight, MeasurePass measure, Size size) {
+ @NonNull PaintContext context,
+ float maxWidth,
+ float maxHeight,
+ @NonNull MeasurePass measure,
+ @NonNull Size size) {
LayoutManager layout = getLayout(currentLayoutIndex);
layout.computeWrapSize(context, maxWidth, maxHeight, measure, size);
}
@Override
- public void onClick(RemoteContext context, CoreDocument document, float x, float y) {
+ public void onClick(
+ @NonNull RemoteContext context, @NonNull CoreDocument document, float x, float y) {
if (!contains(x, y)) {
return;
}
@@ -352,7 +358,7 @@ public class StateLayout extends LayoutManager implements ComponentStartOperatio
}
}
- public LayoutManager getLayout(int idx) {
+ public @NonNull LayoutManager getLayout(int idx) {
int index = 0;
for (Component pane : mChildrenComponents) {
if (pane instanceof LayoutComponent) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
index 8aa7712635fc..a527e5ad4077 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
@@ -19,6 +19,7 @@ import static com.android.internal.widget.remotecompose.core.documentation.Docum
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -52,8 +53,9 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
private float mTextX;
private float mTextY;
private float mTextW;
+ private float mTextH;
- private String mCachedString = "";
+ @Nullable private String mCachedString = "";
@Override
public void registerListening(@NonNull RemoteContext context) {
@@ -89,7 +91,7 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
}
public TextLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
float x,
@@ -114,7 +116,7 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
}
public TextLayout(
- Component parent,
+ @Nullable Component parent,
int componentId,
int animationId,
int textId,
@@ -162,6 +164,9 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
mPaint.setTextSize(mFontSize);
mPaint.setTextStyle(mType, (int) mFontWeight, mFontStyle == 1);
context.applyPaint(mPaint);
+ if (mCachedString == null) {
+ return;
+ }
int length = mCachedString.length();
context.drawTextRun(mTextId, 0, length, 0, 0, mTextX, mTextY, false);
if (DEBUG) {
@@ -241,7 +246,7 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
@NonNull PaintContext context,
float maxWidth,
float maxHeight,
- MeasurePass measure,
+ @NonNull MeasurePass measure,
@NonNull Size size) {
context.savePaint();
mPaint.reset();
@@ -250,6 +255,9 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
context.applyPaint(mPaint);
float[] bounds = new float[4];
int flags = PaintContext.TEXT_MEASURE_FONT_HEIGHT;
+ if (mCachedString == null) {
+ return;
+ }
context.getTextBounds(mTextId, 0, mCachedString.length(), flags, bounds);
context.restorePaint();
float w = bounds[2] - bounds[0];
@@ -259,6 +267,17 @@ public class TextLayout extends LayoutManager implements ComponentStartOperation
size.setHeight(h);
mTextY = -bounds[1];
mTextW = w;
+ mTextH = h;
+ }
+
+ @Override
+ public float intrinsicHeight() {
+ return mTextH;
+ }
+
+ @Override
+ public float intrinsicWidth() {
+ return mTextW;
}
@NonNull
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
index 426e02337f5b..82f23cdcf766 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/ComponentMeasure.java
@@ -26,7 +26,7 @@ public class ComponentMeasure {
float mY;
float mW;
float mH;
- Component.Visibility mVisibility = Component.Visibility.VISIBLE;
+ @NonNull Component.Visibility mVisibility = Component.Visibility.VISIBLE;
public void setX(float value) {
mX = value;
@@ -60,16 +60,16 @@ public class ComponentMeasure {
return mH;
}
- public Component.Visibility getVisibility() {
+ public @NonNull Component.Visibility getVisibility() {
return mVisibility;
}
- public void setVisibility(Component.Visibility visibility) {
+ public void setVisibility(@NonNull Component.Visibility visibility) {
mVisibility = visibility;
}
public ComponentMeasure(
- int id, float x, float y, float w, float h, Component.Visibility visibility) {
+ int id, float x, float y, float w, float h, @NonNull Component.Visibility visibility) {
this.mId = id;
this.mX = x;
this.mY = y;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
index b48c2d5ae88b..fbf2784be843 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.measure;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.RemoteContext;
@@ -26,15 +28,15 @@ public interface Measurable {
* does not apply the measure to the component.
*/
void measure(
- PaintContext context,
+ @NonNull PaintContext context,
float minWidth,
float maxWidth,
float minHeight,
float maxHeight,
- MeasurePass measure);
+ @NonNull MeasurePass measure);
/** Apply a given measure to the component */
- void layout(RemoteContext context, MeasurePass measure);
+ void layout(@NonNull RemoteContext context, @NonNull MeasurePass measure);
/**
* Return true if the component needs to be remeasured
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
index 112ab1b93474..5cfb1b43cf15 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/MeasurePass.java
@@ -43,7 +43,7 @@ public class MeasurePass {
return mList.containsKey(id);
}
- public ComponentMeasure get(@NonNull Component c) {
+ public @NonNull ComponentMeasure get(@NonNull Component c) {
if (!mList.containsKey(c.getComponentId())) {
ComponentMeasure measure =
new ComponentMeasure(
@@ -54,7 +54,7 @@ public class MeasurePass {
return mList.get(c.getComponentId());
}
- public ComponentMeasure get(int id) {
+ public @NonNull ComponentMeasure get(int id) {
if (!mList.containsKey(id)) {
ComponentMeasure measure =
new ComponentMeasure(id, 0f, 0f, 0f, 0f, Component.Visibility.GONE);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
index 76a97ca0eb51..71d2ba6edf21 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BackgroundModifierOperation.java
@@ -98,7 +98,7 @@ public class BackgroundModifierOperation extends DecoratorModifierOperation {
}
@Override
- public void layout(RemoteContext context, float width, float height) {
+ public void layout(@NonNull RemoteContext context, float width, float height) {
this.mWidth = width;
this.mHeight = height;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
index d48a9c732cd5..0707cd627678 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/BorderModifierOperation.java
@@ -124,7 +124,7 @@ public class BorderModifierOperation extends DecoratorModifierOperation {
}
@Override
- public void layout(RemoteContext context, float width, float height) {
+ public void layout(@NonNull RemoteContext context, float width, float height) {
this.mWidth = width;
this.mHeight = height;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
index 78b51c3f83aa..e05b02781e10 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ClipRectModifierOperation.java
@@ -40,7 +40,7 @@ public class ClipRectModifierOperation extends DecoratorModifierOperation {
}
@Override
- public void layout(RemoteContext context, float width, float height) {
+ public void layout(@NonNull RemoteContext context, float width, float height) {
this.mWidth = width;
this.mHeight = height;
}
@@ -68,7 +68,7 @@ public class ClipRectModifierOperation extends DecoratorModifierOperation {
buffer.start(OP_CODE);
}
- public static void read(WireBuffer buffer, @NonNull List<Operation> operations) {
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
operations.add(new ClipRectModifierOperation());
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
index 011d7edd18c8..d11f26f83ebd 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
@@ -62,7 +62,7 @@ public class ComponentModifiers extends PaintOperation
}
@Override
- public void write(WireBuffer buffer) {
+ public void write(@NonNull WireBuffer buffer) {
// nothing
}
@@ -73,7 +73,7 @@ public class ComponentModifiers extends PaintOperation
}
}
- public void add(ModifierOperation operation) {
+ public void add(@NonNull ModifierOperation operation) {
mList.add(operation);
}
@@ -109,7 +109,7 @@ public class ComponentModifiers extends PaintOperation
}
@Override
- public void layout(RemoteContext context, float width, float height) {
+ public void layout(@NonNull RemoteContext context, float width, float height) {
float w = width;
float h = height;
for (ModifierOperation op : mList) {
@@ -126,13 +126,17 @@ public class ComponentModifiers extends PaintOperation
}
}
- public void addAll(ArrayList<ModifierOperation> operations) {
+ public void addAll(@NonNull ArrayList<ModifierOperation> operations) {
mList.addAll(operations);
}
@Override
public void onClick(
- RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ @NonNull RemoteContext context,
+ @NonNull CoreDocument document,
+ @NonNull Component component,
+ float x,
+ float y) {
for (ModifierOperation op : mList) {
if (op instanceof ClickHandler) {
((ClickHandler) op).onClick(context, document, component, x, y);
@@ -169,4 +173,110 @@ public class ComponentModifiers extends PaintOperation
}
}
}
+
+ @Override
+ public void onTouchDrag(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof TouchHandler) {
+ ((TouchHandler) op).onTouchDrag(context, document, component, x, y);
+ }
+ }
+ }
+
+ public boolean hasHorizontalScroll() {
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isHorizontalScroll()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean hasVerticalScroll() {
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isVerticalScroll()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public float getScrollX() {
+ float scroll = 0;
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isHorizontalScroll()) {
+ scroll = Math.min(scroll, scrollModifier.getScrollX());
+ }
+ }
+ }
+ return scroll;
+ }
+
+ public float getScrollY() {
+ float scroll = 0;
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isVerticalScroll()) {
+ scroll = Math.min(scroll, scrollModifier.getScrollY());
+ }
+ }
+ }
+ return scroll;
+ }
+
+ public void setHorizontalScrollDimension(float hostDimension, float contentDimension) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isHorizontalScroll()) {
+ scrollModifier.setHorizontalScrollDimension(hostDimension, contentDimension);
+ }
+ }
+ }
+ }
+
+ public void setVerticalScrollDimension(float hostDimension, float contentDimension) {
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isVerticalScroll()) {
+ scrollModifier.setVerticalScrollDimension(hostDimension, contentDimension);
+ }
+ }
+ }
+ }
+
+ public float getHorizontalScrollDimension() {
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isHorizontalScroll()) {
+ return scrollModifier.getContentDimension();
+ }
+ }
+ }
+ return 0f;
+ }
+
+ public float getVerticalScrollDimension() {
+ for (ModifierOperation op : mList) {
+ if (op instanceof ScrollModifierOperation) {
+ ScrollModifierOperation scrollModifier = (ScrollModifierOperation) op;
+ if (scrollModifier.isVerticalScroll()) {
+ return scrollModifier.getContentDimension();
+ }
+ }
+ }
+ return 0f;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
index 26e737b32027..471db0bedb11 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentVisibilityOperation.java
@@ -63,16 +63,16 @@ public class ComponentVisibilityOperation
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void write(WireBuffer buffer) {}
+ public void write(@NonNull WireBuffer buffer) {}
public static void apply(@NonNull WireBuffer buffer, int valueId) {
buffer.start(OP_CODE);
@@ -114,10 +114,10 @@ public class ComponentVisibilityOperation
}
}
- public void setParent(LayoutComponent parent) {
+ public void setParent(@Nullable LayoutComponent parent) {
mParent = parent;
}
@Override
- public void layout(RemoteContext context, float width, float height) {}
+ public void layout(@NonNull RemoteContext context, float width, float height) {}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
index 3c2d85cfee5b..b9324f0320d3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/DimensionModifierOperation.java
@@ -16,7 +16,6 @@
package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.VariableSupport;
@@ -57,16 +56,16 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V
}
}
- Type mType = Type.EXACT;
+ @NonNull Type mType = Type.EXACT;
float mValue = Float.NaN;
float mOutValue = Float.NaN;
- public DimensionModifierOperation(Type type, float value) {
+ public DimensionModifierOperation(@NonNull Type type, float value) {
mType = type;
mOutValue = mValue = value;
}
- public DimensionModifierOperation(Type type) {
+ public DimensionModifierOperation(@NonNull Type type) {
this(type, Float.NaN);
}
@@ -115,7 +114,15 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V
return mType == Type.FILL;
}
- public Type getType() {
+ public boolean isIntrinsicMin() {
+ return mType == Type.INTRINSIC_MIN;
+ }
+
+ public boolean isIntrinsicMax() {
+ return mType == Type.INTRINSIC_MAX;
+ }
+
+ public @NonNull Type getType() {
return mType;
}
@@ -143,11 +150,11 @@ public abstract class DimensionModifierOperation implements ModifierOperation, V
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
index 2b3038281d57..571e554b9c71 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/GraphicsLayerModifierOperation.java
@@ -18,6 +18,8 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -175,8 +177,9 @@ public class GraphicsLayerModifierOperation extends DecoratorModifierOperation {
serializer.append(indent, "GRAPHICS_LAYER = [" + mScaleX + ", " + mScaleY + "]");
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
index 97c76c0aedf7..7bb4a756afa5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HeightModifierOperation.java
@@ -59,11 +59,11 @@ public class HeightModifierOperation extends DimensionModifierOperation {
apply(buffer, mType.ordinal(), mValue);
}
- public HeightModifierOperation(Type type, float value) {
+ public HeightModifierOperation(@NonNull Type type, float value) {
super(type, value);
}
- public HeightModifierOperation(Type type) {
+ public HeightModifierOperation(@NonNull Type type) {
super(type);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
index 836321fff8e6..d239bc857446 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostActionOperation.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -63,22 +62,22 @@ public class HostActionOperation implements ActionOperation {
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void write(WireBuffer buffer) {}
+ public void write(@NonNull WireBuffer buffer) {}
@Override
public void runAction(
@NonNull RemoteContext context,
- CoreDocument document,
- Component component,
+ @NonNull CoreDocument document,
+ @NonNull Component component,
float x,
float y) {
context.runAction(mActionId, "");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
index e97e89784a23..3268e5efd449 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/HostNamedActionOperation.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -39,6 +38,7 @@ public class HostNamedActionOperation implements ActionOperation {
public static final int FLOAT_TYPE = 0;
public static final int INT_TYPE = 1;
public static final int STRING_TYPE = 2;
+ public static final int FLOAT_ARRAY_TYPE = 3;
public static final int NONE_TYPE = -1;
int mTextId = -1;
@@ -72,22 +72,22 @@ public class HostNamedActionOperation implements ActionOperation {
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void write(WireBuffer buffer) {}
+ public void write(@NonNull WireBuffer buffer) {}
@Override
public void runAction(
@NonNull RemoteContext context,
- CoreDocument document,
- Component component,
+ @NonNull CoreDocument document,
+ @NonNull Component component,
float x,
float y) {
Object value = null;
@@ -98,6 +98,8 @@ public class HostNamedActionOperation implements ActionOperation {
value = context.mRemoteComposeState.getFromId(mValueId);
} else if (mType == FLOAT_TYPE) {
value = context.mRemoteComposeState.getFloat(mValueId);
+ } else if (mType == FLOAT_ARRAY_TYPE) {
+ value = context.mRemoteComposeState.getFloats(mValueId);
}
}
context.runNamedAction(mTextId, value);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
index 50f098e25f6a..8f08f1417add 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ModifierOperation.java
@@ -15,10 +15,12 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
/** Represents a modifier */
public interface ModifierOperation extends Operation {
- void serializeToString(int indent, StringSerializer serializer);
+ void serializeToString(int indent, @NonNull StringSerializer serializer);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
index 65fe345ac920..8c07059369ab 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/OffsetModifierOperation.java
@@ -17,6 +17,8 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -67,8 +69,9 @@ public class OffsetModifierOperation extends DecoratorModifierOperation {
serializer.append(indent, "OFFSET = [" + mX + ", " + mY + "]");
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
index ed5522ea865f..2b6621e4fd58 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/PaddingModifierOperation.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -92,11 +91,11 @@ public class PaddingModifierOperation implements ModifierOperation {
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
index 6218dd5f3311..3fefc5817270 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/RoundedClipRectModifierOperation.java
@@ -96,7 +96,7 @@ public class RoundedClipRectModifierOperation extends DrawBase4
}
@Override
- public void layout(RemoteContext context, float width, float height) {
+ public void layout(@NonNull RemoteContext context, float width, float height) {
this.mWidth = width;
this.mHeight = height;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
new file mode 100644
index 000000000000..8dcfed999c5c
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.TouchHandler;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/** Represents a scroll modifier. */
+public class ScrollModifierOperation extends DecoratorModifierOperation implements TouchHandler {
+ private static final int OP_CODE = Operations.MODIFIER_SCROLL;
+ public static final String CLASS_NAME = "ScrollModifierOperation";
+
+ private final float mPositionExpression;
+ private final float mMax;
+ private final float mNotchMax;
+
+ float mWidth = 0;
+ float mHeight = 0;
+
+ int mDirection;
+
+ float mTouchDownX;
+ float mTouchDownY;
+
+ float mInitialScrollX;
+ float mInitialScrollY;
+
+ float mScrollX;
+ float mScrollY;
+
+ float mMaxScrollX;
+ float mMaxScrollY;
+
+ float mHostDimension;
+ float mContentDimension;
+
+ public ScrollModifierOperation(int direction, float position, float max, float notchMax) {
+ this.mDirection = direction;
+ this.mPositionExpression = position;
+ this.mMax = max;
+ this.mNotchMax = notchMax;
+ }
+
+ public boolean isVerticalScroll() {
+ return mDirection == 0;
+ }
+
+ public boolean isHorizontalScroll() {
+ return mDirection != 0;
+ }
+
+ public float getScrollX() {
+ return mScrollX;
+ }
+
+ public float getScrollY() {
+ return mScrollY;
+ }
+
+ @Override
+ public void apply(RemoteContext context) {
+ RootLayoutComponent root = context.getDocument().getRootLayoutComponent();
+ if (root != null) {
+ root.setHasTouchListeners(true);
+ }
+ super.apply(context);
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {
+ apply(buffer, mDirection, mPositionExpression, mMax, mNotchMax);
+ }
+
+ // @Override
+ public void serializeToString(int indent, StringSerializer serializer) {
+ serializer.append(indent, "SCROLL = [" + mDirection + "]");
+ }
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(PaintContext context) {
+ float position =
+ context.getContext()
+ .mRemoteComposeState
+ .getFloat(Utils.idFromNan(mPositionExpression));
+
+ if (mDirection == 0) {
+ mScrollY = -position;
+ } else {
+ mScrollX = -position;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ScrollModifierOperation(" + mDirection + ")";
+ }
+
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ public static int id() {
+ return OP_CODE;
+ }
+
+ public static void apply(
+ WireBuffer buffer, int direction, float position, float max, float notchMax) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(direction);
+ buffer.writeFloat(position);
+ buffer.writeFloat(max);
+ buffer.writeFloat(notchMax);
+ }
+
+ public static void read(WireBuffer buffer, List<Operation> operations) {
+ int direction = buffer.readInt();
+ float position = buffer.readFloat();
+ float max = buffer.readFloat();
+ float notchMax = buffer.readFloat();
+ operations.add(new ScrollModifierOperation(direction, position, max, notchMax));
+ }
+
+ public static void documentation(DocumentationBuilder doc) {
+ doc.operation("Modifier Operations", OP_CODE, CLASS_NAME)
+ .description("define a Scroll Modifier")
+ .field(INT, "direction", "");
+ }
+
+ @Override
+ public void layout(RemoteContext context, float width, float height) {
+ mWidth = width;
+ mHeight = height;
+ if (mDirection == 0) { // VERTICAL
+ context.loadFloat(Utils.idFromNan(mMax), mMaxScrollY);
+ context.loadFloat(Utils.idFromNan(mNotchMax), mContentDimension);
+ } else {
+ context.loadFloat(Utils.idFromNan(mMax), mMaxScrollX);
+ context.loadFloat(Utils.idFromNan(mNotchMax), mContentDimension);
+ }
+ }
+
+ @Override
+ public void onTouchDown(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ mTouchDownX = x;
+ mTouchDownY = y;
+ mInitialScrollX = mScrollX;
+ mInitialScrollY = mScrollY;
+ document.appliedTouchOperation(component);
+ }
+
+ @Override
+ public void onTouchUp(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ // If not using touch expression, should add velocity decay here
+ }
+
+ @Override
+ public void onTouchDrag(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {
+ float dx = x - mTouchDownX;
+ float dy = y - mTouchDownY;
+
+ if (!Utils.isVariable(mPositionExpression)) {
+ if (mDirection == 0) {
+ mScrollY = Math.max(-mMaxScrollY, Math.min(0, mInitialScrollY + dy));
+ } else {
+ mScrollX = Math.max(-mMaxScrollX, Math.min(0, mInitialScrollX + dx));
+ }
+ }
+ }
+
+ @Override
+ public void onTouchCancel(
+ RemoteContext context, CoreDocument document, Component component, float x, float y) {}
+
+ public void setHorizontalScrollDimension(float hostDimension, float contentDimension) {
+ mHostDimension = hostDimension;
+ mContentDimension = contentDimension;
+ mMaxScrollX = contentDimension - hostDimension;
+ }
+
+ public void setVerticalScrollDimension(float hostDimension, float contentDimension) {
+ mHostDimension = hostDimension;
+ mContentDimension = contentDimension;
+ mMaxScrollY = contentDimension - hostDimension;
+ }
+
+ public float getContentDimension() {
+ return mContentDimension;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
index 29ec82810a7c..a97fcffdf75c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatChangeActionOperation.java
@@ -18,6 +18,8 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
@@ -59,8 +61,9 @@ public class ValueFloatChangeActionOperation implements ActionOperation {
@Override
public void apply(RemoteContext context) {}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java
new file mode 100644
index 000000000000..41586b4939a6
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueFloatExpressionChangeActionOperation.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.operations.layout.ActionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+
+import java.util.List;
+
+/** Apply a value change on an integer variable. */
+public class ValueFloatExpressionChangeActionOperation implements ActionOperation {
+ private static final int OP_CODE = Operations.VALUE_FLOAT_EXPRESSION_CHANGE_ACTION;
+
+ int mTargetValueId = -1;
+ int mValueExpressionId = -1;
+
+ public ValueFloatExpressionChangeActionOperation(int id, int valueId) {
+ mTargetValueId = id;
+ mValueExpressionId = valueId;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "ValueFloatExpressionChangeActionOperation(" + mTargetValueId + ")";
+ }
+
+ @NonNull
+ public String serializedName() {
+ return "VALUE_FLOAT_EXPRESSION_CHANGE";
+ }
+
+ @Override
+ public void serializeToString(int indent, @NonNull StringSerializer serializer) {
+ serializer.append(
+ indent, serializedName() + " = " + mTargetValueId + " -> " + mValueExpressionId);
+ }
+
+ @Override
+ public void apply(RemoteContext context) {}
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void write(WireBuffer buffer) {}
+
+ @Override
+ public void runAction(
+ @NonNull RemoteContext context,
+ @NonNull CoreDocument document,
+ Component component,
+ float x,
+ float y) {
+ document.evaluateFloatExpression(mValueExpressionId, mTargetValueId, context);
+ }
+
+ public static void apply(@NonNull WireBuffer buffer, int valueId, int value) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(valueId);
+ buffer.writeInt(value);
+ }
+
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+ int valueId = buffer.readInt();
+ int value = buffer.readInt();
+ operations.add(new ValueFloatExpressionChangeActionOperation(valueId, value));
+ }
+
+ public static void documentation(@NonNull DocumentationBuilder doc) {
+ doc.operation("Layout Operations", OP_CODE, "ValueIntegerExpressionChangeActionOperation")
+ .description(
+ "ValueIntegerExpressionChange action. "
+ + " This operation represents a value change for the given id")
+ .field(INT, "TARGET_VALUE_ID", "Value ID")
+ .field(INT, "VALUE_ID", "id of the value to be assigned to the target");
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
index d7ce8acc72bf..c2cd2ab32bb7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerChangeActionOperation.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -61,22 +60,22 @@ public class ValueIntegerChangeActionOperation implements ActionOperation {
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void write(WireBuffer buffer) {}
+ public void write(@NonNull WireBuffer buffer) {}
@Override
public void runAction(
@NonNull RemoteContext context,
- CoreDocument document,
- Component component,
+ @NonNull CoreDocument document,
+ @NonNull Component component,
float x,
float y) {
context.overrideInteger(mTargetValueId, mValue);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
index 75d13e785d4c..43fbb8546b9d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueIntegerExpressionChangeActionOperation.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -62,22 +61,22 @@ public class ValueIntegerExpressionChangeActionOperation implements ActionOperat
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void write(WireBuffer buffer) {}
+ public void write(@NonNull WireBuffer buffer) {}
@Override
public void runAction(
@NonNull RemoteContext context,
@NonNull CoreDocument document,
- Component component,
+ @NonNull Component component,
float x,
float y) {
document.evaluateIntExpression(mValueExpressionId, (int) mTargetValueId, context);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
index 26d7244eee8c..1107889faaab 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ValueStringChangeActionOperation.java
@@ -18,7 +18,6 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.Operation;
@@ -65,22 +64,22 @@ public class ValueStringChangeActionOperation implements ActionOperation {
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(@Nullable String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
@Override
- public void write(WireBuffer buffer) {}
+ public void write(@NonNull WireBuffer buffer) {}
@Override
public void runAction(
@NonNull RemoteContext context,
- CoreDocument document,
- Component component,
+ @NonNull CoreDocument document,
+ @NonNull Component component,
float x,
float y) {
context.overrideText(mTargetValueId, mValueId);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
index e2f899ce2b46..3c757a893a57 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/WidthModifierOperation.java
@@ -54,7 +54,7 @@ public class WidthModifierOperation extends DimensionModifierOperation {
operations.add(op);
}
- public WidthModifierOperation(Type type, float value) {
+ public WidthModifierOperation(@NonNull Type type, float value) {
super(type, value);
}
@@ -63,7 +63,7 @@ public class WidthModifierOperation extends DimensionModifierOperation {
apply(buffer, mType.ordinal(), mValue);
}
- public WidthModifierOperation(Type type) {
+ public WidthModifierOperation(@NonNull Type type) {
super(type);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
index aa20e0388d31..82c8f343565e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ZIndexModifierOperation.java
@@ -17,6 +17,8 @@ package com.android.internal.widget.remotecompose.core.operations.layout.modifie
import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT;
+import android.annotation.NonNull;
+
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.Operations;
import com.android.internal.widget.remotecompose.core.PaintContext;
@@ -57,8 +59,9 @@ public class ZIndexModifierOperation extends DecoratorModifierOperation {
serializer.append(indent, "ZINDEX = [" + mValue + "]");
}
+ @NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return (indent != null ? indent : "") + toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
index d8e49b0a9ccd..842c9c161aee 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
@@ -27,11 +27,11 @@ public class DebugLog {
public static class Node {
@Nullable public Node parent;
- public String name;
- public String endString;
+ @NonNull public String name;
+ @NonNull public String endString;
@NonNull public ArrayList<Node> list = new ArrayList<>();
- public Node(@Nullable Node parent, String name) {
+ public Node(@Nullable Node parent, @NonNull String name) {
this.parent = parent;
this.name = name;
this.endString = name + " DONE";
@@ -40,13 +40,13 @@ public class DebugLog {
}
}
- public void add(Node node) {
+ public void add(@NonNull Node node) {
list.add(node);
}
}
public static class LogNode extends Node {
- public LogNode(Node parent, String name) {
+ public LogNode(@Nullable Node parent, @NonNull String name) {
super(parent, name);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java
index 701167abb8f0..5ec149390b84 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/StringValueSupplier.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.layout.utils;
+import android.annotation.NonNull;
+
/** Basic interface for a lambda (used for logging) */
public interface StringValueSupplier {
/**
@@ -22,5 +24,6 @@ public interface StringValueSupplier {
*
* @return a string
*/
+ @NonNull
String getString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
index e714947c6a5c..07cf7627e24d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintBundle.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.paint;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.VariableSupport;
@@ -25,8 +28,8 @@ import java.util.Arrays;
/** Paint Bundle represents a delta of changes to a paint object */
public class PaintBundle {
- int[] mArray = new int[200];
- int[] mOutArray = null;
+ @NonNull int[] mArray = new int[200];
+ @Nullable int[] mOutArray = null;
int mPos = 0;
/**
@@ -35,7 +38,7 @@ public class PaintBundle {
* @param paintContext
* @param p
*/
- public void applyPaintChange(PaintContext paintContext, PaintChanges p) {
+ public void applyPaintChange(@NonNull PaintContext paintContext, @NonNull PaintChanges p) {
int i = 0;
int mask = 0;
if (mOutArray == null) {
@@ -138,12 +141,14 @@ public class PaintBundle {
// return "????" + id + "????";
// }
+ @NonNull
private static String colorInt(int color) {
String str = "000000000000" + Integer.toHexString(color);
return "0x" + str.substring(str.length() - 8);
}
- private static String colorInt(int[] color) {
+ @NonNull
+ private static String colorInt(@NonNull int[] color) {
String str = "[";
for (int i = 0; i < color.length; i++) {
if (i > 0) {
@@ -162,6 +167,7 @@ public class PaintBundle {
return Float.toString(fValue);
}
+ @NonNull
@Override
public String toString() {
StringBuilder ret = new StringBuilder("\n");
@@ -244,7 +250,8 @@ public class PaintBundle {
return ret.toString();
}
- private void registerFloat(int iv, RemoteContext context, VariableSupport support) {
+ private void registerFloat(
+ int iv, @NonNull RemoteContext context, @NonNull VariableSupport support) {
float v = Float.intBitsToFloat(iv);
if (Float.isNaN(v)) {
context.listensTo(Utils.idFromNan(v), support);
@@ -252,7 +259,11 @@ public class PaintBundle {
}
int callRegisterGradient(
- int cmd, int[] array, int i, RemoteContext context, VariableSupport support) {
+ int cmd,
+ int[] array,
+ int i,
+ @NonNull RemoteContext context,
+ @NonNull VariableSupport support) {
int ret = i;
int type = (cmd >> 16);
int control = array[ret++];
@@ -343,7 +354,7 @@ public class PaintBundle {
return ret;
}
- int callPrintGradient(int cmd, int[] array, int i, StringBuilder p) {
+ int callPrintGradient(int cmd, int[] array, int i, @NonNull StringBuilder p) {
int ret = i;
int type = (cmd >> 16);
int tileMode = 0;
@@ -432,7 +443,7 @@ public class PaintBundle {
return ret;
}
- int callSetGradient(int cmd, int[] array, int i, PaintChanges p) {
+ int callSetGradient(int cmd, @NonNull int[] array, int i, @NonNull PaintChanges p) {
int ret = i;
int gradientType = (cmd >> 16);
@@ -487,14 +498,14 @@ public class PaintBundle {
return ret;
}
- public void writeBundle(WireBuffer buffer) {
+ public void writeBundle(@NonNull WireBuffer buffer) {
buffer.writeInt(mPos);
for (int index = 0; index < mPos; index++) {
buffer.writeInt(mArray[index]);
}
}
- public void readBundle(WireBuffer buffer) {
+ public void readBundle(@NonNull WireBuffer buffer) {
int len = buffer.readInt();
if (len <= 0 || len > 1024) {
throw new RuntimeException("buffer corrupt paint len = " + len);
@@ -589,9 +600,9 @@ public class PaintBundle {
* @param tileMode The Shader tiling mode
*/
public void setLinearGradient(
- int[] colors,
+ @NonNull int[] colors,
int idMask,
- float[] stops,
+ @Nullable float[] stops,
float startX,
float startY,
float endX,
@@ -600,7 +611,7 @@ public class PaintBundle {
// int startPos = mPos;
int len;
mArray[mPos++] = GRADIENT | (LINEAR_GRADIENT << 16);
- mArray[mPos++] = (idMask << 16) | (len = (colors == null) ? 0 : colors.length);
+ mArray[mPos++] = (idMask << 16) | (len = colors.length);
for (int i = 0; i < len; i++) {
mArray[mPos++] = colors[i];
}
@@ -629,7 +640,12 @@ public class PaintBundle {
* spaced evenly.
*/
public void setSweepGradient(
- int[] colors, int idMask, float[] stops, float centerX, float centerY) {
+ @NonNull int[] colors,
+ int idMask,
+ @Nullable float[] stops, // TODO: rename positions to stops or stops to positions, but
+ // don't have both in the same file
+ float centerX,
+ float centerY) {
int len;
mArray[mPos++] = GRADIENT | (SWEEP_GRADIENT << 16);
mArray[mPos++] = (idMask << 16) | (len = (colors == null) ? 0 : colors.length);
@@ -659,9 +675,9 @@ public class PaintBundle {
* @param tileMode The Shader tiling mode
*/
public void setRadialGradient(
- int[] colors,
+ @NonNull int[] colors,
int idMask,
- float[] stops,
+ @Nullable float[] stops,
float centerX,
float centerY,
float radius,
@@ -900,7 +916,7 @@ public class PaintBundle {
mPos = 0;
}
- public static String blendModeString(int mode) {
+ public static @NonNull String blendModeString(int mode) {
switch (mode) {
case PaintBundle.BLEND_MODE_CLEAR:
return "CLEAR";
@@ -974,7 +990,7 @@ public class PaintBundle {
* @param context
* @param support
*/
- public void registerVars(RemoteContext context, VariableSupport support) {
+ public void registerVars(@NonNull RemoteContext context, @NonNull VariableSupport support) {
int i = 0;
while (i < mPos) {
int cmd = mArray[i++];
@@ -1020,7 +1036,7 @@ public class PaintBundle {
*
* @param context
*/
- public void updateVariables(RemoteContext context) {
+ public void updateVariables(@NonNull RemoteContext context) {
if (mOutArray == null) {
mOutArray = Arrays.copyOf(mArray, mArray.length);
} else {
@@ -1066,7 +1082,7 @@ public class PaintBundle {
}
}
- private int fixFloatVar(int val, RemoteContext context) {
+ private int fixFloatVar(int val, @NonNull RemoteContext context) {
float v = Float.intBitsToFloat(val);
if (Float.isNaN(v)) {
int id = Utils.idFromNan(v);
@@ -1075,12 +1091,13 @@ public class PaintBundle {
return val;
}
- private int fixColor(int colorId, RemoteContext context) {
+ private int fixColor(int colorId, @NonNull RemoteContext context) {
int n = context.getColor(colorId);
return n;
}
- int updateFloatsInGradient(int cmd, int[] out, int[] array, int i, RemoteContext context) {
+ int updateFloatsInGradient(
+ int cmd, int[] out, int[] array, int i, @NonNull RemoteContext context) {
int ret = i;
int type = (cmd >> 16);
int control = array[ret++];
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java
index e2402be4e4d4..87a663266e0e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChangeAdapter.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.paint;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
public class PaintChangeAdapter implements PaintChanges {
@Override
@@ -64,8 +67,8 @@ public class PaintChangeAdapter implements PaintChanges {
@Override
public void setLinearGradient(
- int[] colorsArray,
- float[] stopsArray,
+ @NonNull int[] colorsArray,
+ @Nullable float[] stopsArray,
float startX,
float startY,
float endX,
@@ -74,8 +77,8 @@ public class PaintChangeAdapter implements PaintChanges {
@Override
public void setRadialGradient(
- int[] colorsArray,
- float[] stopsArray,
+ @NonNull int[] colorsArray,
+ @Nullable float[] stopsArray,
float centerX,
float centerY,
float radius,
@@ -83,7 +86,10 @@ public class PaintChangeAdapter implements PaintChanges {
@Override
public void setSweepGradient(
- int[] colorsArray, float[] stopsArray, float centerX, float centerY) {}
+ @NonNull int[] colorsArray,
+ @Nullable float[] stopsArray,
+ float centerX,
+ float centerY) {}
@Override
public void setColorFilter(int color, int mode) {}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java
index 486d763cb6d5..e68164716a44 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/PaintChanges.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.paint;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
/** Interface to a paint object For more details see Android Paint */
public interface PaintChanges {
@@ -135,7 +138,7 @@ public interface PaintChanges {
* Set a linear gradient fill
*
* @param colorsArray
- * @param stopsArray
+ * @param stopsArray // todo: standardize naming
* @param startX
* @param startY
* @param endX
@@ -143,8 +146,8 @@ public interface PaintChanges {
* @param tileMode
*/
void setLinearGradient(
- int[] colorsArray,
- float[] stopsArray,
+ @NonNull int[] colorsArray,
+ @Nullable float[] stopsArray,
float startX,
float startY,
float endX,
@@ -155,15 +158,15 @@ public interface PaintChanges {
* Set a radial gradient fill
*
* @param colorsArray
- * @param stopsArray
+ * @param stopsArray // todo: standardize naming
* @param centerX
* @param centerY
* @param radius
* @param tileMode
*/
void setRadialGradient(
- int[] colorsArray,
- float[] stopsArray,
+ @NonNull int[] colorsArray,
+ @Nullable float[] stopsArray,
float centerX,
float centerY,
float radius,
@@ -173,11 +176,12 @@ public interface PaintChanges {
* Set a sweep gradient fill
*
* @param colorsArray
- * @param stopsArray
+ * @param stopsArray // todo: standardize naming to either "positions" or "stops"
* @param centerX
* @param centerY
*/
- void setSweepGradient(int[] colorsArray, float[] stopsArray, float centerX, float centerY);
+ void setSweepGradient(
+ @NonNull int[] colorsArray, @Nullable float[] stopsArray, float centerX, float centerY);
/**
* Set Color filter mod
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java
index a808cf0e17b3..e5f6f2838d34 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/Painter.java
@@ -16,6 +16,7 @@
package com.android.internal.widget.remotecompose.core.operations.paint;
import android.annotation.NonNull;
+import android.annotation.Nullable;
/** Provides a Builder pattern for a PaintBundle */
class Painter {
@@ -173,8 +174,8 @@ class Painter {
float centerX,
float centerY,
float radius,
- int[] colors,
- float[] positions,
+ @NonNull int[] colors,
+ @NonNull float[] positions,
int tileMode) {
mPaint.setRadialGradient(colors, 0, positions, centerX, centerY, radius, tileMode);
return this;
@@ -193,7 +194,8 @@ class Painter {
* spaced evenly.
*/
@NonNull
- public Painter setSweepGradient(float centerX, float centerY, int[] colors, float[] positions) {
+ public Painter setSweepGradient(
+ float centerX, float centerY, @NonNull int[] colors, @Nullable float[] positions) {
mPaint.setSweepGradient(colors, 0, positions, centerX, centerY);
return this;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/TextPaint.java b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/TextPaint.java
index 1c0bec76bb62..ff6f45db5385 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/paint/TextPaint.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/paint/TextPaint.java
@@ -15,6 +15,9 @@
*/
package com.android.internal.widget.remotecompose.core.operations.paint;
+import android.annotation.NonNull;
+
+// TODO: this interface is unused. Delete it.
public interface TextPaint {
void setARGB(int a, int r, int g, int b);
@@ -28,7 +31,7 @@ public interface TextPaint {
void setFlags(int flags);
- void setFontFeatureSettings(String settings);
+ void setFontFeatureSettings(@NonNull String settings);
void setHinting(int mode);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
index b25f4cd3c530..e5633c70faee 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
@@ -18,6 +18,9 @@ package com.android.internal.widget.remotecompose.core.operations.utilities;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+import com.android.internal.widget.remotecompose.core.operations.utilities.easing.MonotonicSpline;
+
/** high performance floating point expression evaluator used in animation */
public class AnimatedFloatExpression {
@NonNull static IntMap<String> sNames = new IntMap<>();
@@ -64,20 +67,37 @@ public class AnimatedFloatExpression {
public static final float A_SUM = asNan(OFFSET + 35);
public static final float A_AVG = asNan(OFFSET + 36);
public static final float A_LEN = asNan(OFFSET + 37);
- public static final int LAST_OP = OFFSET + 37;
+ public static final float A_SPLINE = asNan(OFFSET + 38);
+
+ public static final int LAST_OP = OFFSET + 38;
- public static final float VAR1 = asNan(OFFSET + 38);
- public static final float VAR2 = asNan(OFFSET + 39);
+ public static final float VAR1 = asNan(OFFSET + 39);
+ public static final float VAR2 = asNan(OFFSET + 40);
// TODO CLAMP, CBRT, DEG, RAD, EXPM1, CEIL, FLOOR
// private static final float FP_PI = (float) Math.PI;
private static final float FP_TO_RAD = 57.29578f; // 180/PI
private static final float FP_TO_DEG = 0.017453292f; // 180/PI
- float[] mStack;
+ @NonNull float[] mStack = new float[0];
@NonNull float[] mLocalStack = new float[128];
- float[] mVar;
- CollectionsAccess mCollectionsAccess;
+ @NonNull float[] mVar = new float[0];
+ @Nullable CollectionsAccess mCollectionsAccess;
+ IntMap<MonotonicSpline> mSplineMap = new IntMap<>();
+
+ private float getSplineValue(int arrayId, float pos) {
+ MonotonicSpline fit = mSplineMap.get(arrayId);
+ float[] f = mCollectionsAccess.getFloats(arrayId);
+ if (fit != null) {
+ if (fit.getArray() == f) { // the array has not changed.
+ return fit.getPos(pos);
+ }
+ }
+
+ fit = new MonotonicSpline(null, f);
+ mSplineMap.put(arrayId, fit);
+ return fit.getPos(pos);
+ }
/**
* is float a math operator
@@ -114,7 +134,7 @@ public class AnimatedFloatExpression {
* @param var
* @return
*/
- public float eval(float[] exp, float... var) {
+ public float eval(@NonNull float[] exp, @NonNull float... var) {
mStack = exp;
mVar = var;
int sp = -1;
@@ -137,7 +157,8 @@ public class AnimatedFloatExpression {
* @param var
* @return
*/
- public float eval(CollectionsAccess ca, float[] exp, int len, float... var) {
+ public float eval(
+ @NonNull CollectionsAccess ca, @NonNull float[] exp, int len, @NonNull float... var) {
System.arraycopy(exp, 0, mLocalStack, 0, len);
mStack = mLocalStack;
mVar = var;
@@ -167,7 +188,7 @@ public class AnimatedFloatExpression {
* @param exp
* @return
*/
- public float eval(CollectionsAccess ca, float[] exp, int len) {
+ public float eval(@NonNull CollectionsAccess ca, @NonNull float[] exp, int len) {
System.arraycopy(exp, 0, mLocalStack, 0, len);
mStack = mLocalStack;
mCollectionsAccess = ca;
@@ -189,7 +210,7 @@ public class AnimatedFloatExpression {
return mStack[sp];
}
- private int dereference(CollectionsAccess ca, int id, int sp) {
+ private int dereference(@NonNull CollectionsAccess ca, int id, int sp) {
mStack[sp] = ca.getFloatValue(id, (int) (mStack[sp]));
return sp;
}
@@ -202,7 +223,7 @@ public class AnimatedFloatExpression {
* @param var
* @return
*/
- public float eval(@NonNull float[] exp, int len, float... var) {
+ public float eval(@NonNull float[] exp, int len, @NonNull float... var) {
System.arraycopy(exp, 0, mLocalStack, 0, len);
mStack = mLocalStack;
mVar = var;
@@ -225,13 +246,12 @@ public class AnimatedFloatExpression {
* @param var
* @return
*/
- public float evalDB(@NonNull float[] exp, float... var) {
+ public float evalDB(@NonNull float[] exp, @NonNull float... var) {
mStack = exp;
mVar = var;
int sp = -1;
for (float v : exp) {
if (Float.isNaN(v)) {
- System.out.print(" " + sNames.get((fromNaN(v) - OFFSET)));
sp = mOps[fromNaN(v) - OFFSET].eval(sp);
} else {
System.out.print(" " + v);
@@ -375,12 +395,12 @@ public class AnimatedFloatExpression {
return sp - 2;
};
Op mCLAMP =
- (sp) -> { // CLAMP
+ (sp) -> { // CLAMP (min, max, value)
mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
return sp - 2;
};
Op mCBRT =
- (sp) -> { // CBRT
+ (sp) -> { // CBRT is cube root
mStack[sp] = (float) Math.pow(mStack[sp], 1 / 3.);
return sp;
};
@@ -401,8 +421,10 @@ public class AnimatedFloatExpression {
};
Op mA_DEREF =
(sp) -> { // A_DEREF
- int id = fromNaN(mStack[sp]);
- mStack[sp - 1] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp - 1]);
+ Utils.log(" \n >>> DREF " + Integer.toHexString(fromNaN(mStack[sp - 1])));
+ Utils.log(" >>> DREF " + mStack[sp] + " " + mStack[sp - 1]);
+ int id = fromNaN(mStack[sp - 1]);
+ mStack[sp - 1] = mCollectionsAccess.getFloatValue(id, (int) mStack[sp]);
return sp - 1;
};
Op mA_MAX =
@@ -420,11 +442,14 @@ public class AnimatedFloatExpression {
(sp) -> { // A_MIN
int id = fromNaN(mStack[sp]);
float[] array = mCollectionsAccess.getFloats(id);
- float max = array[0];
+ if (array.length == 0) {
+ return sp;
+ }
+ float min = array[0];
for (int i = 1; i < array.length; i++) {
- max = Math.max(max, array[i]);
+ min = Math.min(min, array[i]);
}
- mStack[sp] = max;
+ mStack[sp] = min;
return sp;
};
Op mA_SUM =
@@ -455,6 +480,12 @@ public class AnimatedFloatExpression {
mStack[sp] = mCollectionsAccess.getListLength(id);
return sp;
};
+ Op mA_SPLINE =
+ (sp) -> { // A_SPLINE
+ int id = fromNaN(mStack[sp - 1]);
+ mStack[sp - 1] = getSplineValue(id, mStack[sp]);
+ return sp - 1;
+ };
Op mFIRST_VAR =
(sp) -> { // FIRST_VAR
mStack[sp] = mVar[0];
@@ -510,6 +541,7 @@ public class AnimatedFloatExpression {
mA_SUM,
mA_AVG,
mA_LEN,
+ mA_SPLINE,
mFIRST_VAR,
mSECOND_VAR,
mTHIRD_VAR,
@@ -558,6 +590,7 @@ public class AnimatedFloatExpression {
sNames.put(k++, "A_SUM");
sNames.put(k++, "A_AVG");
sNames.put(k++, "A_LEN");
+ sNames.put(k++, "A_SPLINE");
sNames.put(k++, "a[0]");
sNames.put(k++, "a[1]");
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java
index eb5e4828f2a0..182d36a5eb06 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ArrayAccess.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.Nullable;
+
/**
* Support a standardized interface to commands that contain arrays All commands that implement
* array access will be collected in a map in the state TODO refactor to DataAccess,
@@ -27,6 +29,7 @@ public interface ArrayAccess {
return 0;
}
+ @Nullable
float[] getFloats();
int getLength();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java
index 0128253e1f90..4f1287265d75 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/CollectionsAccess.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.Nullable;
+
/**
* interface to allow expressions to access collections Todo define a convention for when access is
* unavailable
@@ -22,6 +24,7 @@ package com.android.internal.widget.remotecompose.core.operations.utilities;
public interface CollectionsAccess {
float getFloatValue(int id, int index);
+ @Nullable
float[] getFloats(int id);
int getListLength(int id);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java
index 24f17d7b00c7..07a3d8482db2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/DataMap.java
@@ -15,18 +15,20 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.NonNull;
+
public class DataMap {
- public String[] mNames;
- public int[] mIds;
- public byte[] mTypes;
+ @NonNull public final String[] mNames;
+ @NonNull public final int[] mIds;
+ @NonNull public final byte[] mTypes;
- public DataMap(String[] names, byte[] types, int[] ids) {
+ public DataMap(@NonNull String[] names, @NonNull byte[] types, @NonNull int[] ids) {
mNames = names;
mTypes = types;
mIds = ids;
}
- public int getPos(String str) {
+ public int getPos(@NonNull String str) {
for (int i = 0; i < mNames.length; i++) {
String name = mNames[i];
if (str.equals(name)) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java
index e74b3350f427..98ee91b370e0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/ImageScaling.java
@@ -17,6 +17,8 @@ package com.android.internal.widget.remotecompose.core.operations.utilities;
import android.annotation.NonNull;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+
/** Implement the scaling logic for Compose Image or ImageView */
public class ImageScaling {
@@ -109,7 +111,7 @@ public class ImageScaling {
String s = str;
s += str(left) + ", " + str(top) + ", " + str(right) + ", " + str(bottom) + ", ";
s += " [" + str(right - left) + " x " + str(bottom - top) + "]";
- System.out.println(s);
+ Utils.log(s);
}
/** This adjust destnation on the DrawBitMapInt to support all contentScale types */
@@ -128,7 +130,7 @@ public class ImageScaling {
print("test rc ", mSrcLeft, mSrcTop, mSrcRight, mSrcBottom);
print("test dst ", mDstLeft, mDstTop, mDstRight, mDstBottom);
}
-
+ if (sh == 0 || sw == 0) return;
switch (mScaleType) {
case SCALE_NONE:
dh = sh;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java
index 749c0fe0dcc3..b9aa88146f2a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntMap.java
@@ -15,6 +15,7 @@
*/
package com.android.internal.widget.remotecompose.core.operations.utilities;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import java.util.ArrayList;
@@ -45,7 +46,7 @@ public class IntMap<T> {
}
@Nullable
- public T put(int key, T value) {
+ public T put(int key, @NonNull T value) {
if (key == NOT_PRESENT) throw new IllegalArgumentException("Key cannot be NOT_PRESENT");
if (mSize > mKeys.length * LOAD_FACTOR) {
resize();
@@ -66,7 +67,7 @@ public class IntMap<T> {
}
@Nullable
- private T insert(int key, T value) {
+ private T insert(int key, @NonNull T value) {
int index = hash(key) % mKeys.length;
while (mKeys[index] != NOT_PRESENT && mKeys[index] != key) {
index = (index + 1) % mKeys.length;
@@ -116,6 +117,7 @@ public class IntMap<T> {
}
}
+ @Nullable
public T remove(int key) {
int index = hash(key) % mKeys.length;
int initialIndex = index;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
index 8905431d14d7..f73ab39e496e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/IntegerExpressionEvaluator.java
@@ -59,9 +59,9 @@ public class IntegerExpressionEvaluator {
public static final int I_VAR1 = OFFSET + 24;
public static final int I_VAR2 = OFFSET + 25;
- int[] mStack;
+ @NonNull int[] mStack = new int[0];
@NonNull int[] mLocalStack = new int[128];
- int[] mVar;
+ @NonNull int[] mVar = new int[0];
interface Op {
int eval(int sp);
@@ -75,7 +75,7 @@ public class IntegerExpressionEvaluator {
* @param var variables if the expression is a function
* @return return the results of evaluating the expression
*/
- public int eval(int mask, int[] exp, int... var) {
+ public int eval(int mask, @NonNull int[] exp, @NonNull int... var) {
mStack = exp;
mVar = var;
int sp = -1;
@@ -99,7 +99,7 @@ public class IntegerExpressionEvaluator {
* @param var variables if the expression is a function
* @return return the results of evaluating the expression
*/
- public int eval(int mask, @NonNull int[] exp, int len, int... var) {
+ public int eval(int mask, @NonNull int[] exp, int len, @NonNull int... var) {
System.arraycopy(exp, 0, mLocalStack, 0, len);
mStack = mLocalStack;
mVar = var;
@@ -123,17 +123,15 @@ public class IntegerExpressionEvaluator {
* @param var variables if the expression is a function
* @return return the results of evaluating the expression
*/
- public int evalDB(int opMask, @NonNull int[] exp, int... var) {
+ public int evalDB(int opMask, @NonNull int[] exp, @NonNull int... var) {
mStack = exp;
mVar = var;
int sp = -1;
for (int i = 0; i < exp.length; i++) {
int v = mStack[i];
if (((1 << i) & opMask) != 0) {
- System.out.print(" " + sNames.get((v - OFFSET)));
sp = mOps[v - OFFSET].eval(sp);
} else {
- System.out.print(" " + v);
mStack[++sp] = v;
}
}
@@ -199,7 +197,7 @@ public class IntegerExpressionEvaluator {
return sp - 1;
};
Op mCOPY_SIGN =
- (sp) -> { // COPY_SIGN
+ (sp) -> { // COPY_SIGN copy the sign via bit manipulation
mStack[sp - 1] = (mStack[sp - 1] ^ (mStack[sp] >> 31)) - (mStack[sp] >> 31);
return sp - 1;
};
@@ -239,12 +237,12 @@ public class IntegerExpressionEvaluator {
return sp;
};
Op mSIGN =
- (sp) -> { // SIGN
+ (sp) -> { // SIGN x<0 = -1,x==0 = 0 , x>0 = 1
mStack[sp] = (mStack[sp] >> 31) | (-mStack[sp] >>> 31);
return sp;
};
Op mCLAMP =
- (sp) -> { // CLAMP
+ (sp) -> { // CLAMP(min,max, val)
mStack[sp - 2] = Math.min(Math.max(mStack[sp - 2], mStack[sp]), mStack[sp - 1]);
return sp - 2;
};
@@ -360,7 +358,7 @@ public class IntegerExpressionEvaluator {
* @return
*/
@NonNull
- public static String toString(int opMask, @NonNull int[] exp, String[] labels) {
+ public static String toString(int opMask, @NonNull int[] exp, @NonNull String[] labels) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < exp.length; i++) {
int v = exp[i];
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java
index ebb22b6e98c5..465c95d06726 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/FloatAnimation.java
@@ -57,13 +57,17 @@ public class FloatAnimation extends Easing {
mEasingCurve = new CubicEasing(mType);
}
- public FloatAnimation(float... description) {
+ public FloatAnimation(@NonNull float... description) {
mType = CUBIC_STANDARD;
setAnimationDescription(description);
}
public FloatAnimation(
- int type, float duration, float[] description, float initialValue, float wrap) {
+ int type,
+ float duration,
+ @Nullable float[] description,
+ float initialValue,
+ float wrap) {
mType = CUBIC_STANDARD;
setAnimationDescription(packToFloatArray(duration, type, description, initialValue, wrap));
}
@@ -77,7 +81,7 @@ public class FloatAnimation extends Easing {
* @param initialValue
* @return
*/
- public static float[] packToFloatArray(
+ public static @NonNull float[] packToFloatArray(
float duration, int type, @Nullable float[] spec, float initialValue, float wrap) {
int count = 0;
@@ -221,7 +225,7 @@ public class FloatAnimation extends Easing {
*
* @param description
*/
- public void setAnimationDescription(float[] description) {
+ public void setAnimationDescription(@NonNull float[] description) {
mSpec = description;
mDuration = (mSpec.length == 0) ? 1 : mSpec[0];
int len = 0;
@@ -242,7 +246,7 @@ public class FloatAnimation extends Easing {
create(mType, description, 2, len);
}
- private void create(int type, float[] params, int offset, int len) {
+ private void create(int type, @Nullable float[] params, int offset, int len) {
switch (type) {
case CUBIC_STANDARD:
case CUBIC_ACCELERATE:
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
index 90b65bf2353a..06969ccd1b10 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/GeneralEasing.java
@@ -19,7 +19,7 @@ import android.annotation.NonNull;
/** Provides and interface to create easing functions */
public class GeneralEasing extends Easing {
- float[] mEasingData = new float[0];
+ @NonNull float[] mEasingData = new float[0];
@NonNull Easing mEasingCurve = new CubicEasing(CUBIC_STANDARD);
/**
@@ -27,12 +27,12 @@ public class GeneralEasing extends Easing {
*
* @param data
*/
- public void setCurveSpecification(float[] data) {
+ public void setCurveSpecification(@NonNull float[] data) {
mEasingData = data;
createEngine();
}
- public float[] getCurveSpecification() {
+ public @NonNull float[] getCurveSpecification() {
return mEasingData;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java
index f540e7008471..f4579a24fd44 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicCurveFit.java
@@ -22,11 +22,11 @@ import java.util.Arrays;
/** This performs a spline interpolation in multiple dimensions */
public class MonotonicCurveFit {
private static final String TAG = "MonotonicCurveFit";
- private double[] mT;
- private double[][] mY;
- private double[][] mTangent;
+ @NonNull private final double[] mT;
+ @NonNull private final double[][] mY;
+ @NonNull private final double[][] mTangent;
private boolean mExtrapolate = true;
- double[] mSlopeTemp;
+ @NonNull final double[] mSlopeTemp;
/**
* create a collection of curves
@@ -81,7 +81,7 @@ public class MonotonicCurveFit {
* @param t
* @param v
*/
- public void getPos(double t, double[] v) {
+ public void getPos(double t, @NonNull double[] v) {
final int n = mT.length;
final int dim = mY[0].length;
if (mExtrapolate) {
@@ -141,7 +141,7 @@ public class MonotonicCurveFit {
* @param t
* @param v
*/
- public void getPos(double t, float[] v) {
+ public void getPos(double t, @NonNull float[] v) {
final int n = mT.length;
final int dim = mY[0].length;
if (mExtrapolate) {
@@ -243,7 +243,7 @@ public class MonotonicCurveFit {
* @param t
* @param v
*/
- public void getSlope(double t, double[] v) {
+ public void getSlope(double t, @NonNull double[] v) {
final int n = mT.length;
int dim = mY[0].length;
if (t <= mT[0]) {
@@ -297,7 +297,7 @@ public class MonotonicCurveFit {
return 0; // should never reach here
}
- public double[] getTimePoints() {
+ public @NonNull double[] getTimePoints() {
return mT;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicSpline.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicSpline.java
new file mode 100644
index 000000000000..23a664336c5f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/MonotonicSpline.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/** This performs a spline interpolation in multiple dimensions */
+public class MonotonicSpline {
+ private static final String TAG = "MonotonicCurveFit";
+ private float[] mT;
+ private float[] mY;
+ private float[] mTangent;
+ private boolean mExtrapolate = true;
+ float[] mSlopeTemp;
+
+ /**
+ * create a collection of curves
+ *
+ * @param time the point along the curve
+ * @param y the parameter at those points
+ */
+ public MonotonicSpline(@Nullable float[] time, @NonNull float[] y) {
+ if (time == null) { // if time is null assume even 0 to 1;
+ time = new float[y.length];
+ for (int i = 0; i < time.length; i++) {
+ time[i] = i / (float) (time.length - 1);
+ }
+ }
+ mT = time;
+ mY = y;
+ final int n = time.length;
+ final int dim = 1;
+ mSlopeTemp = new float[dim];
+ float[] slope = new float[n - 1]; // could optimize this out
+ float[] tangent = new float[n];
+ for (int i = 0; i < n - 1; i++) {
+ float dt = time[i + 1] - time[i];
+ slope[i] = (y[i + 1] - y[i]) / dt;
+ if (i == 0) {
+ tangent[i] = slope[i];
+ } else {
+ tangent[i] = (slope[i - 1] + slope[i]) * 0.5f;
+ }
+ }
+ tangent[n - 1] = slope[n - 2];
+
+ for (int i = 0; i < n - 1; i++) {
+ if (slope[i] == 0.) {
+ tangent[i] = 0f;
+ tangent[i + 1] = 0f;
+ } else {
+ float a = tangent[i] / slope[i];
+ float b = tangent[i + 1] / slope[i];
+ float h = (float) Math.hypot(a, b);
+ if (h > 9.0) {
+ float t = 3f / h;
+ tangent[i] = t * a * slope[i];
+ tangent[i + 1] = t * b * slope[i];
+ }
+ }
+ }
+ mTangent = tangent;
+ }
+
+ public float[] getArray() {
+ return mY;
+ }
+
+ /**
+ * Get the position of all curves at time t
+ *
+ * @param t
+ * @return position at t
+ */
+ public float getPos(float t) {
+ final int n = mT.length;
+ float v;
+ if (mExtrapolate) {
+ if (t <= mT[0]) {
+ float slopeTemp = getSlope(mT[0]);
+ v = mY[0] + (t - mT[0]) * slopeTemp;
+
+ return v;
+ }
+ if (t >= mT[n - 1]) {
+ float slopeTemp = getSlope(mT[n - 1]);
+ v = mY[n - 1] + (t - mT[n - 1]) * slopeTemp;
+
+ return v;
+ }
+ } else {
+ if (t <= mT[0]) {
+ v = mY[0];
+
+ return v;
+ }
+ if (t >= mT[n - 1]) {
+ v = mY[n - 1];
+
+ return v;
+ }
+ }
+
+ for (int i = 0; i < n - 1; i++) {
+ if (t == mT[i]) {
+
+ v = mY[i];
+ }
+ if (t < mT[i + 1]) {
+ float h = mT[i + 1] - mT[i];
+ float x = (t - mT[i]) / h;
+
+ float y1 = mY[i];
+ float y2 = mY[i + 1];
+ float t1 = mTangent[i];
+ float t2 = mTangent[i + 1];
+ v = interpolate(h, x, y1, y2, t1, t2);
+
+ return v;
+ }
+ }
+ return 0f;
+ }
+
+ /**
+ * Get the slope of the curve at position t
+ *
+ * @param t
+ * @return slope at t
+ */
+ public float getSlope(float t) {
+ final int n = mT.length;
+ float v = 0;
+
+ if (t <= mT[0]) {
+ t = mT[0];
+ } else if (t >= mT[n - 1]) {
+ t = mT[n - 1];
+ }
+
+ for (int i = 0; i < n - 1; i++) {
+ if (t <= mT[i + 1]) {
+ float h = mT[i + 1] - mT[i];
+ float x = (t - mT[i]) / h;
+ float y1 = mY[i];
+ float y2 = mY[i + 1];
+ float t1 = mTangent[i];
+ float t2 = mTangent[i + 1];
+ v = diff(h, x, y1, y2, t1, t2) / h;
+ }
+ break;
+ }
+ return v;
+ }
+
+ public float[] getTimePoints() {
+ return mT;
+ }
+
+ /** Cubic Hermite spline */
+ private static float interpolate(float h, float x, float y1, float y2, float t1, float t2) {
+ float x2 = x * x;
+ float x3 = x2 * x;
+ return -2 * x3 * y2
+ + 3 * x2 * y2
+ + 2 * x3 * y1
+ - 3 * x2 * y1
+ + y1
+ + h * t2 * x3
+ + h * t1 * x3
+ - h * t2 * x2
+ - 2 * h * t1 * x2
+ + h * t1 * x;
+ }
+
+ /** Cubic Hermite spline slope differentiated */
+ private static float diff(float h, float x, float y1, float y2, float t1, float t2) {
+ float x2 = x * x;
+ return -6 * x2 * y2
+ + 6 * x * y2
+ + 6 * x2 * y1
+ - 6 * x * y1
+ + 3 * h * t2 * x2
+ + 3 * h * t1 * x2
+ - 2 * h * t2 * x
+ - 4 * h * t1 * x
+ + h * t1;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/SpringStopEngine.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/SpringStopEngine.java
new file mode 100644
index 000000000000..03e45031e515
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/SpringStopEngine.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.utilities.easing;
+
+/**
+ * This contains the class to provide the logic for an animation to come to a stop using a spring
+ * model. String debug(String desc, float time); float getVelocity(float time); float
+ * getInterpolation(float time); float getVelocity(); boolean isStopped();
+ */
+public class SpringStopEngine {
+ double mDamping = 0.5f;
+
+ @SuppressWarnings("unused")
+ private static final double UNSET = Double.MAX_VALUE;
+
+ @SuppressWarnings("unused")
+ private boolean mInitialized = false;
+
+ private double mStiffness;
+ private double mTargetPos;
+
+ @SuppressWarnings("unused")
+ private double mLastVelocity;
+
+ private float mLastTime;
+ private float mPos;
+ private float mV;
+ private float mMass;
+ private float mStopThreshold;
+ private int mBoundaryMode = 0;
+
+ public String debug(String desc, float time) {
+ return null;
+ }
+
+ void log(String str) {
+ StackTraceElement s = new Throwable().getStackTrace()[1];
+ String line =
+ ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + s.getMethodName() + "() ";
+ System.out.println(line + str);
+ }
+
+ public SpringStopEngine() {}
+
+ public float getTargetValue() {
+ return (float) mTargetPos;
+ }
+
+ public void setInitialValue(float v) {
+ mPos = v;
+ }
+
+ public void setTargetValue(float v) {
+ mTargetPos = v;
+ }
+
+ public SpringStopEngine(float[] parameters) {
+ if (parameters[0] != 0) {
+ throw new RuntimeException(" parameter[0] should be 0");
+ }
+
+ springParameters(
+ 1,
+ parameters[1],
+ parameters[2],
+ parameters[3],
+ Float.floatToRawIntBits(parameters[4]));
+ }
+
+ /**
+ * Config the spring starting conditions
+ *
+ * @param currentPos
+ * @param target
+ * @param currentVelocity
+ */
+ public void springStart(float currentPos, float target, float currentVelocity) {
+ mTargetPos = target;
+ mInitialized = false;
+ mPos = currentPos;
+ mLastVelocity = currentVelocity;
+ mLastTime = 0;
+ }
+
+ /**
+ * Config the spring parameters
+ *
+ * @param mass The mass of the spring
+ * @param stiffness The stiffness of the spring
+ * @param damping The dampening factor
+ * @param stopThreshold how low energy must you be to stop
+ * @param boundaryMode The boundary behaviour
+ */
+ public void springParameters(
+ float mass, float stiffness, float damping, float stopThreshold, int boundaryMode) {
+ mDamping = damping;
+ mInitialized = false;
+ mStiffness = stiffness;
+ mMass = mass;
+ mStopThreshold = stopThreshold;
+ mBoundaryMode = boundaryMode;
+ mLastTime = 0;
+ }
+
+ public float getVelocity(float time) {
+ return (float) mV;
+ }
+
+ public float get(float time) {
+ compute(time - mLastTime);
+ mLastTime = time;
+ if (isStopped()) {
+ mPos = (float) mTargetPos;
+ }
+ return (float) mPos;
+ }
+
+ public float getAcceleration() {
+ double k = mStiffness;
+ double c = mDamping;
+ double x = (mPos - mTargetPos);
+ return (float) (-k * x - c * mV) / mMass;
+ }
+
+ public float getVelocity() {
+ return 0;
+ }
+
+ public boolean isStopped() {
+ double x = (mPos - mTargetPos);
+ double k = mStiffness;
+ double v = mV;
+ double m = mMass;
+ double energy = v * v * m + k * x * x;
+ double max_def = Math.sqrt(energy / k);
+ return max_def <= mStopThreshold;
+ }
+
+ private void compute(double dt) {
+ if (dt <= 0) {
+ // Nothing to compute if there's no time difference
+ return;
+ }
+
+ double k = mStiffness;
+ double c = mDamping;
+ // Estimate how many time we should over sample based on the frequency and current sampling
+ int overSample = (int) (1 + 9 / (Math.sqrt(mStiffness / mMass) * dt * 4));
+ dt /= overSample;
+
+ for (int i = 0; i < overSample; i++) {
+ double x = (mPos - mTargetPos);
+ double a = (-k * x - c * mV) / mMass;
+ // This refinement of a simple coding of the acceleration increases accuracy
+ double avgV = mV + a * dt / 2; // pass 1 calculate the average velocity
+ double avgX = mPos + dt * avgV / 2 - mTargetPos; // pass 1 calculate the average pos
+ a = (-avgX * k - avgV * c) / mMass; // calculate acceleration over that average pos
+
+ double dv = a * dt; // calculate change in velocity
+ avgV = mV + dv / 2; // average velocity is current + half change
+ mV += (float) dv;
+ mPos += (float) (avgV * dt);
+ if (mBoundaryMode > 0) {
+ if (mPos < 0 && ((mBoundaryMode & 1) == 1)) {
+ mPos = -mPos;
+ mV = -mV;
+ }
+ if (mPos > 1 && ((mBoundaryMode & 2) == 2)) {
+ mPos = 2 - mPos;
+ mV = -mV;
+ }
+ }
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java
index c7be3cab4c0b..b1eb8041b0b3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/easing/StepCurve.java
@@ -24,14 +24,14 @@ import android.annotation.NonNull;
*/
public class StepCurve extends Easing {
// private static final boolean DEBUG = false;
- MonotonicCurveFit mCurveFit;
+ @NonNull private final MonotonicCurveFit mCurveFit;
- public StepCurve(float[] params, int offset, int len) {
+ public StepCurve(@NonNull float[] params, int offset, int len) {
mCurveFit = genSpline(params, offset, len);
}
@NonNull
- private static MonotonicCurveFit genSpline(float[] values, int off, int arrayLen) {
+ private static MonotonicCurveFit genSpline(@NonNull float[] values, int off, int arrayLen) {
int length = arrayLen * 3 - 2;
int len = arrayLen - 1;
double gap = 1.0 / len;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
index 3e24372f9b8c..7e02bc9416a9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
@@ -212,7 +212,6 @@ public class VelocityEasing {
mStage[1].setUp(peak_v, d1, t1, 0f, destination, t2 + t1);
mDuration = t2 + t1;
if (mDuration > maxTime) {
- System.out.println(" fail ");
return false;
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
index 3fba8acf8bca..4af79f3ce4f4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/BooleanConstant.java
@@ -54,11 +54,11 @@ public class BooleanConstant implements Operation {
}
@Override
- public void apply(RemoteContext context) {}
+ public void apply(@NonNull RemoteContext context) {}
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
index 79f2a8d8dec5..613e7328e24a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/IntegerConstant.java
@@ -50,7 +50,7 @@ public class IntegerConstant implements Operation {
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
index 01672b469728..745caa384e4c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/types/LongConstant.java
@@ -54,13 +54,13 @@ public class LongConstant implements Operation {
}
@Override
- public void apply(RemoteContext context) {
+ public void apply(@NonNull RemoteContext context) {
context.putObject(mId, this);
}
@NonNull
@Override
- public String deepToString(String indent) {
+ public String deepToString(@NonNull String indent) {
return toString();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
index aaee9c565fbb..2a3f3be714b9 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
@@ -141,4 +141,9 @@ public class RemoteComposeDocument {
}
return mDocument.getStats();
}
+
+ public int hasSensorListeners(int[] ids) {
+
+ return 0;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index cc74b119866d..648f7bf06dd4 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -15,9 +15,14 @@
*/
package com.android.internal.widget.remotecompose.player;
+import android.app.Application;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
@@ -28,6 +33,7 @@ import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
import com.android.internal.widget.remotecompose.player.platform.RemoteComposeCanvas;
@@ -81,6 +87,7 @@ public class RemoteComposePlayer extends FrameLayout {
mInner.setDocument(null);
}
mapColors();
+ setupSensors();
mInner.setHapticEngine(
new CoreDocument.HapticEngine() {
@@ -543,4 +550,113 @@ public class RemoteComposePlayer extends FrameLayout {
private void provideHapticFeedback(int type) {
performHapticFeedback(sHapticTable[type % sHapticTable.length]);
}
+
+ SensorManager mSensorManager;
+ Sensor mAcc = null, mGyro = null, mMag = null, mLight = null;
+ SensorEventListener mListener;
+
+ private void setupSensors() {
+
+ int minId = RemoteContext.ID_ACCELERATION_X;
+ int maxId = RemoteContext.ID_LIGHT;
+ int[] ids = new int[1 + maxId - minId];
+
+ int count = mInner.hasSensorListeners(ids);
+ mAcc = null;
+ mGyro = null;
+ mMag = null;
+ mLight = null;
+ if (count > 0) {
+ Application app = (Application) getContext().getApplicationContext();
+
+ mSensorManager = (SensorManager) app.getSystemService(Context.SENSOR_SERVICE);
+ for (int i = 0; i < count; i++) {
+ switch (ids[i]) {
+ case RemoteContext.ID_ACCELERATION_X:
+ case RemoteContext.ID_ACCELERATION_Y:
+ case RemoteContext.ID_ACCELERATION_Z:
+ if (mAcc == null) {
+ mAcc = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ }
+ break;
+ case RemoteContext.ID_GYRO_ROT_X:
+ case RemoteContext.ID_GYRO_ROT_Y:
+ case RemoteContext.ID_GYRO_ROT_Z:
+ if (mGyro == null) {
+ mGyro = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
+ }
+ break;
+ case RemoteContext.ID_MAGNETIC_X:
+ case RemoteContext.ID_MAGNETIC_Y:
+ case RemoteContext.ID_MAGNETIC_Z:
+ if (mMag == null) {
+ mMag = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+ }
+ break;
+ case RemoteContext.ID_LIGHT:
+ if (mLight == null) {
+ mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+ }
+ }
+ }
+ }
+ registerListener();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ unregisterListener();
+ }
+
+ public void registerListener() {
+ Sensor[] s = {mAcc, mGyro, mMag, mLight};
+ if (mListener != null) {
+ unregisterListener();
+ }
+ SensorEventListener listener =
+ new SensorEventListener() {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (event.sensor == mAcc) {
+ mInner.setExternalFloat(
+ RemoteContext.ID_ACCELERATION_X, event.values[0]);
+ mInner.setExternalFloat(
+ RemoteContext.ID_ACCELERATION_Y, event.values[1]);
+ mInner.setExternalFloat(
+ RemoteContext.ID_ACCELERATION_Z, event.values[2]);
+ } else if (event.sensor == mGyro) {
+ mInner.setExternalFloat(RemoteContext.ID_GYRO_ROT_X, event.values[0]);
+ mInner.setExternalFloat(RemoteContext.ID_GYRO_ROT_Y, event.values[1]);
+ mInner.setExternalFloat(RemoteContext.ID_GYRO_ROT_Z, event.values[2]);
+ } else if (event.sensor == mMag) {
+ mInner.setExternalFloat(RemoteContext.ID_MAGNETIC_X, event.values[0]);
+ mInner.setExternalFloat(RemoteContext.ID_MAGNETIC_Y, event.values[1]);
+ mInner.setExternalFloat(RemoteContext.ID_MAGNETIC_Z, event.values[2]);
+ } else if (event.sensor == mLight) {
+ mInner.setExternalFloat(RemoteContext.ID_LIGHT, event.values[0]);
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {}
+ };
+
+ Sensor[] sensors = {mAcc, mGyro, mMag, mLight};
+ for (int i = 0; i < sensors.length; i++) {
+ Sensor sensor = sensors[i];
+ if (sensor != null) {
+ mListener = listener;
+ mSensorManager.registerListener(
+ mListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+ }
+ }
+
+ public void unregisterListener() {
+ if (mListener != null && mSensorManager != null) {
+ mSensorManager.unregisterListener(mListener);
+ }
+ mListener = null;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
index 0b650a93c9db..3c91cffcec3f 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPaintContext.java
@@ -15,6 +15,7 @@
*/
package com.android.internal.widget.remotecompose.player.platform;
+import android.annotation.NonNull;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Canvas;
@@ -247,7 +248,7 @@ public class AndroidPaintContext extends PaintContext {
}
@Override
- public void getTextBounds(int textId, int start, int end, int flags, float[] bounds) {
+ public void getTextBounds(int textId, int start, int end, int flags, @NonNull float[] bounds) {
String str = getText(textId);
if (end == -1) {
end = str.length();
@@ -420,7 +421,7 @@ public class AndroidPaintContext extends PaintContext {
* @param paintData the list change to the paint
*/
@Override
- public void applyPaint(PaintBundle paintData) {
+ public void applyPaint(@NonNull PaintBundle paintData) {
paintData.applyPaintChange(
(PaintContext) this,
new PaintChanges() {
@@ -576,8 +577,8 @@ public class AndroidPaintContext extends PaintContext {
@Override
public void setLinearGradient(
- int[] colors,
- float[] stops,
+ @NonNull int[] colors,
+ @NonNull float[] stops,
float startX,
float startY,
float endX,
@@ -596,8 +597,8 @@ public class AndroidPaintContext extends PaintContext {
@Override
public void setRadialGradient(
- int[] colors,
- float[] stops,
+ @NonNull int[] colors,
+ @NonNull float[] stops,
float centerX,
float centerY,
float radius,
@@ -614,7 +615,10 @@ public class AndroidPaintContext extends PaintContext {
@Override
public void setSweepGradient(
- int[] colors, float[] stops, float centerX, float centerY) {
+ @NonNull int[] colors,
+ @NonNull float[] stops,
+ float centerX,
+ float centerY) {
mPaint.setShader(new SweepGradient(centerX, centerY, colors, stops));
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java
index f28e85a44c1b..ba8d83bff51f 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidPlatformServices.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.player.platform;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.graphics.Path;
import android.graphics.PathIterator;
@@ -31,7 +33,7 @@ public class AndroidPlatformServices implements Platform {
private static final String LOG_TAG = "RemoteCompose";
@Override
- public byte[] imageToByteArray(Object image) {
+ public byte[] imageToByteArray(@NonNull Object image) {
if (image instanceof Bitmap) {
// let's create a bitmap
ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream();
@@ -42,7 +44,7 @@ public class AndroidPlatformServices implements Platform {
}
@Override
- public int getImageWidth(Object image) {
+ public int getImageWidth(@NonNull Object image) {
if (image instanceof Bitmap) {
return ((Bitmap) image).getWidth();
}
@@ -50,7 +52,7 @@ public class AndroidPlatformServices implements Platform {
}
@Override
- public int getImageHeight(Object image) {
+ public int getImageHeight(@NonNull Object image) {
if (image instanceof Bitmap) {
return ((Bitmap) image).getHeight();
}
@@ -58,7 +60,8 @@ public class AndroidPlatformServices implements Platform {
}
@Override
- public float[] pathToFloatArray(Object path) {
+ @Nullable
+ public float[] pathToFloatArray(@NonNull Object path) {
// if (path is RemotePath) {
// return path.createFloatArray()
// }
@@ -88,7 +91,7 @@ public class AndroidPlatformServices implements Platform {
}
}
- private float[] androidPathToFloatArray(Path path) {
+ private @NonNull float[] androidPathToFloatArray(@NonNull Path path) {
PathIterator i = path.getPathIterator();
int estimatedSize = 0;
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
index 7a7edba160c8..77c25147b1fd 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.player.platform;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
@@ -22,11 +24,15 @@ import android.graphics.Canvas;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.TouchListener;
import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.operations.BitmapData;
import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
import com.android.internal.widget.remotecompose.core.operations.ShaderData;
import com.android.internal.widget.remotecompose.core.operations.utilities.ArrayAccess;
import com.android.internal.widget.remotecompose.core.operations.utilities.DataMap;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.HashMap;
/**
@@ -53,7 +59,7 @@ class AndroidRemoteContext extends RemoteContext {
///////////////////////////////////////////////////////////////////////////////////////////////
@Override
- public void loadPathData(int instanceId, float[] floatPath) {
+ public void loadPathData(int instanceId, @NonNull float[] floatPath) {
if (!mRemoteComposeState.containsId(instanceId)) {
mRemoteComposeState.cacheData(instanceId, floatPath);
}
@@ -74,12 +80,12 @@ class AndroidRemoteContext extends RemoteContext {
HashMap<String, VarName> mVarNameHashMap = new HashMap<>();
@Override
- public void loadVariableName(String varName, int varId, int varType) {
+ public void loadVariableName(@NonNull String varName, int varId, int varType) {
mVarNameHashMap.put(varName, new VarName(varName, varId, varType));
}
@Override
- public void setNamedStringOverride(String stringName, String value) {
+ public void setNamedStringOverride(@NonNull String stringName, @NonNull String value) {
if (mVarNameHashMap.get(stringName) != null) {
int id = mVarNameHashMap.get(stringName).mId;
overrideText(id, value);
@@ -87,7 +93,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void clearNamedStringOverride(String stringName) {
+ public void clearNamedStringOverride(@NonNull String stringName) {
if (mVarNameHashMap.get(stringName) != null) {
int id = mVarNameHashMap.get(stringName).mId;
clearDataOverride(id);
@@ -96,7 +102,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void setNamedIntegerOverride(String stringName, int value) {
+ public void setNamedIntegerOverride(@NonNull String stringName, int value) {
if (mVarNameHashMap.get(stringName) != null) {
int id = mVarNameHashMap.get(stringName).mId;
overrideInt(id, value);
@@ -104,7 +110,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void clearNamedIntegerOverride(String integerName) {
+ public void clearNamedIntegerOverride(@NonNull String integerName) {
if (mVarNameHashMap.get(integerName) != null) {
int id = mVarNameHashMap.get(integerName).mId;
clearIntegerOverride(id);
@@ -118,18 +124,18 @@ class AndroidRemoteContext extends RemoteContext {
* @param colorName name of color
* @param color
*/
- public void setNamedColorOverride(String colorName, int color) {
+ public void setNamedColorOverride(@NonNull String colorName, int color) {
int id = mVarNameHashMap.get(colorName).mId;
mRemoteComposeState.overrideColor(id, color);
}
@Override
- public void addCollection(int id, ArrayAccess collection) {
+ public void addCollection(int id, @NonNull ArrayAccess collection) {
mRemoteComposeState.addCollection(id, collection);
}
@Override
- public void putDataMap(int id, DataMap map) {
+ public void putDataMap(int id, @NonNull DataMap map) {
mRemoteComposeState.putDataMap(id, map);
}
@@ -139,7 +145,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void runAction(int id, String metadata) {
+ public void runAction(int id, @NonNull String metadata) {
mDocument.performClick(id);
}
@@ -152,21 +158,66 @@ class AndroidRemoteContext extends RemoteContext {
/**
* Decode a byte array into an image and cache it using the given imageId
*
- * @param width with of image to be loaded
+ * @param encoding how the data is encoded 0 = png, 1 = raw, 2 = url
+ * @param type the type of the data 0 = RGBA 8888, 1 = 888, 2 = 8 gray
+ * @param width with of image to be loaded largest dimension is 32767
* @param height height of image to be loaded
* @param bitmap a byte array containing the image information
* @oaram imageId the id of the image
*/
@Override
- public void loadBitmap(int imageId, int width, int height, byte[] bitmap) {
+ public void loadBitmap(
+ int imageId, short encoding, short type, int width, int height, @NonNull byte[] data) {
if (!mRemoteComposeState.containsId(imageId)) {
- Bitmap image = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length);
+ Bitmap image = null;
+ switch (encoding) {
+ case BitmapData.ENCODING_INLINE:
+ switch (type) {
+ case BitmapData.TYPE_PNG_8888:
+ image = BitmapFactory.decodeByteArray(data, 0, data.length);
+ break;
+ case BitmapData.TYPE_RAW8888:
+ image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ int[] idata = new int[data.length / 4];
+ for (int i = 0; i < idata.length; i++) {
+ int p = i * 4;
+ idata[i] =
+ (data[p] << 24)
+ | (data[p + 1] << 16)
+ | (data[p + 2] << 8)
+ | data[p + 3];
+ }
+ image.setPixels(idata, 0, width, 0, 0, width, height);
+ break;
+ case BitmapData.TYPE_RAW8:
+ image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ int[] bdata = new int[data.length / 4];
+ for (int i = 0; i < bdata.length; i++) {
+
+ bdata[i] = 0x1010101 * data[i];
+ }
+ image.setPixels(bdata, 0, width, 0, 0, width, height);
+ break;
+ }
+ break;
+ case BitmapData.ENCODING_FILE:
+ image = BitmapFactory.decodeFile(new String(data));
+ break;
+ case BitmapData.ENCODING_URL:
+ try {
+ image = BitmapFactory.decodeStream(new URL(new String(data)).openStream());
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
mRemoteComposeState.cacheData(imageId, image);
}
}
@Override
- public void loadText(int id, String text) {
+ public void loadText(int id, @NonNull String text) {
if (!mRemoteComposeState.containsId(id)) {
mRemoteComposeState.cacheData(id, text);
} else {
@@ -225,12 +276,12 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void loadAnimatedFloat(int id, FloatExpression animatedFloat) {
+ public void loadAnimatedFloat(int id, @NonNull FloatExpression animatedFloat) {
mRemoteComposeState.cacheData(id, animatedFloat);
}
@Override
- public void loadShader(int id, ShaderData value) {
+ public void loadShader(int id, @NonNull ShaderData value) {
mRemoteComposeState.cacheData(id, value);
}
@@ -240,7 +291,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void putObject(int id, Object value) {
+ public void putObject(int id, @NonNull Object value) {
mRemoteComposeState.updateObject(id, value);
}
@@ -260,7 +311,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
- public void listensTo(int id, VariableSupport variableSupport) {
+ public void listensTo(int id, @NonNull VariableSupport variableSupport) {
mRemoteComposeState.listenToVar(id, variableSupport);
}
@@ -270,6 +321,7 @@ class AndroidRemoteContext extends RemoteContext {
}
@Override
+ @Nullable
public ShaderData getShader(int id) {
return (ShaderData) mRemoteComposeState.getFromId(id);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java b/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java
index fdd9aad68d47..41ed017b3896 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/ClickAreaView.java
@@ -15,6 +15,7 @@
*/
package com.android.internal.widget.remotecompose.player.platform;
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -23,13 +24,17 @@ import android.view.View;
/** Implementation for the click handling */
class ClickAreaView extends View {
private int mId;
- private String mMetadata;
+ private final String mMetadata;
Paint mPaint = new Paint();
private boolean mDebug;
ClickAreaView(
- Context context, boolean debug, int id, String contentDescription, String metadata) {
+ Context context,
+ boolean debug,
+ int id,
+ @Nullable String contentDescription,
+ String metadata) {
super(context);
this.mId = id;
this.mMetadata = metadata;
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index b54ed8a77ec5..8f55f8abf713 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -26,6 +26,7 @@ import android.view.View;
import android.widget.FrameLayout;
import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.player.RemoteComposeDocument;
@@ -194,6 +195,20 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
}
}
+ public int hasSensorListeners(int[] ids) {
+ int count = 0;
+ for (int id = RemoteContext.ID_ACCELERATION_X; id <= RemoteContext.ID_LIGHT; id++) {
+ if (mARContext.mRemoteComposeState.hasListener(id)) {
+ ids[count++] = id;
+ }
+ }
+ return count;
+ }
+
+ public void setExternalFloat(int id, float value) {
+ mARContext.loadFloat(id, value);
+ }
+
public interface ClickCallbacks {
void click(int id, String metadata);
}
@@ -344,7 +359,9 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
mARContext.setAnimationEnabled(true);
mARContext.currentTime = System.currentTimeMillis();
mARContext.setDebug(mDebug);
+ float density = getContext().getResources().getDisplayMetrics().density;
mARContext.useCanvas(canvas);
+ mARContext.setDensity(density);
mARContext.mWidth = getWidth();
mARContext.mHeight = getHeight();
mDocument.paint(mARContext, mTheme);
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index a21bf9abdd7b..5c03c5cca66d 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -161,6 +161,7 @@ cc_library_shared_for_libandroid_runtime {
"android_view_MotionPredictor.cpp",
"android_view_PointerIcon.cpp",
"android_view_SurfaceControl.cpp",
+ "android_view_SurfaceControlActivePictureListener.cpp",
"android_view_SurfaceControlHdrLayerInfoListener.cpp",
"android_view_WindowManagerGlobal.cpp",
"android_graphics_BLASTBufferQueue.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 821861efd59b..00a62977de43 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -128,6 +128,7 @@ extern int register_android_view_InputApplicationHandle(JNIEnv* env);
extern int register_android_view_InputWindowHandle(JNIEnv* env);
extern int register_android_view_Surface(JNIEnv* env);
extern int register_android_view_SurfaceControl(JNIEnv* env);
+extern int register_android_view_SurfaceControlActivePictureListener(JNIEnv* env);
extern int register_android_view_SurfaceControlHdrLayerInfoListener(JNIEnv* env);
extern int register_android_view_SurfaceSession(JNIEnv* env);
extern int register_android_view_CompositionSamplingListener(JNIEnv* env);
@@ -1563,6 +1564,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_view_Surface),
REG_JNI(register_android_view_SurfaceControl),
+ REG_JNI(register_android_view_SurfaceControlActivePictureListener),
REG_JNI(register_android_view_SurfaceControlHdrLayerInfoListener),
REG_JNI(register_android_view_SurfaceSession),
REG_JNI(register_android_view_InputApplicationHandle),
diff --git a/core/jni/android_os_PerformanceHintManager.cpp b/core/jni/android_os_PerformanceHintManager.cpp
index aebe7ea7ee61..0f78c9e93a00 100644
--- a/core/jni/android_os_PerformanceHintManager.cpp
+++ b/core/jni/android_os_PerformanceHintManager.cpp
@@ -88,9 +88,10 @@ void ensureAPerformanceHintBindingInitialized() {
"Failed to find required symbol "
"APerformanceHint_getPreferredUpdateRateNanos!");
- gAPH_createSessionFn = (APH_createSession)dlsym(handle_, "APerformanceHint_createSession");
+ gAPH_createSessionFn =
+ (APH_createSession)dlsym(handle_, "APerformanceHint_createSessionFromJava");
LOG_ALWAYS_FATAL_IF(gAPH_createSessionFn == nullptr,
- "Failed to find required symbol APerformanceHint_createSession!");
+ "Failed to find required symbol APerformanceHint_createSessionFromJava!");
gAPH_updateTargetWorkDurationFn =
(APH_updateTargetWorkDuration)dlsym(handle_,
@@ -106,9 +107,9 @@ void ensureAPerformanceHintBindingInitialized() {
"Failed to find required symbol "
"APerformanceHint_reportActualWorkDuration!");
- gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSession");
+ gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSessionFromJava");
LOG_ALWAYS_FATAL_IF(gAPH_closeSessionFn == nullptr,
- "Failed to find required symbol APerformanceHint_closeSession!");
+ "Failed to find required symbol APerformanceHint_closeSessionFromJava!");
gAPH_sendHintFn = (APH_sendHint)dlsym(handle_, "APerformanceHint_sendHint");
LOG_ALWAYS_FATAL_IF(gAPH_sendHintFn == nullptr,
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 593b982d4cf2..68e642086636 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -55,6 +55,7 @@
#include <ui/FrameStats.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
+#include <ui/PictureProfileHandle.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/StaticDisplayInfo.h>
@@ -820,6 +821,21 @@ static void nativeSetLuts(JNIEnv* env, jclass clazz, jlong transactionObj, jlong
transaction->setLuts(ctrl, base::unique_fd(fd), offsets, dimensions, sizes, samplingKeys);
}
+static void nativeSetPictureProfileId(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jlong surfaceControlObj, jlong pictureProfileId) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlObj);
+ PictureProfileHandle handle(pictureProfileId);
+ transaction->setPictureProfileHandle(surfaceControl, handle);
+}
+
+static void nativeSetContentPriority(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jlong surfaceControlObj, jint priority) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlObj);
+ transaction->setContentPriority(surfaceControl, priority);
+}
+
static void nativeSetCachingHint(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jint cachingHint) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2351,6 +2367,20 @@ static jboolean nativeBootFinished(JNIEnv* env, jclass clazz) {
return error == OK ? JNI_TRUE : JNI_FALSE;
}
+static jint nativeGetMaxPictureProfiles(JNIEnv* env, jclass clazz) {
+ const auto displayIds = SurfaceComposerClient::SurfaceComposerClient::getPhysicalDisplayIds();
+ int largestMaxProfiles = 0;
+ for (auto displayId : displayIds) {
+ sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(displayId);
+ int32_t maxProfiles = 0;
+ SurfaceComposerClient::getMaxLayerPictureProfiles(token, &maxProfiles);
+ if (maxProfiles > largestMaxProfiles) {
+ largestMaxProfiles = maxProfiles;
+ }
+ }
+ return largestMaxProfiles;
+}
+
jlong nativeCreateTpc(JNIEnv* env, jclass clazz, jobject trustedPresentationCallback) {
return reinterpret_cast<jlong>(
new TrustedPresentationCallbackWrapper(env, trustedPresentationCallback));
@@ -2672,6 +2702,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeGetDefaultApplyToken },
{"nativeBootFinished", "()Z",
(void*)nativeBootFinished },
+ {"nativeGetMaxPictureProfiles", "()I",
+ (void*)nativeGetMaxPictureProfiles },
{"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J",
(void*)nativeCreateTpc},
{"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer },
@@ -2683,6 +2715,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeNotifyShutdown },
{"nativeSetLuts", "(JJ[F[I[I[I[I)V", (void*)nativeSetLuts },
{"nativeEnableDebugLogCallPoints", "(J)V", (void*)nativeEnableDebugLogCallPoints },
+ {"nativeSetPictureProfileId", "(JJJ)V", (void*)nativeSetPictureProfileId },
+ {"nativeSetContentPriority", "(JJI)V", (void*)nativeSetContentPriority },
// clang-format on
};
diff --git a/core/jni/android_view_SurfaceControlActivePictureListener.cpp b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
new file mode 100644
index 000000000000..91849c1514cc
--- /dev/null
+++ b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceControlActivePictureListener"
+
+#include <android/gui/BnActivePictureListener.h>
+#include <android_runtime/Log.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <utils/RefBase.h>
+
+#include "android_util_Binder.h"
+#include "core_jni_helpers.h"
+
+namespace android {
+
+namespace {
+
+struct {
+ jclass clazz;
+ jmethodID onActivePicturesChanged;
+} gListenerClassInfo;
+
+static struct {
+ jclass clazz;
+ jmethodID constructor;
+} gActivePictureClassInfo;
+
+static struct {
+ jclass clazz;
+ jmethodID constructor;
+ jfieldID id;
+} gPictureProfileHandleClassInfo;
+
+struct SurfaceControlActivePictureListener : public gui::BnActivePictureListener {
+ SurfaceControlActivePictureListener(JNIEnv* env, jobject listener)
+ : mListener(env->NewGlobalRef(listener)) {
+ LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mVm) != JNI_OK, "Failed to GetJavaVm");
+ }
+
+ binder::Status onActivePicturesChanged(
+ const std::vector<gui::ActivePicture>& activePictures) override {
+ JNIEnv* env = requireEnv();
+
+ ScopedLocalRef<jobjectArray> activePictureArrayObj(env);
+ activePictureArrayObj.reset(
+ env->NewObjectArray(activePictures.size(), gActivePictureClassInfo.clazz, NULL));
+ if (env->ExceptionCheck() || !activePictureArrayObj.get()) {
+ LOGE_EX(env);
+ LOG_ALWAYS_FATAL("Failed to create an active picture array.");
+ }
+
+ {
+ std::vector<ScopedLocalRef<jobject>> pictureProfileHandleObjs;
+ std::vector<ScopedLocalRef<jobject>> activePictureObjs;
+
+ for (size_t i = 0; i < activePictures.size(); ++i) {
+ pictureProfileHandleObjs.push_back(ScopedLocalRef<jobject>(env));
+ pictureProfileHandleObjs[i].reset(
+ env->NewObject(gPictureProfileHandleClassInfo.clazz,
+ gPictureProfileHandleClassInfo.constructor,
+ activePictures[i].pictureProfileId));
+ if (env->ExceptionCheck() || !pictureProfileHandleObjs[i].get()) {
+ LOGE_EX(env);
+ LOG_ALWAYS_FATAL("Failed to create a picture profile handle.");
+ }
+ activePictureObjs.push_back(ScopedLocalRef<jobject>(env));
+ activePictureObjs[i].reset(env->NewObject(gActivePictureClassInfo.clazz,
+ gActivePictureClassInfo.constructor,
+ activePictures[i].layerId,
+ activePictures[i].ownerUid,
+ pictureProfileHandleObjs[i].get()));
+ if (env->ExceptionCheck() || !activePictureObjs[i].get()) {
+ LOGE_EX(env);
+ LOG_ALWAYS_FATAL("Failed to create an active picture.");
+ }
+ env->SetObjectArrayElement(activePictureArrayObj.get(), i,
+ activePictureObjs[i].get());
+ }
+
+ env->CallVoidMethod(mListener, gListenerClassInfo.onActivePicturesChanged,
+ activePictureArrayObj.get());
+ }
+
+ if (env->ExceptionCheck()) {
+ ALOGE("SurfaceControlActivePictureListener.onActivePicturesChanged failed");
+ LOGE_EX(env);
+ env->ExceptionClear();
+ }
+ return binder::Status::ok();
+ }
+
+ status_t startListening() {
+ // TODO(b/337330263): Make SF multiple-listener capable
+ return SurfaceComposerClient::setActivePictureListener(this);
+ }
+
+ status_t stopListening() {
+ return SurfaceComposerClient::setActivePictureListener(nullptr);
+ }
+
+protected:
+ virtual ~SurfaceControlActivePictureListener() {
+ JNIEnv* env = requireEnv();
+ env->DeleteGlobalRef(mListener);
+ }
+
+ JNIEnv* requireEnv() {
+ JNIEnv* env = nullptr;
+ if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ if (mVm->AttachCurrentThreadAsDaemon(&env, nullptr) != JNI_OK) {
+ LOG_ALWAYS_FATAL("Failed to AttachCurrentThread!");
+ }
+ }
+ return env;
+ }
+
+private:
+ jobject mListener;
+ JavaVM* mVm;
+};
+
+jlong nativeMakeAndStartListening(JNIEnv* env, jobject jthis) {
+ auto listener = sp<SurfaceControlActivePictureListener>::make(env, jthis);
+ status_t err = listener->startListening();
+ if (err != OK) {
+ auto errStr = statusToString(err);
+ jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ "Failed to start listening, err = %d (%s)", err, errStr.c_str());
+ return 0;
+ }
+ SurfaceControlActivePictureListener* listenerRawPtr = listener.get();
+ listenerRawPtr->incStrong(0);
+ return static_cast<jlong>(reinterpret_cast<intptr_t>(listenerRawPtr));
+}
+
+static void destroy(SurfaceControlActivePictureListener* listener) {
+ listener->stopListening();
+ listener->decStrong(0);
+}
+
+static jlong nativeGetDestructor(JNIEnv* env, jobject clazz) {
+ return static_cast<jlong>(reinterpret_cast<intptr_t>(&destroy));
+}
+
+const JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ {"nativeGetDestructor", "()J", (void*)nativeGetDestructor},
+ {"nativeMakeAndStartListening", "()J", (void*)nativeMakeAndStartListening}};
+} // namespace
+
+int register_android_view_SurfaceControlActivePictureListener(JNIEnv* env) {
+ int res = jniRegisterNativeMethods(env, "android/view/SurfaceControlActivePictureListener",
+ gMethods, NELEM(gMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+
+ jclass listenerClazz = env->FindClass("android/view/SurfaceControlActivePictureListener");
+ gListenerClassInfo.clazz = MakeGlobalRefOrDie(env, listenerClazz);
+ gListenerClassInfo.onActivePicturesChanged =
+ env->GetMethodID(listenerClazz, "onActivePicturesChanged",
+ "([Landroid/view/SurfaceControlActivePicture;)V");
+
+ gActivePictureClassInfo.clazz = static_cast<jclass>(
+ env->NewGlobalRef(env->FindClass("android/view/SurfaceControlActivePicture")));
+ gActivePictureClassInfo.constructor =
+ env->GetMethodID(gActivePictureClassInfo.clazz, "<init>",
+ "(IILandroid/media/quality/PictureProfileHandle;)V");
+
+ gPictureProfileHandleClassInfo.clazz = static_cast<jclass>(
+ env->NewGlobalRef(env->FindClass("android/media/quality/PictureProfileHandle")));
+ gPictureProfileHandleClassInfo.constructor =
+ env->GetMethodID(gPictureProfileHandleClassInfo.clazz, "<init>", "(J)V");
+ return 0;
+}
+
+} // namespace android
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index 9779dc0e00b8..16d25657f08e 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -217,6 +217,7 @@ message SystemSettingsProto {
optional SettingProto right_click_zone = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto tap_to_click = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto tap_dragging = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto three_finger_tap_customization = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Touchpad touchpad = 36;
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 0e4e22b09e24..8042b30df4dc 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -161,6 +161,7 @@ android_app {
"android.app.flags-aconfig",
"android.appwidget.flags-aconfig",
"android.content.pm.flags-aconfig",
+ "android.media.audio-aconfig",
"android.provider.flags-aconfig",
"camera_platform_flags",
"android.net.platform.flags-aconfig",
@@ -170,6 +171,7 @@ android_app {
"android.os.vibrator.flags-aconfig",
"android.media.tv.flags-aconfig",
"android.security.flags-aconfig",
+ "device_policy_aconfig_flags",
"com.android.hardware.input.input-aconfig",
"aconfig_trade_in_mode_flags",
"art-aconfig-flags",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7fcbf19d137f..cedcd2feafc3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2649,6 +2649,22 @@
android:label="@string/permlab_getAccounts" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
+ <!-- @SystemApi Allows access to remove an account.
+ @FlaggedApi(android.app.admin.flags.Flags.FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED)
+ <p>Not for use by third-party applications.
+ @hide -->
+ <permission android:name="android.permission.REMOVE_ACCOUNTS"
+ android:protectionLevel="signature|role"
+ android:featureFlag="android.app.admin.flags.split_create_managed_profile_enabled" />
+
+ <!-- @SystemApi Allows access to copy an account to another user.
+ @FlaggedApi(android.app.admin.flags.Flags.FLAG_SPLIT_CREATE_MANAGED_PROFILE_ENABLED)
+ <p>Not for use by third-party applications.
+ @hide -->
+ <permission android:name="android.permission.COPY_ACCOUNTS"
+ android:protectionLevel="signature|role"
+ android:featureFlag="android.app.admin.flags.split_create_managed_profile_enabled" />
+
<!-- Allows applications to call into AccountAuthenticators.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.ACCOUNT_MANAGER"
@@ -4185,53 +4201,54 @@
android:protectionLevel="signature|installer" />
<uses-permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" />
- <!-- Allows an application to toggle the device's advanced protection mode status.
- @FlaggedApi("android.security.aapm_api")
+ <!-- Allows an application to modify the device's advanced protection mode status, and query
+ the list of enabled features
+ @FlaggedApi(android.security.Flags.FLAG_AAPM_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.SET_ADVANCED_PROTECTION_MODE"
+ <permission android:name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE"
android:protectionLevel="signature|privileged"
android:featureFlag="android.security.aapm_api"/>
- <uses-permission android:name="android.permission.SET_ADVANCED_PROTECTION_MODE"
+ <uses-permission android:name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE"
android:featureFlag="android.security.aapm_api"/>
<!-- Allows an application to query the device's advanced protection mode status.
- @FlaggedApi("android.security.aapm_api") -->
+ @FlaggedApi(android.security.Flags.FLAG_AAPM_API) -->
<permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
android:protectionLevel="normal"
android:featureFlag="android.security.aapm_api"/>
<uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
android:featureFlag="android.security.aapm_api"/>
- <!-- Allows an application to read the state of the ForensicService
+ <!-- Allows an application to read the state of the IntrusionDetectionService
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.READ_FORENSIC_STATE"
+ <permission android:name="android.permission.READ_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"
android:protectionLevel="signature|privileged" />
- <uses-permission android:name="android.permission.READ_FORENSIC_STATE"
+ <uses-permission android:name="android.permission.READ_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
- <!-- Allows an application to change the state of the ForensicService
+ <!-- Allows an application to change the state of the IntrusionDetectionService
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.MANAGE_FORENSIC_STATE"
+ <permission android:name="android.permission.MANAGE_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"
android:protectionLevel="signature|privileged" />
- <uses-permission android:name="android.permission.MANAGE_FORENSIC_STATE"
+ <uses-permission android:name="android.permission.MANAGE_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
- <!-- Must be required by any ForensicEventTransportService to ensure that
+ <!-- Must be required by any IntrusionDetectionEventTransportService to ensure that
only the system can bind to it.
@FlaggedApi(android.security.Flags.FLAG_AFL_API)
@SystemApi
@hide -->
- <permission android:name="android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE"
+ <permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE"
android:featureFlag="android.security.afl_api"
android:protectionLevel="signature" />
- <uses-permission android:name="android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE"
+ <uses-permission android:name="android.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE"
android:featureFlag="android.security.afl_api"/>
<!-- @SystemApi @hide Allows an application to set a device owner on retail demo devices.-->
@@ -6492,6 +6509,15 @@
<permission android:name="android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT"
android:protectionLevel="signature|privileged|role" />
+ <!-- @SystemApi Allows an application to bypass concurrency restrictions while
+ recording audio. For example, apps with this permission can continue to record
+ while a voice call is active.</p>
+ @FlaggedApi(android.media.audio.Flags.FLAG_CONCURRENT_AUDIO_RECORD_BYPASS_PERMISSION)
+ @hide -->
+ <permission android:name="android.permission.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION"
+ android:featureFlag="android.media.audio.concurrent_audio_record_bypass_permission"
+ android:protectionLevel="signature|privileged|role" />
+
<!-- @SystemApi Allows an application to capture audio for hotword detection.
<p>Not for use by third-party applications.</p>
@hide -->
@@ -8651,6 +8677,17 @@
<permission android:name="android.permission.SETUP_FSVERITY"
android:protectionLevel="signature|privileged"/>
+ <!-- @SystemApi
+ @FlaggedApi(android.security.Flags.FLAG_SECURE_LOCKDOWN)
+ Allows an application to lock down the device into an enhanced security state.
+ <p>Not for use by third-party applications.
+ <p>Protection level: signature|privileged
+ @hide
+ -->
+ <permission android:name="android.permission.MANAGE_SECURE_LOCK_DEVICE"
+ android:protectionLevel="signature|privileged"
+ android:featureFlag="android.security.secure_lockdown" />
+
<!-- Allows app to enter trade-in-mode.
<p>Protection level: signature|privileged
@hide
@@ -8680,29 +8717,6 @@
<permission android:name="android.permission.RESERVED_FOR_TESTING_SIGNATURE"
android:protectionLevel="signature"/>
- <!-- @SystemApi
- @FlaggedApi("android.content.pm.verification_service")
- Allows app to be the verification agent to verify packages.
- <p>Protection level: signature|privileged
- @hide
- -->
- <permission android:name="android.permission.VERIFICATION_AGENT"
- android:protectionLevel="signature|privileged"
- android:featureFlag="android.content.pm.verification_service" />
-
- <!-- @SystemApi
- @FlaggedApi("android.content.pm.verification_service")
- Must be required by a privileged {@link android.content.pm.verify.pkg.VerifierService}
- to ensure that only the system can bind to it.
- This permission should not be held by anything other than the system.
- <p>Not for use by third-party applications. </p>
- <p>Protection level: signature
- @hide
- -->
- <permission android:name="android.permission.BIND_VERIFICATION_AGENT"
- android:protectionLevel="internal"
- android:featureFlag="android.content.pm.verification_service" />
-
<!--
This permission allows the system to receive PACKAGE_CHANGED broadcasts when the component
state of a non-exported component has been changed.
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_filled.xml b/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
index 0029de14e34a..6e74f64fea60 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
+++ b/core/res/res/drawable-watch-v36/btn_background_material_filled.xml
@@ -19,7 +19,7 @@
<item>
<shape android:shape="rectangle">
<solid android:color="@color/btn_material_filled_background_color"/>
- <corners android:radius="?android:attr/buttonCornerRadius"/>
+ <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
<size
android:width="@dimen/btn_material_width"
android:height="@dimen/btn_material_height" />
diff --git a/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml b/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
index 105f077cd841..fbd697371329 100644
--- a/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
+++ b/core/res/res/drawable-watch-v36/btn_background_material_filled_tonal.xml
@@ -19,7 +19,7 @@
<item>
<shape android:shape="rectangle">
<solid android:color="@color/btn_material_filled_tonal_background_color"/>
- <corners android:radius="?android:attr/buttonCornerRadius"/>
+ <corners android:radius="@dimen/config_wearMaterial3_buttonCornerRadius"/>
<size
android:width="@dimen/btn_material_width"
android:height="@dimen/btn_material_height" />
diff --git a/core/res/res/layout/notification_2025_template_heads_up_base.xml b/core/res/res/layout/notification_2025_template_heads_up_base.xml
new file mode 100644
index 000000000000..e4ff835a3524
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_heads_up_base.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ android:tag="headsUp"
+ >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:orientation="vertical"
+ >
+
+ <include
+ layout="@layout/notification_2025_template_collapsed_base"
+ android:id="@null"
+ />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-20dp"
+ android:clipChildren="false"
+ android:orientation="vertical"
+ >
+
+ <ViewStub
+ android:layout="@layout/notification_material_reply_text"
+ android:id="@+id/notification_material_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <include
+ layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ />
+
+ <include layout="@layout/notification_material_action_list" />
+ </LinearLayout>
+ </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9cfaca792f64..a4499efae37d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Laat die program toe om relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek te bepaal"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"om interaksie met wi‑fi-toestelle in die omtrek te hê"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Laat die program toe om op toestelle in die omtrek te adverteer, aan hulle te koppel en hul relatiewe posisie te bepaal"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"bepaal relatiewe posisie tussen toestelle in die omtrek"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Laat die app toe om relatiewe posisie tussen toestelle in die omtrek te bepaal"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Voorkeur-NFC-betalingdiensinligting"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Laat die program toe om voorkeur-NFC-betalingdiensinligting soos geregistreerde hulpmiddels en roetebestemming te kry."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"beheer kortveldkommunikasie"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Skakel aan"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gaan terug"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satelliet-SOS is nou beskikbaar"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Jy kan vir nooddienste ’n boodskap stuur as daar geen selfoon- of wi-fi-netwerk is nie. Google Boodskappe moet jou verstekboodskapapp wees."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelliet-SOS word nie gesteun nie"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satelliet-SOS word nie op hierdie toestel gesteun nie"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelliet-SOS is nie opgestel nie"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Maak seker jy is aan die internet gekoppel en probeer weer om op te stel"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelliet-SOS is nie beskikbaar nie"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelliet-SOS is nie in hierdie land of streek beskikbaar nie"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelliet-SOS is nie opgestel nie"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Stel Google Boodskappe as jou verstekboodskapapp op om boodskappe per satelliet te stuur"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satelliet-SOS is nie beskikbaar nie"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Skakel ligginginstellings aan om te kyk of satelliet-SOS in hierdie land of streek beskikbaar is"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellietboodskappe is beskikbaar"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Jy kan per satelliet ’n boodskap stuur as daar geen selfoon- of wi-fi-netwerk is nie. Google Boodskappe moet jou verstekboodskapapp wees."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellietboodskappe word nie gesteun nie"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellietboodskappe word nie op hierdie toestel gesteun nie"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellietboodskappe is nie opgestel nie"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Maak seker jy is aan die internet gekoppel en probeer weer om op te stel"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellietboodskappe is nie beskikbaar nie"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellietboodskappe is nie in hierdie land of streek beskikbaar nie"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellietboodskappe is nie opgestel nie"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Stel Google Boodskappe as jou verstekboodskapapp op om boodskappe per satelliet te stuur"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellietboodskappe is nie beskikbaar nie"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Skakel ligginginstellings aan om te kyk of satellietboodskappe in hierdie land of streek beskikbaar is"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c30a5c853421..225f04d53ad0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"በአቅራቢያ ባሉ ልዕለ-ሰፊ ባንድ መሣሪያዎች መካከል ያለውን አንጻራዊ አቀማመጣቸውን ለማወቅ ንዲችል ለመተግበሪያው ይፍቀዱ"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"በአቅራቢያ ካሉ የWi‑Fi መሣሪያዎች ጋር መስተጋብር መፍጠር"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"መተግበሪያው በአቅራቢያ ያሉ የWi-Fi መሣሪያዎች አንጻራዊ ቦታን እንዲያሳውቅ፣ እንዲያገናኝ እና እንዲያውቅ ያስችለዋል"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"በአቅራቢያ ባሉ መሣሪያዎች መካከል ያለውን አንጻራዊ አካባቢ ይወቁ"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"መተግበሪያው በአቅራቢያ ባሉ መሣሪያዎች መካከል ያለውን አንጻራዊ አካባቢ ለማወቅ እንዲችል ይፍቀዱለት"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ተመራጭ NFC የክፍያ አገልግሎት መረጃ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"እንደ የተመዘገቡ እርዳታዎች እና የጉዞ መሥመር መዳረሻ የመሳሰለ ተመራጭ nfc የክፍያ አገልግሎት መረጃን ለማግኘት ለመተግበሪያው ያፈቅድለታል።"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ቅርብ የግኑኙነትመስክ (NFC) ተቆጣጠር"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"አብራ"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ወደኋላ ተመለስ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ሳተላይት ኤስኦኤስ አሁን ይገኛል"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"ምንም የሞባይል ወይም Wi-Fi አውታረ መረብ ባይኖርም እንኳን ለድንገተኛ አደጋ አገልግሎቶች መልዕክት መላክ ይችላሉ። Google መልዕክቶች የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ መሆን አለበት።"</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ሳተላይት ኤስኦኤስ አይደገፍም"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"ሳተላይት ኤስኦኤስ በዚህ መሣሪያ ላይ አይደገፍም"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ሳተላይት ኤስኦኤስ አልተዋቀረም"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"ከበይነመረቡ ጋር መገናኘትዎን ያረጋግጡ እና ውቅረትን እንደገና ይሞክሩ"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ሳተላይት ኤስኦኤስ አይገኝም"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ሳተላይት ኤስኦኤስ በዚህ አገር ወይም ክልል ውስጥ አይገኝም"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ሳተላይት ኤስኦኤስ አልተዋቀረም"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"በሳተላይት መልዕክት ለመላክ Google መልዕክቶችን እንደ የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ ያቀናብሩ"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ሳተላይት ኤስኦኤስ አይገኝም"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"በዚህ አገር ወይም ክልል ውስጥ ሳተላይት ኤስኦኤስ እንደሚገኝ ለመፈተሽ የአካባቢ ቅንብሮችን ያብሩ"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"የሳተላይት መልዕክት ይገኛል"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"የሞባይል ወይም የWi-Fi አውታረ መረብ ከሌለ በሳተላይት መልዕክት መላክ ይችላሉ። Google መልዕክቶች የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ መሆን አለበት።"</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"የሳተላይት መልዕክት አይደገፍም"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"የሳተላይት መልዕክት በዚህ መሣሪያ ላይ አይደገፍም"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"የሳተላይት መልዕክት አልተዋቀረም"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"ከበይነመረቡ ጋር መገናኘትዎን ያረጋግጡ እና ውቅረትን እንደገና ይሞክሩ"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"የሳተላይት መልዕክት አይገኝም"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"የሳተላይት መልዕክት በዚህ አገር ወይም ክልል ውስጥ አይገኝም"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"የሳተላይት መልዕክት አልተዋቀረም"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"በሳተላይት መልዕክት ለመላክ Google መልዕክቶችን እንደ የእርስዎ ነባሪ የመልዕክት መላኪያ መተግበሪያ ያቀናብሩ"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"የሳተላይት መልዕክት አይገኝም"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"በዚህ አገር ወይም ክልል ውስጥ የሳተላይት መልዕክት እንደሚገኝ ለመፈተሽ የአካባቢ ቅንብሮችን ያብሩ"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም።"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f2080cbbe3d9..484d22047fcf 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -616,10 +616,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا."</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏التفاعل مع أجهزة Wi‑Fi المجاورة"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏للسماح للتطبيق بعرض الإعلانات والاتصال بالأجهزة الأخرى وتحديد الموقع النسبي لأجهزة Wi-Fi المجاورة."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"تحديد الموضع النسبي بين الأجهزة المجاورة"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 1f207d571c5a..fdddc70e56d3 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"এপ্‌টোক নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"নিকটৱৰ্তী ৱাই-ফাই ডিভাইচসমূহৰ সৈতে ভাব বিনিময় কৰক"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্‌টোক বিজ্ঞাপন প্ৰচাৰাভিযান কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"নিকটৱৰ্তী ডিভাইচৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰক"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"এপ্‌টোক নিকটৱৰ্তী ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্‌টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 07216f55bdcd..003c0dbc6f26 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tətbiqə yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etməyə icazə verin"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yaxınlıqdakı Wi-Fi cihazları ilə əlaqə qurmaq"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Tətbiqə yaxınlıqdakı Wi-Fi cihazlarında reklam etmək, onlara qoşulmaq və nisbi mövqeyini təyin etmək icazəsi verir"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"yaxınlıqdakı cihazlar arasında nisbi mövqeyin təyini"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Tətbiqin yaxınlıqdakı cihazlar arasında nisbi mövqeyi təyin etməsinə icazə verin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tərcih edilən NFC ödəniş xidməti məlumatı"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tətbiqə qeydiyyatdan keçmiş yardım və marşrut təyinatı kimi tərcih edilən nfc ödəniş xidməti məlumatını əldə etmək icazəsi verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication\'ı kontrol et"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktiv edin"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Geri qayıdın"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Təcili peyk bağlantısı artıq əlçatandır"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mobil və ya Wi-Fi şəbəkəsi yoxdursa, təcili xidmətlərə mesaj göndərə bilərsiniz. Google Mesajlar defolt mesajlaşma tətbiqiniz olmalıdır."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Təcili peyk bağlantısı dəstəklənmir"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Təcili peyk bağlantısı bu cihazda dəstəklənmir"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Təcili peyk bağlantısı ayarlanmayıb"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"İnternetə qoşulduğunuzdan əmin olun və yenidən ayarlamağa cəhd edin"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Təcili peyk bağlantısı əlçatan deyil"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Təcili peyk bağlantısı bu ölkə və ya regionda əlçatan deyil"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Təcili peyk bağlantısı ayarlanmayıb"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Peyk vasitəsilə mesaj göndərmək üçün Google Mesajları defolt mesajlaşma tətbiqi olaraq təyin edin"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Təcili peyk bağlantısı əlçatan deyil"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Bu ölkədə və ya regionda təcili peyk bağlantısının əlçatan olub-olmadığını yoxlamaq üçün məkan ayarlarını aktiv edin"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Peyk mesajlaşması əlçatandır"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Mobil və ya Wi-Fi şəbəkəsi yoxdursa, peyk vasitəsilə mesaj göndərə bilərsiniz. Google Mesajlar defolt mesajlaşma tətbiqiniz olmalıdır."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Peyk mesajlaşması dəstəklənmir"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Peyk mesajlaşması bu cihazda dəstəklənmir"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Peyk mesajlaşması quraşdırılmayıb"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"İnternetə qoşulduğunuzdan əmin olun və yenidən ayarlamağa cəhd edin"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Peyk mesajlaşması əlçatan deyil"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Peyk mesajlaşması bu ölkə və ya regionda əlçatan deyil"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Peyk mesajlaşması quraşdırılmayıb"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Peyk vasitəsilə mesaj göndərmək üçün Google Mesajları defolt mesajlaşma tətbiqi olaraq təyin edin"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Peyk mesajlaşması əlçatan deyil"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Bu ölkədə və ya regionda peyk mesajlaşmasının əlçatan olub-olmadığını yoxlamaq üçün məkan ayarlarını aktiv edin"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ac6a47fd8f84..5a848bafc7eb 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvoljava aplikaciji da određuje relativnu razdaljinu između uređaja ultra-širokog pojasa u blizini"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija sa WiFi uređajima u blizini"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i utvrđuje relativnu poziciju WiFi uređaja u blizini"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"određivanje razdaljine između uređaja u blizini"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Dozvolite aplikaciji da određuje relativnu razdaljinu između uređaja u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o željenoj NFC usluzi za plaćanje"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da preuzima informacije o željenoj NFC usluzi za plaćanje, poput registrovanih identifikatora aplikacija i odredišta preusmeravanja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrola komunikacije u užem polju (Near Field Communication)"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index f492bfa4cc7b..ce98a5ff7473 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дазволіць праграме вызначаць адлегласць паміж прыладамі паблізу, якія выкарыстоўваюць звышшырокапалосную сувязь"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"узаемадзейнічаць з прыладамі з Wi‑Fi паблізу"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Праграма зможа адпраўляць даныя на прылады Wi-Fi паблізу, падключацца да іх і вызначаць іх месцазнаходжанне"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"вызначаць адноснае месцазнаходжанне прылад паблізу"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Дазвольце праграме вызначаць адноснае месцазнаходжанне прылад паблізу"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Інфармацыя пра прыярытэтны сэрвіс аплаты NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дазваляе праграме атрымаць доступ да інфармацыі пра прыярытэтны сэрвіс аплаты NFC, напрыклад зарэгістраваныя ідэнтыфікатары праграм і маршруты адпраўкі даных."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"кантроль Near Field Communication"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index c8b171af5bc9..aad5d48f80cd 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Разрешаване на приложението да определя относителната позиция между устройствата с ултрашироколентови сигнали в близост"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"взаимодействие с устройствата с Wi-Fi в близост"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Разрешава на приложението да рекламира, да се свързва и да определя относителната позиция на устройствата с Wi-Fi в близост"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"опр. на относителната позиция м/у у-вата в близост"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Разрешаване на приложението да определя относителната позиция между устройствата в близост"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информация за предпочитаната услуга за плащане чрез NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дава възможност на приложението да получава информация за предпочитаната услуга за плащане чрез NFC, като например регистрирани помощни средства и местоназначение."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Включване"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Функцията „SOS чрез сателит“ вече е налице"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Можете да изпращате съобщения до службите за спешни случаи, ако нямате връзка с мобилна или Wi-Fi мрежа. Google Messages трябва да е основното ви приложение за съобщения."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Функцията „SOS чрез сателит“ не се поддържа"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Функцията „SOS чрез сателит“ не се поддържа на това устройство"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Функцията „SOS чрез сателит“ не е настроена"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Проверете дали имате връзка с интернет, и опитайте да настроите отново"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Функцията „SOS чрез сателит“ не е налице"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Функцията „SOS чрез сателит“ не е налице в тази държава или регион"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Функцията „SOS чрез сателит“ не е настроена"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"За да изпращате съобщения чрез сателит, задайте Google Messages като основното си приложение за съобщения"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Функцията „SOS чрез сателит“ не е налице"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"За да проверите дали функцията „SOS чрез сателит“ е налице в тази държава или регион, включете настройките за местоположението"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Функцията за сателитни съобщения е налице"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Можете да изпращате съобщения чрез сателит, ако нямате връзка с мобилна или Wi-Fi мрежа. Google Messages трябва да е основното ви приложение за съобщения."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Функцията за сателитни съобщения не се поддържа"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Функцията за сателитни съобщения не се поддържа на това устройство"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Функцията за сателитни съобщения не е настроена"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Проверете дали имате връзка с интернет, и опитайте да настроите отново"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Функцията за сателитни съобщения не е налице"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Функцията за сателитни съобщения не е налице в тази държава или регион"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Функцията за сателитни съобщения не е настроена"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"За да изпращате съобщения чрез сателит, задайте Google Messages като основното си приложение за съобщения"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Функцията за сателитни съобщения не е налице"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"За да проверите дали функцията за сателитни съобщения е налице в тази държава или регион, включете настройките за местоположението"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 0e103cc424b0..d52f6e91f45b 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"অ্যাপকে আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"আশপাশের ওয়াই-ফাই ডিভাইসের সাথে ইন্টার‍্যাক্ট করুন"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এটির ফলে অ্যাপ আশপাশের ওয়াই-ফাই ডিভাইসের তথ্য দেখতে, তাদের সাথে কানেক্ট করতে এবং তা কত দূরত্বে আছে সেটি জানতে পারবে"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"আশেপাশের ডিভাইসের আপেক্ষিক অবস্থান নির্ণয় করুন"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"অ্যাপকে আশেপাশের ডিভাইসের আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"পছন্দের NFC পেমেন্ট পরিষেবার তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"অ্যাপের মাধ্যমে পছন্দসই এনএফসি পেমেন্ট পরিষেবার তথ্য, যেমন রেজিস্ট্রার করার সহায়তা এবং রুট ডেস্টিনেশন সম্পর্কিত তথ্য অ্যাক্সেস করার অনুমতি দেয়।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 202afdeb9438..b74b13966405 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dozvolite aplikaciji da odredi relativni položaj između uređaja ultra širokog opsega u blizini"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"stupanje u interakciju s WiFi uređajima u blizini"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Dozvoljava aplikaciji da se oglašava, povezuje i određuje relativni položaj WiFi uređaja u blizini"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"određivanje relativnog položaja uređaja u blizini"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Dozvolite aplikaciji da odredi relativni položaj između uređaja u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja putem NFC-a"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Dozvoljava aplikaciji da dobije informacije o preferiranoj usluzi plaćanja putem NFC-a kao što su registrirana pomagala i odredište rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje NFC-om"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8b28cd7891c8..7500122e6d94 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permet que l\'aplicació determini la posició relativa entre els dispositius de banda ultraampla propers"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interaccionar amb els dispositius Wi‑Fi propers"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet que l\'aplicació s\'anunciï i es connecti als dispositius Wi‑Fi propers, i en determini la posició relativa"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determin. posició relativa entre dispositius propers"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permet que l\'aplicació determini la posició relativa entre els dispositius propers"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informació preferent sobre el servei de pagament per NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet que l\'aplicació obtingui informació preferent sobre el servei de pagament per NFC, com ara complements registrats i destinacions de rutes."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicació de camp proper (NFC)"</string>
@@ -2436,54 +2434,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activa"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Torna"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS per satèl·lit ja està disponible"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Pots enviar missatges als serveis d\'emergències si no tens cap xarxa mòbil ni Wi‑Fi. Missatges de Google ha de ser l\'aplicació de missatgeria predeterminada."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS per satèl·lit no s\'admet"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS per satèl·lit no s\'admet en aquest dispositiu"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS per satèl·lit no està configurat"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Comprova que tinguis connexió a Internet i torna a provar de configurar-lo"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS per satèl·lit no està disponible"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS per satèl·lit no està disponible en aquest país o regió"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS per satèl·lit no està configurat"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Per enviar missatges per satèl·lit, defineix Missatges de Google com a aplicació de missatgeria predeterminada"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS per satèl·lit no està disponible"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Per comprovar si SOS per satèl·lit està disponible en aquest país o regió, activa la configuració d\'ubicació"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Missatges per satèl·lit disponibles"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Pots enviar missatges per satèl·lit si no tens cap xarxa mòbil ni Wi‑Fi. Missatges de Google ha de ser l\'aplicació de missatgeria predeterminada."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Els missatges per satèl·lit no s\'admeten"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Els missatges per satèl·lit no s\'admeten en aquest dispositiu"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Els missatges per satèl·lit no estan configurats"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Comprova que tinguis connexió a Internet i torna a provar de configurar-los"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Els missatges per satèl·lit no estan disponibles"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Els missatges per satèl·lit no estan disponibles en aquest país o regió"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Els missatges per satèl·lit no estan configurats"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Per enviar missatges per satèl·lit, defineix Missatges de Google com a aplicació de missatgeria predeterminada"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Els missatges per satèl·lit no estan disponibles"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Per comprovar si els missatges per satèl·lit estan disponibles en aquest país o regió, activa la configuració d\'ubicació"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f3a020bbfce4..277d359e5fd0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikace bude moci zjišťovat vzájemnou pozici mezi ultra-širokopásmovými zařízeními v okolí"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakce se zařízeními Wi-Fi v okolí"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Umožňuje aplikaci inzerovat, připojovat se a odhadovat relativní polohu zařízení Wi-Fi v okolí"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"zjišťování vzájemné pozice mezi zařízeními v okolí"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Aplikace bude moci zjišťovat vzájemnou pozici mezi zařízeními v okolí"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informace o preferované platební službě NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikaci získat informace o preferované platební službě NFC, například o registrovaných pomůckách a cíli směrování."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládání technologie NFC"</string>
@@ -2437,54 +2435,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnout"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Zpět"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"K dispozici je funkce SOS přes satelit"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Pokud není k dispozici mobilní síť ani Wi-Fi, můžete na tísňovou linku poslat zprávu. Jako výchozí aplikace na odesílání zpráv musí být nastavené Google zprávy."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Funkce SOS přes satelit není podporována"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Funkce SOS přes satelit není na tomto zařízení podporována"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Funkce SOS přes satelit není nastavena"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Zkontrolujte připojení k internetu a zkuste nastavení provést znovu"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Funkce SOS přes satelit není k dispozici"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS před satelit není v této zemi nebo oblasti k dispozici"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Funkce SOS přes satelit není nastavena"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pokud chcete odesílat zprávy přes satelit, nastavte Google zprávy jako výchozí aplikaci na odesílání zpráv"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Funkce SOS přes satelit není k dispozici"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Pokud chcete zjistit, zda je v této zemi nebo oblasti dostupná funkce SOS přes satelit, zapněte nastavení polohy"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Jsou k dispozici satelitní zprávy"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Pokud není k dispozici mobilní síť ani Wi-Fi, můžete odesílat zprávy přes satelit. Jako výchozí aplikace na odesílání zpráv musí být nastavené Google zprávy."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelitní zprávy nejsou podporovány"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelitní zprávy nejsou na tomto zařízení podporovány"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelitní zprávy nejsou nastaveny"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Zkontrolujte připojení k internetu a zkuste nastavení provést znovu"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelitní zprávy nejsou k dispozici"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelitní zprávy nejsou v této zemi nebo oblasti dostupné"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelitní zprávy nejsou nastaveny"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pokud chcete odesílat zprávy přes satelit, nastavte Google zprávy jako výchozí aplikaci na odesílání zpráv"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelitní zprávy nejsou k dispozici"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Pokud chcete zjistit, zda jsou v této zemi nebo oblasti dostupné satelitní zprávy, zapněte nastavení polohy"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index b481682b0448..9db6076ee6fa 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillad, at appen fastlægger den relative position mellem UWB-enheder (Ultra-Wideband) i nærheden"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagere med Wi‑Fi-enheder i nærheden"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Giver appen tilladelse til at informere om, oprette forbindelse til og fastslå den relative placering af Wi‑Fi-enheder i nærheden"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"fastlægge relativ position mellem enheder i nærheden"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Tillad, at appen fastlægger den relative position mellem enheder i nærheden"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Foretrukne oplysninger vedrørende NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillader, at appen får foretrukne oplysninger vedrørende NFC-betalingstjeneste, f.eks. registrerede hjælpemidler og rutedestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivér"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gå tilbage"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS-meldinger via satellit er nu tilgængelig"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Du kan sende beskeder til nødtjenester, hvis du ikke har forbindelse til et mobil- eller Wi-Fi-netværk. Google Beskeder skal være din standardapp til beskeder."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS-meldinger via satellit understøttes ikke"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS-meldinger via satellit understøttes ikke på denne enhed"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS-meldinger via satellit er ikke konfigureret"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Sørg for, at du har forbindelse til internettet, og prøv at konfigurere igen"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS-meldinger via satellit er ikke tilgængelig"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS-meldinger via satellit er ikke tilgængelig i dette land eller denne region"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS-meldinger via satellit er ikke konfigureret"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Hvis du vil sende beskeder via satellit, skal du angive Google Beskeder som din standardapp til beskeder"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS-meldinger via satellit er ikke tilgængelig"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Hvis du vil tjekke, om SOS-meldinger via satellit er tilgængelig i dette land eller denne region, skal du aktivere lokationsindstillinger"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellitbeskeder er tilgængelige"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Du kan sende beskeder via satellit, hvis du ikke har forbindelse til et mobil- eller Wi-Fi-netværk. Google Beskeder skal være din standardapp til beskeder."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellitbeskeder understøttes ikke"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellitbeskeder understøttes ikke på denne enhed"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellitbeskeder er ikke konfigureret"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Sørg for, at du har forbindelse til internettet, og prøv at konfigurere igen"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellitbeskeder er ikke tilgængelige"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellitbeskeder er ikke tilgængelige i dette land eller denne region"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellitbeskeder er ikke konfigureret"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Hvis du vil sende beskeder via satellit, skal du angive Google Beskeder som din standardapp til beskeder"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellitbeskeder er ikke tilgængelige"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Hvis du vil tjekke, om satellitbeskeder er tilgængelige i dette land eller denne region, skal du aktivere lokationsindstillinger"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 64afb5adffc4..9561b3f8a3c5 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ermöglicht der App, die relative Distanz zwischen Ultrabreitband-Geräten in der Nähe zu bestimmen"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mit WLAN-Geräten in der Nähe interagieren"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Erlaubt der App, Inhalte an WLAN-Geräte in der Nähe zu senden, sich mit ihnen zu verbinden und ihre relative Position zu ermitteln"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"Relative Position zu Geräten in der Nähe bestimmen"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Ermöglicht es der App, die relative Position zu Geräten in der Nähe zu bestimmen"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informationen zum bevorzugten NFC-Zahlungsdienst"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ermöglicht der App, Informationen zum bevorzugten NFC-Zahlungsdienst abzurufen, etwa registrierte Hilfsmittel oder das Routenziel."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivieren"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Zurück"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"„Notruf über Satellit“ jetzt verfügbar"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Du kannst dem Rettungsdienst eine Nachricht senden, wenn kein Mobilfunknetz oder WLAN verfügbar ist. Dazu muss Google Messages als Standard-Messaging-App festgelegt sein."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"„Notruf über Satellit“ nicht unterstützt"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"„Notruf über Satellit“ wird auf diesem Gerät nicht unterstützt"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"„Notruf über Satellit“ nicht eingerichtet"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Vergewissere dich, dass du mit dem Internet verbunden bist, und versuche noch einmal, die Einrichtung durchzuführen"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"„Notruf über Satellit“ nicht verfügbar"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"„Notruf über Satellit“ ist in diesem Land oder in dieser Region nicht verfügbar"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"„Notruf über Satellit“ nicht eingerichtet"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Wenn du Nachrichten per Satellit senden möchtest, musst du Google Messages als Standard-Messaging-App festlegen"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"„Notruf über Satellit“ nicht verfügbar"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Wenn du wissen möchtest, ob „Notruf über Satellit“ in diesem Land oder dieser Region verfügbar ist, aktiviere die Standorteinstellungen"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"„Nachrichten per Satellit“ verfügbar"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Du kannst Nachrichten per Satellit senden, wenn kein Mobilfunknetz oder WLAN verfügbar ist. Dazu muss Google Messages als Standard-Messaging-App festgelegt sein."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"„Nachrichten per Satellit“ nicht unterstützt"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"„Nachrichten per Satellit“ wird auf diesem Gerät nicht unterstützt"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"„Nachrichten per Satellit“ nicht eingerichtet"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Vergewissere dich, dass du mit dem Internet verbunden bist, und versuche noch einmal, die Einrichtung durchzuführen"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"„Nachrichten per Satellit“ nicht verfügbar"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"„Nachrichten per Satellit“ ist in diesem Land oder dieser Region nicht verfügbar"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"„Nachrichten per Satellit“ nicht eingerichtet"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Wenn du Nachrichten per Satellit senden möchtest, musst du Google Messages als Standard-Messaging-App festlegen"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"„Nachrichten per Satellit“ nicht verfügbar"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Wenn du wissen möchtest, ob „Nachrichten per Satellit“ in diesem Land oder dieser Region verfügbar ist, aktiviere die Standorteinstellungen"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4ad85d97201a..551fe701e7dd 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Επιτρέψτε στην εφαρμογή να προσδιορίζει τη σχετική θέση μεταξύ κοντινών συσκευών Ultra-Wideband"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"αλληλεπίδραση με κοντινές συσκευές Wi‑Fi"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Επιτρέπει στην εφαρμογή: προβολή διαφημίσεων, σύνδεση και καθορισμό της σχετικής τοποθεσίας των κοντινών συσκευών Wi‑Fi"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"προσδιορ. σχετ. θέσης μεταξύ συσκ. σε κοντ. απόστ."</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Επιτρέψτε στην εφαρμογή να προσδιορίζει τη σχετική θέση μεταξύ συσκευών σε κοντινή απόσταση"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Πληροφορίες προτιμώμενης υπηρεσίας πληρωμών NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Επιτρέπει στην εφαρμογή να λαμβάνει πληροφορίες προτιμώμενης υπηρεσίας πληρωμής NFC, όπως καταχωρημένα βοηθήματα και προορισμό διαδρομής."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ελέγχει την Επικοινωνία κοντινού πεδίου (FNC)"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ενεργοποίηση"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Επιστροφή"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Το δορυφορικό SOS είναι πλέον διαθέσιμο"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Μπορείτε να στέλνετε μηνύματα σε υπηρεσίες έκτακτης ανάγκης, εάν δεν υπάρχει δίκτυο κινητής τηλεφωνίας ή Wi-Fi. Το Google Messages πρέπει να είναι η προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Το δορυφορικό SOS δεν υποστηρίζεται"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Το δορυφορικό SOS δεν υποστηρίζεται σε αυτή τη συσκευή"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Το δορυφορικό SOS δεν έχει ρυθμιστεί"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Βεβαιωθείτε ότι είστε συνδεδεμένοι στο διαδίκτυο και δοκιμάστε ξανά τη ρύθμιση"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Το δορυφορικό SOS δεν είναι διαθέσιμο"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Το δορυφορικό SOS δεν είναι διαθέσιμο σε αυτή τη χώρα ή την περιοχή"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Το δορυφορικό SOS δεν έχει ρυθμιστεί"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Για να ανταλλάζετε μηνύματα μέσω δορυφόρου, ορίστε το Google Messages ως την προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Το δορυφορικό SOS δεν είναι διαθέσιμο"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Για να ελέγξετε αν το δορυφορικό SOS είναι διαθέσιμο σε αυτή τη χώρα ή την περιοχή, ενεργοποιήστε τις ρυθμίσεις τοποθεσίας"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου είναι διαθέσιμη"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Μπορείτε να ανταλλάζετε μηνύματα μέσω δορυφόρου, εάν δεν υπάρχει δίκτυο κινητής τηλεφωνίας ή Wi-Fi. Το Google Messages πρέπει να είναι η προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν υποστηρίζεται"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν υποστηρίζεται σε αυτή τη συσκευή"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν έχει ρυθμιστεί"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Βεβαιωθείτε ότι είστε συνδεδεμένοι στο διαδίκτυο και δοκιμάστε ξανά τη ρύθμιση"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν είναι διαθέσιμη"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν είναι διαθέσιμη σε αυτή τη χώρα ή την περιοχή"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν έχει ρυθμιστεί"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Για να ανταλλάζετε μηνύματα μέσω δορυφόρου, ορίστε το Google Messages ως την προεπιλεγμένη εφαρμογή ανταλλαγής μηνυμάτων"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Η ανταλλαγή μηνυμάτων μέσω δορυφόρου δεν είναι διαθέσιμη"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Για να ελέγξετε αν η ανταλλαγή μηνυμάτων μέσω δορυφόρου είναι διαθέσιμη σε αυτή τη χώρα ή την περιοχή, ενεργοποιήστε τις ρυθμίσεις τοποθεσίας"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index a82b567a087e..5cedb1fa6655 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determine relative position between nearby devices"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Allow the app to determine relative position between nearby devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bf3b985ae6e8..4e728ff0f814 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determine relative position between nearby devices"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Allow the app to determine relative position between nearby devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 5c9c52148750..578e4795f2b4 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Allow the app to determine relative position between nearby ultra-wideband devices"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interact with nearby Wi‑Fi devices"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Allows the app to advertise, connect and determine the relative position of nearby Wi‑Fi devices"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determine relative position between nearby devices"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Allow the app to determine relative position between nearby devices"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferred NFC payment service information"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Allows the app to get preferred NFC payment service information, such as registered aids and route destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"control Near-Field Communication"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index ab6f6ce07c1d..da3c4c4c27eb 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la app determine la posición relativa con dispositivos Ultra Wideband cercanos"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos Wi-Fi cercanos"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que la app muestre anuncios, se conecte y determine la posición relativa de los dispositivos Wi-Fi cercanos"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determinar posición relativa entre disp. cercanos"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permite que la app determine la posición relativa con dispositivos cercanos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre servicio de pago NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la app reciba información del servicio de pago NFC preferido, como el servicio de asistencia registrado y el destino de la ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar la Transmisión de datos en proximidad"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 23e1ae635730..37bf70e9bbd1 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la aplicación determine la posición relativa de los dispositivos de banda ultraancha cercanos"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos Wi-Fi cercanos"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite a la aplicación emitir y conectarse a dispositivos Wi-Fi cercanos y determinar su posición relativa"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determinar posición relativa de dispositivos cercanos"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permite que la aplicación determine la posición relativa de los dispositivos cercanos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la aplicación obtenga información sobre el servicio de pago por NFC preferido, como identificadores de aplicación registrados y destinos de rutas."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
@@ -1411,7 +1409,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Se ha detectado un accesorio de audio analógico"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Depuración por USB activa"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar depuración USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar la depuración por USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Seleccionar para inhabilitar la depuración por USB"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuración inalámbrica conectada"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar la depuración inalámbrica"</string>
@@ -2436,54 +2434,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Volver"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS por satélite ya está disponible"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Puedes enviar mensajes a los servicios de emergencias si no hay una red móvil o Wi-Fi disponible. Mensajes de Google debe ser tu aplicación de mensajería predeterminada."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"No se admite SOS por satélite"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Este dispositivo no admite SOS por satélite"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS por satélite no está configurado"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Comprueba que tienes conexión a Internet e inténtalo de nuevo"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS por satélite no está disponible"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS por satélite no está disponible en este país o territorio"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS por satélite no configurado"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Para enviar mensajes por satélite, configura Mensajes de Google como tu aplicación de mensajería predeterminada"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS por satélite no está disponible"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Para comprobar si SOS por satélite está disponible en este país o territorio, activa los ajustes de ubicación"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Mensajes por satélite disponibles"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Puedes enviar mensajes por satélite si no hay una red móvil o Wi-Fi disponible. Mensajes de Google debe ser tu aplicación de mensajería predeterminada."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Mensajes por satélite no admitidos"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Este dispositivo no admite los mensajes por satélite"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mensajes por satélite no configurados"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Comprueba que tienes conexión a Internet e inténtalo de nuevo"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Mensajes por satélite no disponibles"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Los mensajes por satélite no están disponibles en este país o territorio"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mensajes por satélite no configurados"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Para enviar mensajes por satélite, configura Mensajes de Google como tu aplicación de mensajería predeterminada"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Mensajes por satélite no disponibles"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Para comprobar si los mensajes por satélite están disponibles en este país o territorio, activa los ajustes de ubicación"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index d22c93b30ac9..0d79e8aa0333 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Võimaldab rakendusel määrata lähedalasuvate ülilairibaühendust kasutavate seadmete suhtelise kauguse üksteisest"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Läheduses olevate WiFi-seadmetega suhtlemine"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lubab rakendusel läheduses olevatele WiFi-seadmetele reklaamida, nendega ühenduse luua ja määrata nende suhteline asend"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"Määrata läheduses olevate seadmete suhtelise kauguse üksteisest."</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Võimaldab rakendusel määrata läheduses olevate seadmete suhtelise kauguse üksteisest"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Eelistatud NFC-makseteenuse teave"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Võimaldab rakendusel hankida eelistatud NFC-makseteenuse teavet (nt registreeritud abi ja marsruudi sihtkoht)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lähiväljaside juhtimine"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Lülita sisse"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Mine tagasi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satelliit-SOS on nüüd saadaval"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Saate hädaabiteenustele sõnumi saata, kui mobiilside- või WiFi-võrku pole. Google Messages peab olema teie vaikesõnumsiderakendus."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelliit-SOSi ei toetata"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"See seade ei toeta satelliit-SOSi"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelliit-SOS pole seadistatud"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Veenduge, et teil oleks internetiühendus, ja proovige uuesti seadistada"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelliit-SOS pole saadaval"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelliit-SOS ei ole selles riigis või piirkonnas saadaval"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelliit-SOSi pole seadistatud"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Satelliidi teel sõnumite saatmiseks määrake Google Messages oma sõnumside vaikerakenduseks"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satelliit-SOS pole saadaval"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Et kontrollida, kas satelliit-SOS on selles riigis või piirkonnas saadaval, lülitage sisse asukohaseaded"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Saadaval on satelliidipõhine sõnumside"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Kui mobiilside- või WiFi-võrku pole, saate sõnumeid saata satelliidi teel. Google Messages peab olema teie vaikesõnumsiderakendus."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelliidipõhist sõnumsidet ei toetata"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"See seade ei toeta satelliidipõhist sõnumsidet"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelliidipõhine sõnumside pole seadistatud"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Veenduge, et teil oleks internetiühendus, ja proovige uuesti seadistada"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelliidipõhine sõnumside pole saadaval"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelliidipõhine sõnumside ei ole selles riigis või piirkonnas saadaval"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelliidipõhine sõnumside pole seadistatud"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Satelliidi teel sõnumite saatmiseks määrake Google Messages oma sõnumside vaikerakenduseks"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelliidipõhine sõnumside pole saadaval"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Et kontrollida, kas satelliidipõhine sõnumside on selles riigis või piirkonnas saadaval, lülitage sisse asukohaseaded"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 914dfb72c06e..b96f9eb97c21 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen dio aplikazioari"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"inguruko wifi-gailuekin interakzioan jardun"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Inguruko wifi-gailuetan iragartzeko, haiekin konektatzeko eta haien kokapena zehazteko baimena ematen dio aplikazioari"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"zehaztu inguruko gailuen arteko distantzia erlatiboa"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen dio aplikazioari"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko baimena ematen dio aplikazioari, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktibatu"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Egin atzera"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satelite bidezko SOS komunikazioa erabilgarri dago orain"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Larrialdi-zerbitzuekin mezuak trukatu ahal izango dituzu sare mugikorrik edo wifi-sarerik ez badago. Google-ren Mezuak aplikazioak izan behar du mezularitza-aplikazio lehenetsia."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satelite bidezko SOS komunikazioa ez da bateragarria"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satelite bidezko SOS komunikazioa ez da bateragarria gailu honekin"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satelite bidezko SOS komunikazioa ez dago konfiguratuta"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Ziurtatu Internetera konektatuta zaudela eta saiatu konfiguratzen berriro"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satelite bidezko SOS komunikazioa ez dago erabilgarri"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satelite bidezko SOS komunikazioa ez dago erabilgarri herrialde edo lurralde honetan"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satelite bidezko SOS komunikazioa ez dago konfiguratuta"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Satelite bidez mezuak trukatzeko, ezarri Google-ren Mezuak mezularitza-aplikazio lehenetsi gisa"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satelite bidezko SOS komunikazioa ez dago erabilgarri"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Herrialde edo lurralde honetan satelite bidezko SOS komunikazioa erabilgarri dagoen egiaztatzeko, aktibatu kokapen-ezarpenak"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satelite bidezko mezularitza erabilgarri dago"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Satelite bidez trukatu ahal izango dituzu mezuak sare mugikorrik edo wifi-sarerik ez badago. Google-ren Mezuak aplikazioak izan behar du mezularitza-aplikazio lehenetsia."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelite bidezko mezularitza ez da bateragarria"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelite bidezko mezularitza ez da bateragarria gailu honekin"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelite bidezko mezularitza ez dago konfiguratuta"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Ziurtatu Internetera konektatuta zaudela eta saiatu konfiguratzen berriro"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelite bidezko mezularitza ez dago erabilgarri"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelite bidezko mezularitza ez dago erabilgarri herrialde edo lurralde honetan"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelite bidezko mezularitza ez dago konfiguratuta"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Satelite bidez mezuak trukatzeko, ezarri Google-ren Mezuak mezularitza-aplikazio lehenetsi gisa"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelite bidezko mezularitza ez dago erabilgarri"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Herrialde edo lurralde honetan satelite bidezko mezularitza erabilgarri dagoen egiaztatzeko, aktibatu kokapen-ezarpenak"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c3e4b4680752..7627ff37d2bc 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"به برنامه اجازه داده می‌شود موقعیت نسبی بین دستگاه‌های «فراپهن‌باند» اطراف را مشخص کند"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏برقراری تعامل با دستگاه‌های Wi-Fi اطراف"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏به برنامه اجازه می‌دهد در دستگاه‌های Wi-Fi اطراف تبلیغ کند، به آن‌ها متصل شود، و موقعیت نسبی آن‌ها را تشخیص دهد"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"تعیین موقعیت نسبی بین دستگاه‌های اطراف"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"به برنامه اجازه داده می‌شود موقعیت نسبی بین دستگاه‌های اطراف را تعیین کند"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏اطلاعات ترجیحی سرویس پرداخت NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏به برنامه اجازه می‌دهد اطلاعات ترجیحی سرویس پرداخت NFC، مانند کمک‌های ثبت‌شده و مقصد مسیر را دریافت کند."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"کنترل ارتباط راه نزدیک"</string>
@@ -918,7 +916,7 @@
<string name="phoneTypeCustom" msgid="5120365721260686814">"سفارشی"</string>
<string name="phoneTypeHome" msgid="3880132427643623588">"خانه"</string>
<string name="phoneTypeMobile" msgid="1178852541462086735">"تلفن همراه"</string>
- <string name="phoneTypeWork" msgid="6604967163358864607">"کاری"</string>
+ <string name="phoneTypeWork" msgid="6604967163358864607">"محل کار"</string>
<string name="phoneTypeFaxWork" msgid="6757519896109439123">"نمابر محل کار"</string>
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"نمابر خانه"</string>
<string name="phoneTypePager" msgid="576402072263522767">"پی‌جو"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"روشن کردن"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"برگشتن"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"«درخواست کمک ماهواره‌ای» اکنون دردسترس است"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"‏اگر شبکه Wi-Fi یا تلفن همراه وجود ندارد، می‌توانید به خدمات اضطراری پیام ارسال کنید. «پیام‌نگار Google» باید برنامه پیام‌رسانی پیش‌فرض شما باشد."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"«درخواست کمک ماهواره‌ای» پشتیبانی نمی‌شود"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"«درخواست کمک ماهواره‌ای» در این دستگاه پشتیبانی نمی‌شود"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"«درخواست کمک ماهواره‌ای» راه‌اندازی نشده است"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"مطمئن شوید به اینترنت متصل هستید و دوباره راه‌اندازی را امتحان کنید"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"«درخواست کمک ماهواره‌ای» دردسترس نیست"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"«درخواست کمک ماهواره‌ای» در این کشور یا منطقه دردسترس نیست"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"درخواست کمک ماهواره‌ای راه‌اندازی نمی‌شود"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"‏برای ارسال پیام ازطریق ماهواره، «پیام‌نگار Google» را به‌عنوان برنامه پیام‌رسانی پیش‌فرض تنظیم کنید"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"«درخواست کمک ماهواره‌ای» دردسترس نیست"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"برای بررسی دردسترس بودن «درخواست کمک ماهواره‌ای» در این کشور یا منطقه، تنظیمات مکان را روشن کنید"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"پیام‌رسانی ماهواره‌ای دردسترس است"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"‏اگر شبکه تلفن همراه یا Wi-Fi وجود ندارد، می‌توانید ازطریق ماهواره پیام ارسال کنید. «پیام‌نگار Google» باید برنامه پیام‌رسانی پیش‌فرض شما باشد."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"پیام‌رسانی ماهواره‌ای پشتیبانی نمی‌شود"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"پیام‌رسانی ماهواره‌ای در این دستگاه پشتیبانی نمی‌شود"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"پیام‌رسانی ماهواره‌ای راه‌اندازی نمی‌شود"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"مطمئن شوید به اینترنت متصل هستید و دوباره راه‌اندازی را امتحان کنید"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"پیام‌رسانی ماهواره‌ای دردسترس نیست"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"پیام‌رسانی ماهواره‌ای در این کشور یا منطقه دردسترس نیست"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"پیام‌رسانی ماهواره‌ای راه‌اندازی نمی‌شود"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"‏برای ارسال پیام ازطریق ماهواره، «پیام‌نگار Google» را به‌عنوان برنامه پیام‌رسانی پیش‌فرض تنظیم کنید"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"پیام‌رسانی ماهواره‌ای دردسترس نیست"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"برای بررسی دردسترس بودن پیام‌رسانی ماهواره‌ای در این کشور یا منطقه، تنظیمات مکان را فعال کنید"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راه‌اندازی مجدد «قفل‌گشایی با اثر انگشت»"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابل‌شناسایی نیست."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابل‌شناسایی نیستند."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index fb7c4fed3f47..78fb2a07f756 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Sallii sovelluksen määrittää UVB-taajuutta käyttävien laitteiden sijainnin suhteessa toisiinsa"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"käyttää lähellä olevia Wi-Fi-laitteita"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Sallii sovelluksen ilmoittaa ja määrittää lähellä olevien Wi-Fi-laitteiden suhteellisen sijainnin sekä yhdistää niihin"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"määrittää laitteiden suhteellisen sijainnin"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Sallii sovelluksen määrittää lähellä olevien laitteiden sijainnin suhteessa toisiinsa"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ensisijaiset NFC-maksupalvelutiedot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Sallii sovelluksen noutaa tietoja rekisteröidyistä sovellustunnuksista, maksureitin kohteesta ja muita ensisijaisia NFC-maksupalvelutietoja."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"hallitse Near Field Communication -tunnistusta"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Laita päälle"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Takaisin"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS on nyt käytettävissä"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Voit lähettää viestin hätäkeskukseen, jos sinulla ei ole mobiili‑ tai Wi-Fi-verkkoyhteyttä. Google Messages täytyy valita oletusviestisovellukseksi."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS ei tueta"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS ei tueta tällä laitteella"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS ei ole otettu käyttöön"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Varmista, että internetyhteys on muodostettu, ja yritä käyttöönottoa uudelleen"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS ei ole saatavilla"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS ei ole saatavilla tällä alueella"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS ei ole otettu käyttöön"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Jos haluat lähettää viestejä satelliitin kautta, aseta Google Messages oletusviestisovellukseksi"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS ei ole saatavilla"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Voit tarkistaa, onko Satellite SOS saatavilla tällä alueella, laittamalla sijaintiasetukset päälle"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satelliittiviestintä saatavilla"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Voit lähettää viestin satelliitin kautta, jos sinulla ei ole mobiili‑ tai Wi-Fi-verkkoyhteyttä. Google Messages täytyy valita oletusviestisovellukseksi."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelliittiviestintää ei tueta"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satelliittiviestejä ei tueta tällä laitteella"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelliittiviestintää ei ole otettu käyttöön"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Varmista, että internetyhteys on muodostettu, ja yritä käyttöönottoa uudelleen"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelliittiviestintä ei ole käytettävissä"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satelliittiviestintä ei ole saatavilla tällä alueella"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelliittiviestintää ei ole otettu käyttöön"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Jos haluat lähettää viestejä satelliitin kautta, aseta Google Messages oletusviestisovellukseksi"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelliittiviestintä ei ole käytettävissä"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Voit tarkistaa, onko satelliittiviestit saatavilla tällä alueella, laittamalla sijaintiasetukset päälle"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 18ef10995e90..163d70d49230 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'appli à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"Dét. position relative entre appareils à proximité"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Autorisez l\'appli à déterminer la position relative entre des appareils à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement CCP"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'appli d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index bd064d1dc61e..75b8e3125da0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autoriser l\'appli à déterminer la position relative entre des appareils ultra-wideband à proximité"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de déterminer la position approximative des appareils Wi‑Fi à proximité, de les afficher et de s\'y connecter"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"déterminer l\'emplacement relatif entre des appareils à proximité"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Autorisez l\'appli à déterminer l\'emplacement relatif entre des appareils à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir des informations sur le service de paiement NFC préféré, y compris les ID d\'applications et les destinations de routage enregistrés."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
@@ -2436,54 +2434,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activer"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retour"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS par satellite est maintenant disponible"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Vous pouvez envoyer des messages aux services d\'urgence s\'il n\'y a pas de réseau mobile ou Wi-Fi. Google Messages doit être votre application de chat par défaut."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS par satellite n\'est pas disponible"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS par satellite n\'est pas disponible sur cet appareil"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS par satellite n\'est pas configuré"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Vérifiez votre connexion à Internet, puis essayez à nouveau de lancer la configuration."</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS par satellite n\'est pas disponible"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS par satellite n\'est pas disponible dans ce pays ou cette région"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS par satellite non configuré"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pour envoyer des messages par satellite, définissez Google Messages comme application de chat par défaut"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS par satellite n\'est pas disponible"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Pour savoir si SOS par satellite est disponible dans ce pays ou cette région, activez les paramètres de localisation"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Messagerie par satellite disponible"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Vous pouvez envoyer des messages par satellite s\'il n\'y a pas de réseau mobile ou Wi-Fi. Google Messages doit être votre application de chat par défaut."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Messagerie par satellite non disponible"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"La messagerie par satellite n\'est pas disponible sur cet appareil"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Messagerie par satellite non configurée"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Vérifiez votre connexion à Internet, puis essayez à nouveau de lancer la configuration."</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Messagerie par satellite non disponible"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"La messagerie par satellite n\'est pas disponible dans ce pays ou cette région"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Messagerie par satellite non configurée"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pour envoyer des messages par satellite, définissez Google Messages comme application de chat par défaut"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Messagerie par satellite non disponible"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Pour savoir si la messagerie par satellite est disponible dans ce pays ou cette région, activez les paramètres de localisation"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 292a952b1d46..70a7ec9c7a19 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos que usen banda ultralarga"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactuar con dispositivos wifi próximos"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permítelle á aplicación enviar anuncios e conectarse a dispositivos wifi próximos, e determinar a súa posición relativa"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"fixar a posición relativa entre disp. próximos"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permite que a aplicación determine a posición relativa entre os dispositivos próximos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información do servizo de pagos de NFC preferido"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a aplicación obteña información do servizo de pagos de NFC preferido, como as axudas rexistradas e o destino da ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar Near Field Communication"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Activar"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Volver"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS por satélite xa está dispoñible"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Podes enviar mensaxes aos servizos de emerxencia se non tes conexión con ningunha rede wifi nin de telefonía móbil. Debes ter definida Mensaxes de Google como aplicación predeterminada de mensaxaría."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Non se admite SOS por satélite"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Non se admite SOS por satélite neste dispositivo"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS por satélite non se configurou"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Asegúrate de ter conexión a Internet e tenta volver facer a configuración"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS por satélite non está dispoñible"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS por satélite non está dispoñible neste país ou rexión"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS por satélite non se configurou"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Para intercambiar mensaxes por satélite, cómpre establecer Mensaxes de Google como aplicación de mensaxaría predeterminada"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS por satélite non está dispoñible"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Para comprobar se está dispoñible SOS por satélite neste país ou rexión, activa a configuración de localización"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Mensaxaría por satélite dispoñible"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Podes intercambiar mensaxes por satélite se non tes conexión con ningunha rede wifi nin de telefonía móbil. Debes ter definida Mensaxes de Google como aplicación predeterminada de mensaxaría."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Mensaxaría por satélite non admitida"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Non se admite a mensaxaría por satélite neste dispositivo"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mensaxaría por satélite non configurada"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Asegúrate de ter conexión a Internet e tenta volver facer a configuración"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Mensaxaría por satélite non dispoñible"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"A mensaxaría por satélite non está dispoñible neste país ou rexión"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mensaxaría por satélite non configurada"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Para intercambiar mensaxes por satélite, cómpre establecer Mensaxes de Google como aplicación de mensaxaría predeterminada"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Mensaxaría por satélite non dispoñible"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Para ver se está dispoñible a mensaxaría por satélite neste país ou rexión, activa a configuración de localización"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 70454a307791..1535e4f5d463 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ઍપને નજીકના અલ્ટ્રા-વાઇડબૅન્ડ ડિવાઇસની વચ્ચેનું સંબંધિત અંતર નક્કી કરવાની મંજૂરી આપો"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"નજીકના વાઇ-ફાઇ ડિવાઇસ સાથે ક્રિયાપ્રતિક્રિયા કરો"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ઍપને નજીકના વાઇ-ફાઇ ડિવાઇસની માહિતી બતાવવાની, તેની સાથે કનેક્ટ કરવાની અને તેની સંબંધિત સ્થિતિ નક્કી કરવાની મંજૂરી આપો"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ડિવાઇસની વચ્ચેનું સાપેક્ષ અંતર નક્કી કરો"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ઍપને નજીકના ડિવાઇસની વચ્ચેનું સાપેક્ષ અંતર નક્કી કરવાની મંજૂરી આપો"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"આ મંજૂરીને આપવાથી, ઍપ તમારી પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી મેળવી શકે છે, જેમ કે રજિસ્ટર થયેલી સહાય અને નિર્ધારિત સ્થાન."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ચાલુ કરો"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"પાછા જાઓ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ઇમર્જન્સી સૅટલાઇટ સહાય હવે ઉપલબ્ધ છે"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"જો મોબાઇલ કે વાઇ-ફાઇ નેટવર્ક ન હોય, તો તમે ઇમર્જન્સી સર્વિસને મેસેજ કરી શકો છો. Google Messages તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ હોવી આવશ્યક છે."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ઇમર્જન્સી સૅટલાઇટ સહાયને સપોર્ટ કરવામાં આવતો નથી"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"આ ડિવાઇસ પર ઇમર્જન્સી સૅટલાઇટ સહાયને સપોર્ટ કરવામાં આવતો નથી"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ઇમર્જન્સી સૅટલાઇટ સહાયનું સેટઅપ કર્યું નથી"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"તમે ઇન્ટરનેટથી કનેક્ટેડ હોવાની ખાતરી કરો અને ફરી સેટઅપ કરવાનો પ્રયાસ કરો"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ નથી"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"આ દેશ કે પ્રદેશમાં ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ નથી"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ઇમર્જન્સી સૅટલાઇટ સહાયનું સેટઅપ કરેલું નથી"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"સૅટલાઇટ દ્વારા મેસેજ મોકલવા માટે, Google Messagesને તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ તરીકે સેટ કરો"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ નથી"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"આ દેશ કે પ્રદેશમાં ઇમર્જન્સી સૅટલાઇટ સહાય ઉપલબ્ધ છે કે કેમ તે ચેક કરવા માટે, લોકેશન સેટિંગ ચાલુ કરો"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ છે"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"જો કોઈ મોબાઇલ કે વાઇ-ફાઇ નેટવર્ક ઉપલબ્ધ ન હોય, તો તમે સૅટલાઇટ દ્વારા મેસેજ મોકલી શકો છો. Google Messages તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ હોવી આવશ્યક છે."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"સૅટલાઇટ મેસેજિંગને સપોર્ટ કરવામાં આવતો નથી"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"આ ડિવાઇસ પર સૅટલાઇટ મેસેજિંગને સપોર્ટ કરવામાં આવતો નથી"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"સૅટલાઇટ મેસેજિંગનું સેટઅપ કર્યું નથી"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"તમે ઇન્ટરનેટથી કનેક્ટેડ હોવાની ખાતરી કરો અને ફરી સેટઅપ કરવાનો પ્રયાસ કરો"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ નથી"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"આ દેશ કે પ્રદેશમાં સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ નથી"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"સૅટલાઇટ મેસેજિંગનું સેટઅપ કર્યું નથી"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"સૅટલાઇટ દ્વારા મેસેજ મોકલવા માટે, Google Messagesને તમારી ડિફૉલ્ટ મેસેજિંગ ઍપ તરીકે સેટ કરો"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ નથી"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"આ દેશ કે પ્રદેશમાં સૅટલાઇટ મેસેજિંગ ઉપલબ્ધ છે કે કેમ તે ચેક કરવા માટે, લોકેશન સેટિંગ ચાલુ કરો"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 5422f1befc40..c5825fe097db 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -322,7 +322,7 @@
<string name="permgrouplab_location" msgid="1858277002233964394">"जगह की जानकारी"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"इस डिवाइस की जगह तक पहुंचने दें"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"कैलेंडर"</string>
- <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करें"</string>
+ <string name="permgroupdesc_calendar" msgid="6762751063361489379">"आपके कैलेंडर को ऐक्सेस करने की अनुमति"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
<string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइल"</string>
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ऐप्लिकेशन को आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"आस-पास मौजूद वाई-फ़ाई डिवाइसों से इंटरैक्ट करें"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"इससे, ऐप्लिकेशन आस-पास मौजूद वाई-फ़ाई डिवाइसों की जानकारी दिखा पाएगा, उनसे कनेक्ट कर पाएगा, और उनकी दूरी पता लगा पाएगा"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"आस-पास मौजूद डिवाइसों के बीच की दूरी का पता लगाएं"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ऐप्लिकेशन को, आस-पास मौजूद डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC का इस्तेमाल करने वाली पैसे चुकाने की पसंदीदा सेवा की जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"अगर ऐप्लिकेशन को अनुमति दी जाती है, तो वह पैसे चुकाने की आपकी उस पसंदीदा सेवा के बारे में जानकारी पा सकता है जो NFC का इस्तेमाल करती है. इसमें रजिस्टर किए गए डिवाइस और उनके आउटपुट के रूट जैसी जानकारी शामिल होती है."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नियर फ़ील्‍ड कम्‍यूनिकेशन नियंत्रित करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0594788fa9ce..954f4cb1842c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Dopušta aplikaciji da odredi približni položaj između uređaja u blizini koji upotrebljavaju ultraširokopojasno povezivanje"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcija s Wi-Fi uređajima u blizini"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji omogućuje oglašavanje, povezivanje i određivanje približnog položaja Wi-Fi uređaja u blizini"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"određivanje rel. položaja između uređaja u blizini"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Dopustite aplikaciji da odredi relativni položaj između uređaja u blizini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacije o preferiranoj usluzi plaćanja NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Omogućuje aplikaciji primanje informacija o preferiranoj usluzi plaćanja NFC kao što su registrirana pomagala i odredište."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 8adb234830aa..58a5cbdbc2ab 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Az alkalmazás meghatározhatja a közeli, ultraszélessávú eszközök közötti relatív pozíciót"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"műveletek végrehajtása a közeli Wi‑Fi-eszközökkel"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Engedélyezi az alkalmazás számára, hogy közzétegye és meghatározza a közeli Wi-Fi-eszközök viszonylagos helyzetét, és csatlakozzon hozzájuk."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"közeli eszközök közötti relatív pozíció meghatározása"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Az alkalmazás meghatározhatja a közeli eszközök közötti relatív pozíciót"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferált NFC fizetési szolgáltatási információk"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lehetővé teszi az alkalmazás számára preferált NFC fizetési szolgáltatási információk (pl. regisztrált alkalmazásazonosítók és útvonali cél) lekérését."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC technológia vezérlése"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Bekapcsolás"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Vissza"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Mostantól rendelkezésre áll a műholdas SOS"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mobil- vagy Wi-Fi-hálózat nélkül is küldhet üzenetet a segélyhívó szolgálatnak. Ehhez a Google Messagest kell beállítani alapértelmezett üzenetküldő almazásként."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Nem támogatott a műholdas SOS"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Ezen az eszközön nem támogatott a műholdas SOS."</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Nincs beállítva a műholdas SOS"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Ellenőrizze, hogy csatlakozik-e az internethez, majd próbálja újra a beállítást."</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Nem áll rendelkezésre a műholdas SOS"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Ebben az országban vagy régióban nem áll rendelkezésre a műholdas SOS."</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Nincs beállítva a műholdas SOS"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Műholdas üzenetváltáshoz állítsa be a Google Messagest alapértelmezett üzenetküldő alkalmazásként."</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Nem áll rendelkezésre a műholdas SOS"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ha szeretné ellenőrizni, hogy rendelkezésre áll-e a műholdas SOS ebben az országban vagy régióban, kapcsolja be a helybeállításokat."</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Rendelkezésre áll a műholdas üzenetváltás"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Műholdon keresztül is küldhet üzenetet, ha nincs mobil- vagy Wi-Fi-hálózat. Ehhez a Google Messagest kell beállítani alapértelmezett üzenetküldő almazásként."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Nem támogatott a műholdas üzenetváltás"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Ezen az eszközön nem támogatott a műholdas üzenetváltás."</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Nincs beállítva a műholdas üzenetváltás"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Ellenőrizze, hogy csatlakozik-e az internethez, majd próbálja újra a beállítást."</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Nem áll rendelkezésre a műholdas üzenetváltás"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Ebben az országban vagy régióban nem áll rendelkezésre a műholdas üzenetváltás."</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Nincs beállítva a műholdas üzenetváltás"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Műholdas üzenetváltáshoz állítsa be a Google Messagest alapértelmezett üzenetküldő alkalmazásként."</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Nem áll rendelkezésre a műholdas üzenetváltás"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ha szeretné ellenőrizni, hogy rendelkezésre áll-e a műholdas üzenetváltás ebben az országban vagy régióban, kapcsolja be a helybeállításokat."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 4a16d2f37194..f457c42d9cd4 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Թույլատրել հավելվածին որոշել գերլայնաշերտ կապի տեխնոլոգիան աջակցող մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"փոխներգործել մոտակա Wi‑Fi սարքերի հետ"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Թույլ է տալիս հավելվածին տվյալներ փոխանցել մոտակա Wi‑Fi սարքերին, միանալ դրանց և որոշել դրանց մոտավոր դիրքը։"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"որոշել մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Թույլատրել հավելվածին որոշել մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Թույլ է տալիս հավելվածին ստանալ նախընտրելի NFC վճարային ծառայության մասին տեղեկություններ (օր․՝ գրանցված լրացուցիչ սարքերի և երթուղու նպատակակետի մասին տվյալներ)։"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"վերահսկել Մոտ Տարածությամբ Հաղորդակցումը"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Միացնել"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Հետ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS-ը այժմ հասանելի է"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Դուք կարող եք հաղորդագրություն գրել արտակարգ իրավիճակների ծառայություններին բջջային կամ Wi-Fi ցանցի բացակայության դեպքում։ Google Messages-ը պետք է լինի հաղորդագրման ձեր կանխադրված հավելվածը։"</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS-ը չի աջակցվում"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS-ը այս սարքում չի աջակցվում"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS-ը կարգավորված չէ"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Համոզվեք, որ միացած եք ինտերնետին, և նորից փորձեք կարգավորել"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS-ը հասանելի չէ"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS-ը հասանելի չէ այս երկրում կամ տարածաշրջանում"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS-ը կարգավորված չէ"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Արբանյակային կապով հաղորդագրություններ ուղարկելու համար Google Messages-ը դարձրեք հաղորդագրման ձեր կանխադրված հավելվածը"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS-ը հասանելի չէ"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Միացրեք տեղադրության կարգավորումները, որպեսզի ստուգեք՝ արդյոք Satellite SOS գործառույթը հասանելի է այս երկրում կամ տարածաշրջանում"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Արբանյակային հաղորդագրումը հասանելի է"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Բջջային կամ Wi-Fi ցանցի բացակայության դեպքում դուք կարող եք հաղորդագրություններ ուղարկել արբանյակային կապով։ Google Messages-ը պետք է լինի հաղորդագրման ձեր կանխադրված հավելվածը։"</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Արբանյակային հաղորդագրումը չի աջակցվում"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Արբանյակային հաղորդագրումն այս սարքում չի աջակցվում"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Արբանյակային հաղորդագրումը կարգավորված չէ"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Համոզվեք, որ միացած եք ինտերնետին, և նորից փորձեք կարգավորել"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Արբանյակային հաղորդագրումը հասանելի չէ"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Արբանյակային հաղորդագրումը հասանելի չէ այս երկրում կամ տարածաշրջանում"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Արբանյակային հաղորդագրումը կարգավորված չէ"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Արբանյակային կապով հաղորդագրություններ ուղարկելու համար Google Messages-ը դարձրեք հաղորդագրման ձեր կանխադրված հավելվածը"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Արբանյակային հաղորդագրումը հասանելի չէ"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Միացրեք տեղադրության կարգավորումները, որպեսզի ստուգեք՝ արդյոք արբանյակային հաղորդագրումը հասանելի է այս երկրում կամ տարածաշրջանում"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index e90137fd761f..88764c4112b8 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Mengizinkan aplikasi menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan perangkat Wi-Fi di sekitar"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Mengizinkan aplikasi menampilkan, menghubungkan, dan menentukan posisi relatif perangkat Wi-Fi di sekitar"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"menentukan posisi relatif antar-perangkat di sekitar"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Izinkan aplikasi menentukan posisi relatif antar-perangkat di sekitar"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Mengizinkan aplikasi untuk mendapatkan informasi layanan pembayaran NFC pilihan seperti bantuan terdaftar dan tujuan rute."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
@@ -1397,7 +1395,7 @@
<string name="no_permissions" msgid="5729199278862516390">"Tidak perlu izin"</string>
<string name="perm_costs_money" msgid="749054595022779685">"ini mungkin tidak gratis"</string>
<string name="dlg_ok" msgid="5103447663504839312">"Oke"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"Daya perangkat sedang diisi via USB"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"Mengisi daya perangkat ini via USB"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"Mengisi daya perangkat yang terhubung via USB"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Transfer file USB diaktifkan"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB diaktifkan"</string>
@@ -1763,7 +1761,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Alat bantu dengar"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
- <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan dan tahan kedua tombol volume lagi selama 3 detik."</string>
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan kedua tombol volume lagi selama 3 detik."</string>
<string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Pilih fitur"</string>
<string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Pilih fitur"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Pilih fitur"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktifkan"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kembali"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS via Satelit kini tersedia"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Anda dapat mengirim pesan ke layanan darurat jika tidak ada jaringan seluler atau Wi-Fi. Google Message harus menjadi aplikasi pesan default Anda."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS via Satelit tidak didukung"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS via Satelit tidak didukung di perangkat ini"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS via Satelit tidak disiapkan"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Pastikan perangkat Anda terhubung ke internet, lalu coba siapkan lagi"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS via Satelit tidak tersedia"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS via Satelit tidak tersedia di negara atau wilayah ini"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS via Satelit tidak disiapkan"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Untuk mengirim pesan melalui satelit, setel Google Message sebagai aplikasi pesan default"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS via Satelit tidak tersedia"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Untuk memeriksa apakah SOS via Satelit tersedia di negara atau wilayah ini, aktifkan setelan lokasi"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Fitur pesan satelit tersedia"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Anda dapat mengirim pesan melalui satelit jika tidak ada jaringan seluler atau Wi-Fi. Google Message harus menjadi aplikasi pesan default Anda."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Fitur pesan satelit tidak didukung"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Fitur pesan satelit tidak didukung di perangkat ini"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Fitur pesan satelit tidak disiapkan"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Pastikan perangkat Anda terhubung ke internet, lalu coba siapkan lagi"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Fitur pesan satelit tidak tersedia"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Fitur pesan satelit tidak tersedia di negara atau wilayah ini"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Fitur pesan satelit tidak disiapkan"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Untuk mengirim pesan melalui satelit, setel Google Message sebagai aplikasi pesan default"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Fitur pesan satelit tidak tersedia"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Untuk memeriksa apakah fitur pesan satelit tersedia di negara atau wilayah ini, aktifkan setelan lokasi"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi."</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9ca5731ad1eb..8e92ed1532c1 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leyfa forritinu að ákvarða fjarlægð milli nálægra tækja með ofurbreiðband"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"eiga í samskiptum við nálæg WiFi-tæki"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Leyfir forritinu að auglýsa, tengja og áætla staðsetningu nálægra WiFi-tækja"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"greina áætlaða fjarlægð á milli nálægra tækja"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Leyfðu forritinu að greina áætlaða fjarlægð á milli nálægra tækja"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Upplýsingar um valda NFC-greiðsluþjónustu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gerir forritinu kleift að fá valda NFC-greiðsluþjónustu, svo sem skráða aðstoð og áfangastað leiðar."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"stjórna nándarsamskiptum (NFC)"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ac0e4580b7a0..49f1f21131e2 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Consenti all\'app di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Interazione con dispositivi Wi-Fi vicini"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Consente all\'app di trasmettere annunci e connettersi a dispositivi Wi‑Fi vicini e di stabilirne la posizione relativa."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"stabilire la posizione relativa tra dispositivi nelle vicinanze"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Consenti all\'app di stabilire la posizione relativa tra dispositivi nelle vicinanze"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informazioni del servizio di pagamento NFC preferito"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Consente all\'app di recuperare informazioni del servizio di pagamento NFC preferito, quali destinazione della route e identificatori applicazione registrati."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controllo Near Field Communication"</string>
@@ -2436,54 +2434,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Attiva"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Indietro"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"SOS satellitare è disponibile"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Puoi inviare messaggi ai servizi di emergenza se non disponi di una rete mobile o Wi-Fi. Google Messaggi deve essere l\'app di messaggistica predefinita."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS satellitare non supportato"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS satellitare non è supportato su questo dispositivo"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS satellitare non configurato"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Assicurati di avere una connessione a internet attiva e prova a ripetere la configurazione"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS satellitare non disponibile"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS satellitare non è disponibile in questo paese o in questa regione"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS satellitare non configurato"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Per inviare messaggi via satellite, imposta Google Messaggi come app di messaggistica predefinita"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS satellitare non disponibile"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Per verificare se SOS satellitare è disponibile in questo paese o in questa regione, attiva le impostazioni di localizzazione"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Messaggi via satellite disponibili"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Puoi inviare messaggi via satellite se non disponi di una rete mobile o Wi-Fi. Google Messaggi deve essere l\'app di messaggistica predefinita."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Messaggi via satellite non supportati"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"I messaggi via satellite non sono supportati su questo dispositivo"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Messaggi via satellite non configurati"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Assicurati di avere una connessione a internet attiva e prova a ripetere la configurazione"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Messaggi via satellite non disponibili"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"I messaggi via satellite non sono disponibili in questo paese o in questa regione"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Messaggi via satellite non configurati"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Per inviare messaggi via satellite, imposta Google Messaggi come app di messaggistica predefinita"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Messaggi via satellite non disponibili"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Per verificare se i messaggi via satellite sono disponibili in questo paese o in questa regione, attiva le impostazioni di localizzazione"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 386f5318f53a..0e8f472cb107 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"‏האפליקציה תזהה את המיקום היחסי בין מכשירים קרובים שמשדרים בטכנולוגיית Ultra Wideband ‏(UWB)"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏אינטראקציה עם מכשירי Wi-Fi בקרבת מקום"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏האפליקציה תוכל לפרסם במכשירי Wi-Fi בקרבת מקום, להתחבר אליהם ולהעריך את המיקום היחסי שלהם"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"זיהוי המיקום היחסי בין מכשירים קרובים"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"האפליקציה תזהה את המיקום היחסי בין מכשירים קרובים"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏פרטים על שירות תשלום מועדף ב-NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏מאפשרת לאפליקציה לקבל פרטים על שירות תשלום מועדף ב-NFC, כמו עזרים רשומים ויעד של נתיב."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"שליטה בתקשורת מטווח קצר"</string>
@@ -1411,7 +1409,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"המכשיר זיהה התקן אודיו אנלוגי"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש להקיש לקבלת מידע נוסף."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"‏ניפוי באגים ב-USB מחובר"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"‏יש להקיש כדי לכבות את ניפוי הבאגים ב-USB"</string>
+ <string name="adb_active_notification_message" 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>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש להקיש כדי להשבית ניפוי באגים אלחוטי"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 339144611afd..6eabd4afaf3d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"付近の Ultra Wideband デバイス間の相対位置の特定をアプリに許可します"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"付近の Wi-Fi デバイスとの通信"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"付近の Wi-Fi デバイスについて、情報の表示、接続、相対位置の確認をアプリに許可します"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"付近のデバイス間の相対位置の特定"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"付近のデバイス間の相対位置の特定をアプリに許可します"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"優先される NFC お支払いサービスの情報"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"登録されている支援やルートの目的地など、優先される NFC お支払いサービスの情報を取得することをアプリに許可します。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFCの管理"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 58f78901ef5e..4ffa312f7c53 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ნებას რთავს აპს, დაადგინოს შედარებითი პოზიცია ახლომახლო ულტრაფართო სიხშირის მოწყობილობების შესახებ"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ინტერაქცია ახლომახლო Wi-Fi მოწყობილობებთან"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"საშუალებას აძლევს აპს, განაცხადოს ახლომახლო Wi-Fi მოწყობილობების შესახებ, დაუკავშირდეს მათ და განსაზღვროს მათი შედარებითი პოზიცია"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ახლომახლო მოწყობილობებთან მიმართ. პოზიციის დადგენა"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"აპისთვის ახლომახლო მოწყობილობებთან მიმართებაში პოზიციის დადგენის ნების დართვა"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"უპირატესი NFC გადახდის სერვისის ინფორმაცია"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"საშუალებას აძლევს აპს, მიიღოს უპირატესი NFC გადახდის სერვისის ინფორმაცია, მაგალითად, რეგისტრირებული დახმარება და დანიშნულება."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 737f950567a1..6355d86a8ac9 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Қолданбаға маңайдағы кең жолақты құрылғылардың бір-біріне қатысты орнын анықтауға мүмкіндік береді."</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"маңайдағы Wi-Fi құрылғыларымен байланысу"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Қолданба маңайдағы Wi‑Fi құрылғыларына жарнама беріп, оларға қосылып, шамамен орналасқан жерін анықтай алады."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"маңайдағы құрылғылардың салыстырмалы орнын анықтау"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Қолданбаның маңайдағы құрылғылардың салыстырмалы орнын анықтауына рұқсат береді."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Таңдаулы NFC төлеу қызметі туралы ақпарат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Қолданба тіркелген көмектер және баратын жер маршруты сияқты таңдаулы NFC төлеу қызметі туралы ақпаратты ала алатын болады."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
@@ -1398,7 +1396,7 @@
<string name="perm_costs_money" msgid="749054595022779685">"бұған төлем қажет болуы мүмкін"</string>
<string name="dlg_ok" msgid="5103447663504839312">"Жарайды"</string>
<string name="usb_charging_notification_title" msgid="1674124518282666955">"Құрылғы USB арқылы зарядталып тұр"</string>
- <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Жалғанған құрылғы USB арқылы зарядталуда"</string>
+ <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Жалғанған құрылғы USB арқылы зарядталып жатыр"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB арқылы файл жіберу мүмкіндігі қосылды"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP режимі USB арқылы қосылды"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-тетеринг режимі қосылды"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Қосу"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артқа"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Satellite SOS функциясы енді қолжетімді"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Мобильдік немесе Wi-Fi желісі жоқ болған жағдайда, құтқару қызметтеріне хабар жіберуге болады. Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Satellite SOS функциясына қолдау көрсетілмейді"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Satellite SOS функциясына бұл құрылғыда қолдау көрсетілмейді."</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Satellite SOS функциясы реттелмеген"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Құрылғыңыздың интернетке қосылғанын тексеріп, қайта реттеп көріңіз."</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Satellite SOS функциясы қолжетімді емес"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Satellite SOS функциясы бұл елде немесе аймақта қолжетімді емес."</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS функциясы реттелмеген"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Жерсерік арқылы хабар алмасу үшін, Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS функциясы қолжетімді емес"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Satellite SOS функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін, локация параметрлерін қосыңыз."</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Жерсерік арқылы хабар алмасу функциясы қолжетімді"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Мобильдік немесе Wi-Fi желісі жоқ болған жағдайда, жерсерік арқылы хабар алмаса аласыз. Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Жерсерік арқылы хабар алмасу функциясына қолдау көрсетілмейді"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Жерсерік арқылы хабар алмасу функциясына бұл құрылғыда қолдау көрсетілмейді."</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Жерсерік арқылы хабар алмасу функциясы реттелмеген"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Құрылғыңыздың интернетке қосылғанын тексеріп, қайта реттеп көріңіз."</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Жерсерік арқылы хабар алмасу функциясы қолжетімді емес"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Жерсерік арқылы хабар алмасу функциясы бұл елде немесе аймақта қолжетімді емес."</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Жерсерік арқылы хабар алмасу функциясы реттелмеген"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Жерсерік арқылы хабар алмасу үшін, Google Messages сіздің әдепкі хабар алмасу қолданбаңыз болуы керек."</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Жерсерік арқылы хабар алмасу функциясы қолжетімді емес"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Жерсерік арқылы хабар алмасу функциясының бұл елде немесе аймақта қолжетімді екенін тексеру үшін, локация параметрлерін қосыңыз."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 0ecad8f60fe1..4163be41f7fd 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"អនុញ្ញាតឱ្យ​កម្មវិធី​កំណត់ចម្ងាយ​ពាក់ព័ន្ធ​រវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ធ្វើអន្តរកម្ម​ជាមួយឧបករណ៍ Wi‑Fi ដែលនៅជិត"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"អនុញ្ញាតឱ្យ​កម្មវិធី​ផ្សាយពាណិជ្ជកម្ម ភ្ជាប់ និងកំណត់ទីតាំង​ពាក់ព័ន្ធរបស់​ឧបករណ៍ Wi‑Fi ដែលនៅជិត"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"កំណត់ទីតាំងធៀបរវាងឧបករណ៍នៅជិត"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"អនុញ្ញាតឱ្យកម្មវិធីកំណត់ទីតាំងធៀបរវាងឧបករណ៍នៅជិត"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម NFC ជាអាទិភាព"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"អនុញ្ញាតឱ្យ​កម្មវិធី​ទទួលបាន​ព័ត៌មានអំពី​សេវាបង់ប្រាក់តាម nfc ជាអាទិភាព​ដូចជា គោលដៅផ្លូវ និង​ព័ត៌មាន​កំណត់អត្តសញ្ញាណ​កម្មវិធី ដែលបានចុះឈ្មោះ​ជាដើម។"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ពិនិត្យ​ការ​ទាក់ទង​នៅ​ក្បែរ (NFC)"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c64f6ec1e7a7..234ba66a5bc3 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ಸಮೀಪದಲ್ಲಿರುವ ಅಲ್ಟ್ರಾ-ವೈಡ್‌ಬ್ಯಾಂಡ್ ಸಾಧನಗಳ ನಡುವೆ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ಹತ್ತಿರದ ವೈ -ಫೈ ಸಾಧನಗಳ ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಿ"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ಹತ್ತಿರದ ವೈ -ಫೈ ಸಾಧನಗಳ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ಸೂಚಿಸಲು, ಕನೆಕ್ಟ್ ಮಾಡಲು ಮತ್ತು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ಸಮೀಪದ ಸಾಧನಗಳ ನಡುವಿನ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಿ"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ನಡುವಿನ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವಾ ಮಾಹಿತಿ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ನೋಂದಾಯಿತ ಆ್ಯಪ್ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ಮಾರ್ಗ ಗಮ್ಯಸ್ಥಾನಗಳಂತಹ ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವೆಗಳ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
@@ -837,7 +835,7 @@
<string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"ಇತರ ಆ್ಯಪ್‌ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ"</string>
<string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"ಇತರ ಆ್ಯಪ್‌ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
<string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
- <string name="policydesc_limitPassword" msgid="4105491021115793793">"ಪರದೆ ಲಾಕ್‌ನಲ್ಲಿನ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಪಿನ್‌ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
+ <string name="policydesc_limitPassword" msgid="4105491021115793793">"ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನಲ್ಲಿನ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಪಿನ್‌ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"ಪರದೆಯ ಅನ್‌ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಸ್ಕ್ರೀನ್ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್‌ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಟೈಪ್‌ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್‌ ಅನ್ನು ಲಾಕ್‌ ಮಾಡಿ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
<string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ Android TV ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡುತ್ತದೆ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದರೆ ನಿಮ್ಮ ಎಲ್ಲಾ Android TV ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
@@ -871,7 +869,7 @@
<string name="policylab_disableCamera" msgid="5749486347810162018">"ಕ್ಯಾಮರಾಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="policydesc_disableCamera" msgid="3204405908799676104">"ಎಲ್ಲಾ ಸಾಧನ ಕ್ಯಾಮರಾಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
<string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"ಕೆಲವು ಸ್ಕ್ರೀನ್ ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"ಕೆಲವು ಪರದೆ ಲಾಕ್‌ನ ವೈಶಿಷ್ಟ್ಯಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
+ <string name="policydesc_disableKeyguardFeatures" msgid="6641673177041195957">"ಕೆಲವು ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನ ವೈಶಿಷ್ಟ್ಯಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
<string-array name="phoneTypes">
<item msgid="8996339953292723951">"ಮನೆ"</item>
<item msgid="7740243458912727194">"ಮೊಬೈಲ್"</item>
@@ -1410,7 +1408,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ಅನ್‌ಲಾಗ್ ಆಡಿಯೋ ಆ್ಯಕ್ಸೆಸರಿ ಪತ್ತೆಯಾಗಿದೆ"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಕನೆಕ್ಟ್‌ ಆಗಿದೆ"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
+ <string name="adb_active_notification_message" 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>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
@@ -1680,8 +1678,8 @@
<string name="media_route_status_available" msgid="1477537663492007608">"ಲಭ್ಯ"</string>
<string name="media_route_status_not_available" msgid="480912417977515261">"ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="media_route_status_in_use" msgid="6684112905244944724">"ಬಳಕೆಯಲ್ಲಿದೆ"</string>
- <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"ಬಿಲ್ಟ್-ಇನ್ ಪರದೆ"</string>
- <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ಪರದೆ"</string>
+ <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"ಬಿಲ್ಟ್-ಇನ್ ಸ್ಕ್ರೀನ್"</string>
+ <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI ಸ್ಕ್ರೀನ್"</string>
<string name="display_manager_overlay_display_name" msgid="5306088205181005861">"ಓವರ್‌ಲೇ #<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_secure_suffix" msgid="2810034719482834679">", ಸುರಕ್ಷಿತ"</string>
@@ -2409,7 +2407,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ… ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"ಖಾಸಗಿ"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"ಪ್ರೈವೆಟ್"</string>
<string name="profile_label_clone" msgid="769106052210954285">"ಕ್ಲೋನ್"</string>
<string name="profile_label_work" msgid="3495359133038584618">"ಕೆಲಸ"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"ಕೆಲಸ 2"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d63d43e4cddd..59af8fb584ce 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"앱이 근처의 초광대역 기기 간 상대적 위치를 파악하도록 허용"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"근처 Wi‑Fi 기기와 상호작용"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"앱이 광역 신호를 보내 근처에 있는 Wi‑Fi 기기의 상대적인 위치를 확인하고 연결할 수 있도록 허용합니다."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"근처 기기 간 상대 위치 파악"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"앱이 근처 기기 간 상대 위치를 파악하도록 허용"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"기본 NFC 결제 서비스 정보"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"앱이 등록된 AID와 경로 목적지 같은 기본 NFC 결제 서비스 정보를 확인하도록 허용합니다."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC(Near Field Communication) 제어"</string>
@@ -659,7 +657,7 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"계속하려면 화면 잠금용 사용자 인증 정보를 입력하세요"</string>
<string name="fingerprint_acquired_partial" msgid="4323789264604479684">"센서를 세게 누르세요"</string>
- <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"지문을 인식할 수 없습니다. 다시 시도해 주세요"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"지문 센서를 닦은 후 다시 시도해 보세요."</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"센서를 닦은 후 다시 시도해 보세요."</string>
<string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"센서를 세게 누르세요"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index e09036a1b679..cbb0a13963b3 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Колдонмо кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктай алат"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Жакын жердеги Wi‑Fi түзмөктөрүнө байланышуу"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Колдонмо жакын жердеги Wi-Fi түзмөктөргө туташып, алардын жайгашкан жерин аныктап, ар кандай нерселерди өткөрө алат."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"жакын жердеги түзмөктөр арасындагы салыштырмалуу абалды аныктоо"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Колдонмого жакын жердеги түзмөктөр ортосундагы салыштырмалуу абалды аныктоого уруксат берүү"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Тандалган NFC төлөм кызматы жөнүндө маалымат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Колдонмого катталган жардам же көздөлгөн жерге маршрут сыяктуу тандалган nfc төлөм кызматы жөнүндө маалыматты алууга уруксат берүү."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication көзөмөлү"</string>
@@ -2409,7 +2407,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Өзгөртүү үчүн басыңыз."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалык баскычтоптор конфигурацияланды"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Баскычтопторду көрүү үчүн басыңыз"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Купуя"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Жеке"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Клон"</string>
<string name="profile_label_work" msgid="3495359133038584618">"Жумуш"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Жумуш 2"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Күйгүзүү"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Артка кайтуу"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Спутник SOS эми жеткиликтүү"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Мобилдик Интернет же Wi-Fi тармагы жок болсо, кырсыктаганда жардамга келчү кызматтарга билдирүү жөнөтө аласыз. Google Messages демейки жазышуу колдонмоңуз болушу керек."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Спутник SOS колдоого алынбайт"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Бул түзмөктө спутник SOS колдоого алынбайт"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Спутник SOS туураланган жок"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Интернет байланышыңызды текшерип, кайра тууралап көрүңүз"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Спутник SOS жеткиликсиз"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Спутник SOS бул өлкөдө же аймакта жеткиликсиз"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Спутник SOS туураланган жок"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Спутник аркылуу жазышуу үчүн Google Messages кызматын демейки жазышуу колдонмосу катары тандаңыз"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Спутник SOS жеткиликсиз"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Бул өлкөдө же аймакта спутник SOS функциясынын жеткиликтүүлүгүн текшерүү үчүн жайгашкан жерди аныктоо параметрлерин күйгүзүңүз"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Спутник аркылуу байланышуу жеткиликтүү"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Мобилдик же Wi-Fi тармагы жок болсо, спутник аркылуу жазыша аласыз. Google Messages демейки жазышуу колдонмоңуз болушу керек."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Спутник аркылуу байланышуу колдоого алынбайт"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Бул түзмөктө спутник аркылуу байланышуу колдоого алынбайт"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Спутник аркылуу байланышуу туураланган жок"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Интернет байланышыңызды текшерип, кайра тууралап көрүңүз"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Спутник аркылуу байланышуу жеткиликсиз"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Бул өлкөдө же аймакта спутник аркылуу байланышуу жеткиликсиз"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Спутник аркылуу байланышуу туураланган жок"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Спутник аркылуу жазышуу үчүн Google Messages кызматын демейки жазышуу колдонмосу катары тандаңыз"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Спутник аркылуу байланышуу жеткиликсиз"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Бул өлкөдө же аймакта спутник аркылуу байланышуу функциясынын жеткиликтүүлүгүн текшерүү үчүн жайгашкан жерди аныктоо параметрлерин күйгүзүңүз"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт."</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index a9ebcd765502..5af4a84c7caf 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ອະນຸຍາດໃຫ້ແອັບກຳນົດຕຳແໜ່ງທີ່ສຳພັນກັນລະຫວ່າງອຸປະກອນ Ultra-Wideband ທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ໂຕ້ຕອບກັບອຸປະກອນ Wi‑Fi ທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ອະນຸຍາດໃຫ້ແອັບໂຄສະນາ, ເຊື່ອມຕໍ່ ແລະ ກຳນົດຕຳແໜ່ງສຳພັນຂອງອຸປະກອນ Wi-Fi ທີ່ຢູ່ໃກ້ຄຽງໄດ້"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ກຳນົດຕຳແໜ່ງທີ່ກ່ຽວຂ້ອງກັນລະຫວ່າງອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ອະນຸຍາດໃຫ້ແອັບກຳນົດຕຳແໜ່ງທີ່ກ່ຽວຂ້ອງກັນລະຫວ່າງອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ອະນຸຍາດໃຫ້ແອັບຮັບຂໍ້ມູນບໍລິການການຈ່າຍເງິນ NFC ທີ່ຕ້ອງການໄດ້ ເຊັ່ນ: ການຊ່ວຍເຫຼືອແບບລົງທະບຽນ ແລະ ປາຍທາງເສັ້ນທາງ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ຄວບຄຸມ Near Field Communication"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 21fddd010ca4..cb7cc896d42f 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Leisti programai nustatyti apytikslę netoliese esančių itin plataus dažnio juostos įrenginių poziciją"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"sąveikauti su „Wi‑Fi“ įrenginiais netoliese"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Leidžiama programai reklamuoti, prisijungti ir nustatyti apytikslę netoliese esančių „Wi-Fi“ įrenginių poziciją"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"nustatyti apytikslę netoliese esančių įrenginių poziciją"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Leisti programai nustatyti apytikslę netoliese esančių įrenginių poziciją"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Pageidaujama ARL mokėjimo paslaugos informacija"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Programai leidžiama gauti pageidaujamą ARL mokamos paslaugos informaciją, pvz., užregistruotą pagalbą ir maršrutų tikslus."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"valdyti artimo lauko perdavimą (angl. „Near Field Communication“)"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 15ee04a5f1d7..b72fb074ab14 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Atļaut lietotnei noteikt relatīvo atrašanās vietu starp tuvumā esošām ultraplatjoslas ierīcēm"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mijiedarbība ar tuvumā esošām Wi‑Fi ierīcēm"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Atļauj lietotnei nodot datus tuvumā esošām Wi‑Fi ierīcē, izveidot savienojumu ar tām un noteikt to relatīvo pozīciju."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"atrašanās vietas noteikšana relatīvi ierīcēm"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Atļaut lietotnei noteikt relatīvo atrašanās vietu starp tuvumā esošām ierīcēm"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informācija par vēlamo NFC maksājumu pakalpojumu"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ļauj lietotnei iegūt informāciju par vēlamo NFC maksājumu pakalpojumu, piemēram, par reģistrētajiem lietojumprogrammu ID un maršruta galamērķi."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolē tuvlauka saziņu"</string>
@@ -2436,54 +2434,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ieslēgt"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Atpakaļ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Funkcija “Satelīta SOS” tagad ir pieejama"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Varat nosūtīt ziņojumu ārkārtas palīdzības dienestiem, ja nav pieejams ne mobilais, ne Wi-Fi tīkls. Lietotnei Google ziņojumi ir jābūt iestatītai kā noklusējuma ziņojumapmaiņas lietotnei."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Funkcija “Satelīta SOS” netiek atbalstīta"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Šajā ierīcē funkcija Satelīta SOS netiek atbalstīta."</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Funkcija “Satelīta SOS” nav iestatīta"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Pārliecinieties, vai ir izveidots savienojums ar internetu, un vēlreiz mēģiniet veikt iestatīšanu."</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Funkcija “Satelīta SOS” nav pieejama"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Šajā valstī vai reģionā funkcija “Satelīta SOS” nav pieejama."</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Funkcija “Satelīta SOS” nav iestatīta"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Lai varētu sūtīt ziņojumus, izmantojot satelītu, iestatiet lietotni Google ziņojumi kā noklusējuma ziņojumapmaiņas lietotni."</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Funkcija “Satelīta SOS” nav pieejama"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Lai pārbaudītu, vai funkcija “Satelīta SOS” ir pieejama šajā valstī vai reģionā, ieslēdziet atrašanās vietas iestatījumus."</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satelīta ziņojumapmaiņa ir pieejama"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Varat sūtīt ziņojumus, izmantojot satelītu, ja nav pieejams ne mobilais, ne Wi-Fi tīkls. Lietotnei Google ziņojumi ir jābūt iestatītai kā noklusējuma ziņojumapmaiņas lietotnei."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satelīta ziņojumapmaiņa netiek atbalstīta"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Šajā ierīcē satelīta ziņojumapmaiņa netiek atbalstīta."</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satelīta ziņojumapmaiņa nav iestatīta"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Pārliecinieties, vai ir izveidots savienojums ar internetu, un vēlreiz mēģiniet veikt iestatīšanu."</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satelīta ziņojumapmaiņa nav pieejama"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Šajā valstī vai reģionā satelīta ziņojumapmaiņa nav pieejama."</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satelīta ziņojumapmaiņa nav iestatīta"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Lai varētu sūtīt ziņojumus, izmantojot satelītu, iestatiet lietotni Google ziņojumi kā noklusējuma ziņojumapmaiņas lietotni."</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satelīta ziņojumapmaiņa nav pieejama"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Lai pārbaudītu, vai satelīta ziņojumapmaiņa ir pieejama šajā valstī vai reģionā, ieslēdziet atrašanās vietas iestatījumus."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index b5187726028b..0b0e3ef81cca 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозволува апликацијата да ја одреди релативната положба помеѓу уредите со ултраширок појас во близина"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"да има интеракција со уредите со Wi‑Fi во близина"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозволува апликацијата да рекламира, да се поврзува и да ја одредува релативната положба на уреди со Wi‑Fi во близина"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"да ја одредува рел. положба меѓу уреди во близина"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Дозволува апликацијата да ја одредува релативната положба меѓу уредите во близина"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информации за претпочитаната услуга за плаќање преку NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволува апликацијата да добие информации за претпочитаната услуга за плаќање преку NFC, како регистрирани помагала и дестинација на маршрутата."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
@@ -2409,9 +2407,9 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Допрете за да промените."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичките тастатури се конфигурирани"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Допрете за да ги видите тастатурите"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"Приватно"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"Приватен"</string>
<string name="profile_label_clone" msgid="769106052210954285">"Клониран профил"</string>
- <string name="profile_label_work" msgid="3495359133038584618">"Работно"</string>
+ <string name="profile_label_work" msgid="3495359133038584618">"Работен"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"Работен профил 2"</string>
<string name="profile_label_work_3" msgid="4834572253956798917">"Работен профил 3"</string>
<string name="profile_label_test" msgid="9168641926186071947">"Профил за тестирање"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Вклучи"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Врати се назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"„Сателитски SOS“ сега е достапна"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Може да разменувате пораки со службите за итни случаи ако нема мобилна или Wi-Fi мрежа. Google Messages мора да биде ваша стандардна апликација за разменување пораки."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"„Сателитски SOS“ не е поддржана"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"„Сателитски SOS“ не е поддржана на уредов"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"„Сателитски SOS“ не е поставена"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Проверете дали сте поврзани на интернет и обидете се да поставите повторно"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"„Сателитски SOS“ не е достапна"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"„Сателитски SOS“ не е достапна во земјава или регионов"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"„Сателитски SOS“ не е поставена"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"За да разменувате пораки преку сателит, поставете ја Google Messages како стандардна апликација за разменување пораки"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"„Сателитски SOS“ не е достапна"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"За да проверите дали „Сателитски SOS“ е достапна во земјава или регионов, вклучете ги поставките за локација"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Достапна е „Сателитска размена на пораки“"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Може да разменувате пораки преку сателит ако нема мобилна или Wi-Fi мрежа. Google Messages мора да биде ваша стандардна апликација за разменување пораки."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"„Сателитска размена на пораки“ не е поддржана"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"„Сателитска размена на пораки“ не е поддржана на уредов"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"„Сателитска размена на пораки“ не е поставена"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Проверете дали сте поврзани на интернет и обидете се да поставите повторно"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"„Сателитска размена на пораки“ не е достапна"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"„Сателитска размена на пораки“ не е достапна во земјава или регионов"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"„Сателитска размена на пораки“ не е поставена"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"За да разменувате пораки преку сателит, поставете ја Google Messages како стандардна апликација за разменување пораки"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"„Сателитска размена на пораки“ не е достапна"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"За да проверите дали е достапна „Сателитска размена на пораки“ во земјава или регионов, вклучете ги поставките за локација"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index aabeb9b98646..fe5974b3df24 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങളുമായി ഇടപഴകുക"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങൾ കാണിക്കാനും അവയിലേക്ക് കണക്റ്റ് ചെയ്യാനും അവയുടെ ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാനും ആപ്പിനെ അനുവദിക്കൂ"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"സമീപമുള്ള ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കൂ"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"സമീപമുള്ള ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്‌റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index c625d31dbd79..376a03350b23 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Аппад ойролцоох ультра өргөн зурвасын төхөөрөмжүүдийн хоорондох холбоотой байрлалыг тодорхойлохыг зөвшөөрөх"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ойролцоох Wi-Fi төхөөрөмжүүдтэй харилцах"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Аппад ойролцоох Wi-Fi төхөөрөмжүүдтэй холбоотой байрлалыг мэдэгдэх, холбох, тодорхойлохыг зөвшөөрнө"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ойр төхөөрөмжүүдийн хоорондох харьцангуй байрлалыг тодорхойл"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Аппад ойролцоох төхөөрөмжүүдийн хоорондох харьцангуй байрлалыг тодорхойлохыг зөвшөөрнө үү"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сонгосон NFC төлбөрийн үйлчилгээний мэдээлэл"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Бүртгүүлсэн төхөөрөмж болон маршрутын хүрэх цэг зэрэг сонгосон nfc төлбөрийн үйлчилгээний мэдээллийг авахыг аппад зөвшөөрдөг."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ойролцоо талбарын холбоог удирдах"</string>
@@ -917,7 +915,7 @@
</string-array>
<string name="phoneTypeCustom" msgid="5120365721260686814">"Тусгай"</string>
<string name="phoneTypeHome" msgid="3880132427643623588">"Гэрийн"</string>
- <string name="phoneTypeMobile" msgid="1178852541462086735">"Мобайл"</string>
+ <string name="phoneTypeMobile" msgid="1178852541462086735">"Гар утас"</string>
<string name="phoneTypeWork" msgid="6604967163358864607">"Ажлын"</string>
<string name="phoneTypeFaxWork" msgid="6757519896109439123">"Ажлын факс"</string>
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"Гэрийн Факс"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Асаах"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Буцах"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Хиймэл дагуул SOS одоо боломжтой боллоо"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Та хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээ байхгүй бол яаралтай тусламжийн үйлчилгээ рүү мессеж бичих боломжтой. Google Мессеж таны өгөгдмөл мессеж апп байх ёстой."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Хиймэл дагуул SOS-г дэмждэггүй"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Хиймэл дагуул SOS-г энэ төхөөрөмж дээр дэмждэггүй"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Хиймэл дагуул SOS-г тохируулаагүй байна"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Та интернэтэд холбогдсон эсэхийг шалгаад, тохируулгыг дахин оролдоно уу"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Хиймэл дагуул SOS боломжгүй байна"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Хиймэл дагуул SOS энэ улс эсвэл бүс нутагт боломжгүй"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Хиймэл дагуул SOS-г тохируулаагүй байна"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Хиймэл дагуулаар дамжин мессеж бичихийн тулд Google Мессежийг өгөгдмөл мессеж аппаараа тохируулна уу"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Хиймэл дагуул SOS боломжгүй байна"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Энэ улс эсвэл бүс нутагт Хиймэл дагуул SOS боломжтой эсэхийг шалгахын тулд байршлын тохиргоог асаана уу"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Хиймэл дагуулаар дамжин мессеж бичих боломжтой"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Хэрэв хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээ байхгүй бол та хиймэл дагуулаар дамжин мессеж бичих боломжтой. Google Мессеж таны өгөгдмөл мессеж апп байх ёстой."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Хиймэл дагуулаар дамжин мессеж бичихийг дэмждэггүй"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Хиймэл дагуулаар дамжин мессеж бичихийг энэ төхөөрөмж дээр дэмждэггүй"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Хиймэл дагуулаар дамжин мессеж бичихийг тохируулаагүй"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Та интернэтэд холбогдсон эсэхийг шалгаад, тохируулгыг дахин оролдоно уу"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Хиймэл дагуулаар дамжин мессеж бичих боломжгүй"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Энэ улс эсвэл бүс нутагт хиймэл дагуулаар дамжин мессеж бичих боломжгүй"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Хиймэл дагуулаар дамжин мессеж бичихийг тохируулаагүй"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Хиймэл дагуулаар дамжин мессеж бичихийн тулд Google Мессежийг өгөгдмөл мессеж аппаараа тохируулна уу"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Хиймэл дагуулаар дамжин мессеж бичих боломжгүй"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Энэ улс эсвэл бүс нутагт хиймэл дагуулаар дамжин мессеж бичих боломжтой эсэхийг шалгахын тулд байршлын тохиргоог асаана уу"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 3240d5914056..e640f729d093 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ॲपला जवळच्या अल्ट्रा-वाइडबँड डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करण्याची अनुमती द्या"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"जवळपासच्या वाय-फाय डिव्हाइसशी संवाद साधा"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ॲपला जाहिरात करण्याची, कनेक्ट करण्याची आणि जवळपासच्या वाय-फाय डिव्हाइसचे संबंधित स्थान निर्धारित करण्याची परवानगी देते"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"जवळपासच्या डिव्हाइसदरम्यान संबंधित स्थान निश्चित करा"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ॲपला जवळच्या डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करण्याची अनुमती द्या"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"प्राधान्यकृत NFC पेमेंट सेवा माहिती"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"नोंदणीकृत एड्स आणि मार्ग गंतव्यस्थान सारखी प्राधान्यकृत एनएफसी पेमेंट सेवेची माहिती मिळवण्यासाठी अ‍ॅपला अनुमती देते."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"फील्ड जवळील कम्युनिकेशन नियंत्रित करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index bd780ae0be92..3946ac1df42f 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Benarkan apl menentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan peranti Wi-Fi berdekatan"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Membenarkan apl mengiklankan, menyambung dan menentukan kedudukan relatif peranti Wi-Fi berdekatan"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"tentukan kedudukan relatif antara peranti berdekatan"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Benarkan apl menentukan kedudukan relatif antara peranti berdekatan"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Membenarkan apl mendapatkan maklumat perkhidmatan pembayaran nfc pilihan seperti bantuan berdaftar dan destinasi laluan."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e4c2acaba9f5..fc0072557cb0 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"အနီးရှိ ‘အလွန်ကျယ်ပြန့်သော လှိုင်းအလျားသုံးစက်များ’ ကြား မှန်းခြေနေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုမည်"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"အနီးရှိ Wi-Fi စက်များနှင့် ပြန်လှန်တုံ့ပြန်ခြင်း"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ကြော်ငြာရန်၊ ချိတ်ဆက်ရန်နှင့် အနီးတစ်ဝိုက်ရှိ Wi-Fi စက်များ၏ နေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"အနီးတစ်ဝိုက်ရှိ စက်များကြား ဆက်စပ်နေရာသတ်မှတ်ခြင်း"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"အနီးတစ်ဝိုက်ရှိ စက်များကြား ဆက်စပ်နေရာသတ်မှတ်ရန် အက်ပ်ကိုခွင့်ပြုသည်"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ဦးစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"အက်ပ်အား ဦစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များဖြစ်သည့် မှတ်ပုံတင်ထားသော အကူအညီများနှင့် သွားလာရာ လမ်းကြောင်းတို့ကို ရယူရန် ခွင့်ပြုသည်။"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
@@ -2446,7 +2444,7 @@
<string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Satellite SOS ကို စနစ်ထည့်သွင်းမထားပါ"</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ရန် Google Messages ကို သင်၏ မက်ဆေ့ဂျ်ပို့ရန် မူရင်းအက်ပ်အဖြစ် သတ်မှတ်ပါ"</string>
<string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Satellite SOS မရနိုင်ပါ"</string>
- <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"satellite SOS ကို ဤနိုင်ငံ (သို့) ဒေသတွင် ရနိုင်ခြင်းရှိ၊ မရှိ စစ်ဆေးရန် တည်နေရာပြ ဆက်တင်များကို ဖွင့်ပါ"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Satellite SOS ကို ဤနိုင်ငံ (သို့) ဒေသတွင် ရနိုင်ခြင်းရှိ၊ မရှိ စစ်ဆေးရန် တည်နေရာပြ ဆက်တင်များကို ဖွင့်ပါ"</string>
<string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ခြင်း ရနိုင်သည်"</string>
<string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက် မရှိသည့်အခါ ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့နိုင်သည်။ Google Messages သည် သင်၏ မူရင်းမက်ဆေ့ဂျ်ပို့ရန်အက်ပ် ဖြစ်ရမည်။"</string>
<string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ခြင်းကို ပံ့ပိုးမထားပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ec4cd961faee..c1095d3978ef 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"tillate at appen fastslår den relative posisjonen mellom enheter i nærheten som bruker ultrabredbånd"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"samhandle med wifi-enheter i nærheten"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lar appen annonsere, koble til og fastslå den relative posisjonen til wifi-enheter i nærheten"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"Relativ posisjon mellom enheter i nærheten"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Tillat at appen avgjør den relative posisjonen mellom enheter i nærheten"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasjon om prioritert NFC-betalingstjeneste"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Gir appen tilgang til informasjon om prioritert NFC-betalingstjeneste, for eksempel registrerte hjelpemidler og destinasjon."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontroller overføring av data med NFC-teknologi"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Slå på"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Gå tilbake"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Nå er SOS-alarm via satellitt tilgjengelig"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Du kan sende meldinger til nødtjenestene hvis du ikke har mobil- eller wifi-dekning. Google Meldinger må være standardappen for meldinger."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"SOS-alarm via satellitt støttes ikke"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"SOS-alarm via satellitt støttes ikke på denne enheten"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"SOS-alarm via satellitt er ikke konfigurert"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Sjekk at du er koblet til internett, og prøv konfigureringen på nytt"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"SOS-alarm via satellitt er ikke tilgjengelig"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"SOS-alarm via satellitt er ikke tilgjengelig i dette landet eller denne regionen"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"SOS-alarm via satellitt er ikke konfigurert"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"For å sende meldinger via satellitt må du angi Google Meldinger som standardapp for meldinger"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"SOS-alarm via satellitt er ikke tilgjengelig"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"For å sjekke om SOS-alarm via satellitt er tilgjengelig i dette landet eller denne regionen, slå på posisjonsinnstillingene"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Satellittmeldinger er tilgjengelige"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Du kan sende meldinger via satellitt hvis du ikke har mobil- eller wifi-dekning. Google Meldinger må være standardappen for meldinger."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Satellittmeldinger støttes ikke"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Satellittmeldinger støttes ikke på denne enheten"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Satellittmeldinger er ikke konfigurert"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Sjekk at du er koblet til internett, og prøv konfigureringen på nytt"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Satellittmeldinger er ikke tilgjengelige"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Satellittmeldinger er ikke tilgjengelige i dette landet eller denne regionen"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Satellittmeldinger er ikke konfigurert"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"For å sende meldinger via satellitt må du angi Google Meldinger som standardapp for meldinger"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Satellittmeldinger er ikke tilgjengelige"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"For å sjekke om satellittmeldinger er tilgjengelige i dette landet eller denne regionen, slå på posisjonsinnstillinger"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 0dc0bd3d04a9..beda131e3de4 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"यो एपलाई नजिकै रहेका अल्ट्रा-वाइडब्यान्ड चल्ने डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउन दिनुहोस्"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Wi-Fi चल्ने नजिकै रहेका डिभाइसहरूमा चलाउन दिन्छ"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"यसले एपलाई Wi-Fi चल्ने नजिकै रहेका डिभाइसहरूमा विज्ञापन गर्न, कनेक्ट गर्न र सापेक्ष स्थिति निर्धारण गर्न दिन्छ"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"नजिकै रहेका डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउने"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"यो एपलाई नजिकै रहेका डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउन दिनुहोस्"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC भुक्तानी सेवासम्बन्धी रुचाइएको जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"यसले एपलाई दर्ता गरिएका सहायता तथा मार्गको गन्तव्य जस्ता रुचाइएका NFC भुक्तानी सेवासम्बन्धी जानकारी प्राप्त गर्न दिन्छ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नजिक क्षेत्र संचार नियन्त्रणहरू"</string>
@@ -2173,8 +2171,8 @@
<string name="mime_type_audio_ext" msgid="2615491023840514797">"<xliff:g id="EXTENSION">%1$s</xliff:g> अडियो"</string>
<string name="mime_type_video" msgid="7071965726609428150">"भिडियो"</string>
<string name="mime_type_video_ext" msgid="185438149044230136">"<xliff:g id="EXTENSION">%1$s</xliff:g> भिडियो"</string>
- <string name="mime_type_image" msgid="2134307276151645257">"छवि"</string>
- <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> छवि"</string>
+ <string name="mime_type_image" msgid="2134307276151645257">"फोटो"</string>
+ <string name="mime_type_image_ext" msgid="5743552697560999471">"<xliff:g id="EXTENSION">%1$s</xliff:g> फोटो"</string>
<string name="mime_type_compressed" msgid="8737300936080662063">"अभिलेख"</string>
<string name="mime_type_compressed_ext" msgid="4775627287994475737">"<xliff:g id="EXTENSION">%1$s</xliff:g> अभिलेख"</string>
<string name="mime_type_document" msgid="3737256839487088554">"कागजात"</string>
@@ -2211,7 +2209,7 @@
<string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Dpad को बिचको बटन"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
- <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"छवि पठाइयो"</string>
+ <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"फोटो पठाइयो"</string>
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"वार्तालाप"</string>
<string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"सामूहिक वार्तालाप"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
@@ -2409,7 +2407,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> भाषामा सेट गरिएको छ… बदल्न ट्याप गर्नुहोस्।"</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"भौतिक किबोर्डहरू कन्फिगर गरिएका छन्"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"किबोर्डहरू हेर्न ट्याप गर्नुहोस्"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"निजी"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"निजी स्पेस"</string>
<string name="profile_label_clone" msgid="769106052210954285">"क्लोन"</string>
<string name="profile_label_work" msgid="3495359133038584618">"कार्य"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"कार्य प्रोफाइल २"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e55334740778..48c8be196bc0 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"De app toestaan om de relatieve positie tussen ultrabreedbandapparaten in de buurt te bepalen"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactie met wifi-apparaten in de buurt"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Hiermee kan de app uitzenden, verbindingen maken en de relatieve positie bepalen van wifi-apparaten in de buurt"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"relatieve positie tussen apparaten in de buurt bepalen"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Sta toe dat de app de relatieve positie tussen apparaten in de buurt bepaalt"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informatie over voorkeursservice voor NFC-betaling"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Hiermee kun je zorgen dat de app informatie krijgt over de voorkeursservice voor NFC-betaling, zoals geregistreerde hulpmiddelen en routebestemmingen."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 2515bb5052eb..a99afa5a0a2f 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ଆଖପାଖର ଅଲଟ୍ରା-ୱାଇଡବ୍ୟାଣ୍ଡ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ଆଖପାଖର ୱାଇ-ଫାଇ ଡିଭାଇସଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରନ୍ତୁ"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ଆଖପାଖର ୱାଇ-ଫାଇ ଡିଭାଇସରେ ବିଜ୍ଞାପନ ଦେବା, ତା ସହ ସଂଯୋଗ କରିବା ଓ ତା’ର ଆପେକ୍ଷିକ ଅବସ୍ଥିତି ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ଆଖପାଖର ଡିଭାଇସ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କର"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ପସନ୍ଦର NFC ପେମେଣ୍ଟ ସେବା ସୂଚନା"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ପଞ୍ଜିକୃତ ଯନ୍ତ୍ର ଏବଂ ମାର୍ଗ ଲକ୍ଷସ୍ଥଳ ପରି ପସନ୍ଦର nfc ପେମେଣ୍ଟ ସେବା ସୂଚନା ପାଇବାକୁ ଆପ୍ ଅନୁମତି କରିଥାଏ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ନିଅର୍ ଫିଲ୍ଡ କମ୍ୟୁନିକେଶନ୍ ଉପରେ ନିୟନ୍ତ୍ରଣ ରଖନ୍ତୁ"</string>
@@ -1993,7 +1991,7 @@
<string name="importance_from_user" msgid="2782756722448800447">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍‍ କରନ୍ତି।"</string>
<string name="importance_from_person" msgid="4235804979664465383">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"କଷ୍ଟମ୍ ଆପ୍ ବିଜ୍ଞପ୍ତି"</string>
- <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
+ <string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ୟୁଜର ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ୟୁଜରଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ୟୁଜର ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"ନିରୀକ୍ଷିତ ୟୁଜର ଯୋଗ କରନ୍ତୁ"</string>
<string name="language_selection_title" msgid="52674936078683285">"ଏକ ଭାଷା ଯୋଗ କରନ୍ତୁ"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ଚାଲୁ କରନ୍ତୁ"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ବର୍ତ୍ତମାନ ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ଅଛି"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"କୌଣସି ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ନଥିଲେ ଆପଣ ଜରୁରୀକାଳୀନ ସେବାଗୁଡ଼ିକୁ ମେସେଜ କରିପାରିବେ। Google Messages ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ହେବା ଆବଶ୍ୟକ।"</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ସେଟେଲାଇଟ SOS ସପୋର୍ଟ କରୁନାହିଁ"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"ଏହି ଡିଭାଇସରେ ସେଟେଲାଇଟ SOS ସପୋର୍ଟ କରୁନାହିଁ"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ସେଟେଲାଇଟ SOS ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"ଆପଣ ଇଣ୍ଟର୍ନେଟ ସହ କନେକ୍ଟ ଅଛନ୍ତି ବୋଲି ସୁନିଶ୍ଚିତ କରି ପୁଣି ସେଟଅପ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ସେଟେଲାଇଟ SOS ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"ସେଟେଲାଇଟ ମାଧ୍ୟମରେ ମେସେଜ କରିବା ପାଇଁ Google Messagesକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ଭାବେ ସେଟ କରନ୍ତୁ"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ SOS ଉପଲବ୍ଧ ଅଛି ନା ନାହିଁ ତାହା ଯାଞ୍ଚ କରିବାକୁ ଲୋକେସନ ସେଟିଂସ ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ଅଛି"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"କୌଣସି ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ନଥିଲେ ଆପଣ ସେଟେଲାଇଟ ମାଧ୍ୟମରେ ମେସେଜ କରିପାରିବେ। Google Messages ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ହେବା ଆବଶ୍ୟକ।"</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"ସେଟେଲାଇଟ ମେସେଜିଂ ସପୋର୍ଟ କରୁନାହିଁ"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"ଏହି ଡିଭାଇସରେ ସେଟେଲାଇଟ ମେସେଜିଂ ସପୋର୍ଟ କରୁନାହିଁ"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"ସେଟେଲାଇଟ ମେସେଜିଂ ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"ଆପଣ ଇଣ୍ଟର୍ନେଟ ସହ କନେକ୍ଟ ଅଛନ୍ତି ବୋଲି ସୁନିଶ୍ଚିତ କରି ପୁଣି ସେଟଅପ କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"ସେଟେଲାଇଟ ମେସେଜିଂ ସେଟ ଅପ କରାଯାଇନାହିଁ"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"ସେଟେଲାଇଟ ମାଧ୍ୟମରେ ମେସେଜ କରିବା ପାଇଁ Google Messagesକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ ମେସେଜିଂ ଆପ ଭାବେ ସେଟ କରନ୍ତୁ"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"ଏହି ଦେଶ କିମ୍ବା ଅଞ୍ଚଳରେ ସେଟେଲାଇଟ ମେସେଜିଂ ଉପଲବ୍ଧ ଅଛି ନା ନାହିଁ ତାହା ଯାଞ୍ଚ କରିବାକୁ ଲୋକେସନ ସେଟିଂସ ଚାଲୁ କରନ୍ତୁ"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 574d991b9dfc..b46301744701 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਅਲਟ੍ਰਾ-ਵਾਈਡਬੈਂਡ ਡੀਵਾਈਸਾਂ ਦੇ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"ਨਜ਼ਦੀਕੀ ਵਾਈ-ਫਾਈ ਡੀਵਾਈਸਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰੋ"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਵਾਈ-ਫਾਈ ਡੀਵਾਈਸਾਂ \'ਤੇ ਵਿਗਿਆਪਨ ਦੇਣ, ਕਨੈਕਟ ਕਰਨ ਅਤੇ ਉਨ੍ਹਾਂ ਦੀ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨਿਰਧਾਰਿਤ ਕਰੋ"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਦੇ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ਐਪ ਨੂੰ ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਕਿ ਰਜਿਸਟਰ ਕੀਤੇ ਸਾਧਨ ਅਤੇ ਮੰਜ਼ਿਲ ਰਸਤਾ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f267877b3a18..4f34fc5ed84e 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Zezwól na określanie przez aplikację względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcje z urządzeniami Wi-Fi w pobliżu"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Zezwala aplikacji na przesyłanie informacji o sobie, łączenie się z urządzeniami Wi‑Fi w pobliżu i określanie ich względnego położenia"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"określanie względnego położenia urządzeń w pobliżu"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Zezwól na określanie przez aplikację względnego położenia urządzeń w pobliżu"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacje o preferowanych usługach płatniczych NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pozwala aplikacji uzyskiwać informacje o preferowanych usługach płatniczych NFC, np. zarejestrowanych pomocach i miejscach docelowych tras."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolowanie łączności Near Field Communication"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1719648d10f0..a2192767258a 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -323,7 +323,7 @@
<string name="permgrouplab_location" msgid="1858277002233964394">"Localização"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"acesse o local do dispositivo"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
+ <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acessar sua agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
<string name="permgrouplab_storage" msgid="17339216290379241">"Arquivos"</string>
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app divulgue, faça conexão e determine a posição relativa de dispositivos Wi-Fi por perto."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determinar o posicionamento relativo entre dispositivos por perto"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permitir que o app determine o posicionamento relativo entre dispositivos por perto"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index b8fc6a96f783..a898121434e5 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permita que a app determine a posição relativa entre os dispositivos de banda ultralarga próximos"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi‑Fi próximos"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que a app anuncie, estabeleça ligação e determine a posição relativa de dispositivos Wi‑Fi próximos"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determinar a posição relativa entre disp. próximos"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permita que a app determine a posição relativa entre os dispositivos próximos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações de serviços de pagamento com NFC preferenciais"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que a app obtenha informações de serviços de pagamento com NFC preferenciais, como apoios registados e destino da rota."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlo Near Field Communication"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1719648d10f0..a2192767258a 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -323,7 +323,7 @@
<string name="permgrouplab_location" msgid="1858277002233964394">"Localização"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"acesse o local do dispositivo"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
+ <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acessar sua agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
<string name="permgrouplab_storage" msgid="17339216290379241">"Arquivos"</string>
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app divulgue, faça conexão e determine a posição relativa de dispositivos Wi-Fi por perto."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"determinar o posicionamento relativo entre dispositivos por perto"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permitir que o app determine o posicionamento relativo entre dispositivos por perto"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7843bbe1e9f1..8b7a29683d8e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"să interacționeze cu dispozitive Wi‑Fi din apropiere"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite aplicației să se conecteze la dispozitive Wi-Fi din apropiere, să transmită anunțuri și să stabilească poziția relativă a acestora"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"stabilește poziția dispozitivelor din apropiere"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Permite-i aplicației să stabilească poziția relativă dintre dispozitivele din apropiere"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite aplicației să obțină informații despre serviciul de plăți NFC preferat, de exemplu, identificatorii de aplicație înregistrați și destinația traseului."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
@@ -2437,7 +2435,7 @@
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Înapoi"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string>
<string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Funcția SOS prin satelit este acum disponibilă"</string>
- <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Poți să trimiți mesaje serviciilor de urgență dacă nu este disponibilă o rețea mobilă sau Wi-Fi. Mesaje Google trebuie să fie aplicația ta pentru mesaje prestabilită."</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Poți să trimiți mesaje serviciilor de urgență dacă nu este disponibilă o rețea mobilă sau Wi-Fi. Mesaje Google trebuie să fie aplicația ta prestabilită pentru mesaje."</string>
<string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Funcția SOS prin satelit nu este acceptată"</string>
<string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Funcția SOS prin satelit nu este acceptată pe acest dispozitiv"</string>
<string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Funcția SOS prin satelit nu este configurată"</string>
@@ -2445,11 +2443,11 @@
<string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Funcția SOS prin satelit nu este disponibilă"</string>
<string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Funcția SOS prin satelit nu este disponibilă în această țară sau regiune"</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Funcția SOS prin satelit nu este configurată"</string>
- <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație pentru mesaje prestabilită"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație prestabilită pentru mesaje"</string>
<string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Funcția SOS prin satelit nu este disponibilă"</string>
<string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Pentru a verifica dacă funcția SOS prin satelit este disponibilă în această țară sau regiune, activează setările privind locația"</string>
<string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Mesajele prin satelit sunt disponibile"</string>
- <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Dacă nu este disponibilă o rețea mobilă sau Wi-Fi, poți să trimiți mesaje prin satelit. Mesaje Google trebuie să fie aplicația ta pentru mesaje prestabilită."</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Dacă nu este disponibilă o rețea mobilă sau Wi-Fi, poți să trimiți mesaje prin satelit. Mesaje Google trebuie să fie aplicația ta prestabilită pentru mesaje."</string>
<string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Mesajele prin satelit nu sunt acceptate"</string>
<string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Mesajele prin satelit nu sunt acceptate pe acest dispozitiv"</string>
<string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mesajele prin satelit nu sunt configurate"</string>
@@ -2457,7 +2455,7 @@
<string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Mesajele prin satelit nu sunt disponibile"</string>
<string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Mesajele prin satelit nu sunt disponibile în această țară sau regiune"</string>
<string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mesajele prin satelit nu sunt configurate"</string>
- <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație pentru mesaje prestabilită"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Pentru a trimite mesaje prin satelit, setează Mesaje Google ca aplicație prestabilită pentru mesaje"</string>
<string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Mesajele prin satelit nu sunt disponibile"</string>
<string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Pentru a verifica dacă mesajele prin satelit sunt disponibile în această țară sau regiune, activează setările privind locația"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 8caa8b60c120..386830e83e66 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Приложение сможет определять относительное позиционирование устройств с технологией сверхширокополосной связи поблизости"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Взаимодействие с устройствами Wi‑Fi поблизости"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Приложение сможет передавать данные на устройства Wi‑Fi рядом, подключаться к ним и определять их примерное местоположение."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"относительное местоположение устройств поблизости"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Приложение сможет определять относительное местоположение устройств поблизости."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Сведения о предпочтительном платежном сервисе NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Приложение сможет получать сведения о предпочтительном платежном сервисе NFC (например, зарегистрированные идентификаторы AID и конечный пункт маршрута)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Управление NFC-модулем"</string>
@@ -2444,11 +2442,11 @@
<string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Спутниковый SOS не настроен"</string>
<string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Проверьте подключение к интернету и повторите попытку."</string>
<string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Спутниковый SOS недоступен"</string>
- <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Функция недоступна в этой стране или регионе."</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Функция недоступна в стране или в этом регионе."</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Спутниковый SOS не настроен"</string>
<string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Чтобы использовать эту функцию, необходимо выбрать Google Сообщения в качестве мессенджера по умолчанию."</string>
<string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Спутниковый SOS недоступен"</string>
- <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Чтобы узнать, можно ли использовать спутниковый SOS в этой стране или регионе, включите настройки геолокации."</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Чтобы узнать, можно ли использовать спутниковый SOS в стране или в этом регионе, включите настройки геолокации."</string>
<string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Доступен спутниковый обмен сообщениями"</string>
<string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Вы можете обмениваться сообщениями по спутниковой связи, даже когда подключение к мобильной сети или Wi-Fi недоступно. Google Сообщения должны быть выбраны в качестве мессенджера по умолчанию."</string>
<string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Спутниковый обмен сообщениями не поддерживается"</string>
@@ -2456,11 +2454,11 @@
<string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Спутниковый обмен сообщениями не настроен"</string>
<string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Проверьте подключение к интернету и повторите попытку."</string>
<string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Спутниковый обмен сообщениями недоступен"</string>
- <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Функция недоступна в этой стране или регионе."</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Функция недоступна в стране или в этом регионе."</string>
<string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Спутниковый обмен сообщениями не настроен"</string>
<string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Чтобы использовать эту функцию, необходимо выбрать Google Сообщения в качестве мессенджера по умолчанию."</string>
<string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Спутниковый обмен сообщениями недоступен"</string>
- <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Чтобы узнать, можно ли обмениваться сообщениями по спутниковой связи в этой стране или регионе, включите настройки геолокации."</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Чтобы узнать, можно ли обмениваться сообщениями по спутниковой связи в стране или в этом регионе, включите настройки геолокации."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f150cd189f45..e969a8ed523f 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"අවට ඇති අල්ට්‍රා-වයිඩ්බෑන්ඩ් උපාංග අතර සාපේක්ෂ පිහිටීම නිර්ණය කිරීමට යෙදුමට ඉඩ දීම"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"අවට Wi‑Fi උපාංග සමග අන්තර්ක්‍රියා කරන්න"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"වෙළඳ දැන්වීම් පළ කිරීමට, සම්බන්ධ වීමට සහ අවට ඇති Wi-Fi උපාංගවල සාපේක්ෂ පිහිටීම නිර්ණය කිරීමට යෙදුමට ඉඩ දෙයි"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"අවට උපාංග අතර සාපේක්ෂ පිහිටීම තීරණය කරන්න"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"අවට උපාංග අතර සාපේක්ෂ පිහිටීම තීරණය කිරීමට යෙදුමට ඉඩ දෙන්න"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"කැමති NFC ගෙවීම් සේවා තොරතුරු"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ලියාපදිංචි කළ ආධාර සහ ගමන් මාර්ග ගමනාන්ත වැනි කැමති nfc ගෙවීම් සේවා තොරතුරු ලබා ගැනීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ආසන්න ක්ෂේත්‍ර සන්නිවේදනය පාලනය කරන්න"</string>
@@ -2409,7 +2407,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"යතුරු පුවරුව <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ලෙස සකසා ඇත… වෙනස් කිරීමට තට්ටු කරන්න."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"භෞතික යතුරු පුවරුව වින්‍යාස කෙරිණි"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"යතුරු පුවරු බැලීමට තට්ටු කරන්න"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"පෞද්ගලික"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"රහසිගත"</string>
<string name="profile_label_clone" msgid="769106052210954285">"ක්ලෝන කරන්න"</string>
<string name="profile_label_work" msgid="3495359133038584618">"කාර්යාලය"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"කාර්යාලය 2"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ක්‍රියාත්මක කරන්න"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"ආපසු යන්න"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"චන්ද්‍රිකා SOS දැන් ලබා ගත හැක"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"ජංගම හෝ Wi-Fi ජාලයක් නොමැති නම් ඔබට හදිසි සේවා පණිවිඩ යැවීමට හැක. Google Messages ඔබේ පෙරනිමි පණිවිඩකරණ යෙදුම විය යුතු යි."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"චන්ද්‍රිකා SOS සහාය නොදක්වයි"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"මෙම උපාංගය මත චන්ද්‍රිකා SOS සහාය නොදක්වයි"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"චන්ද්‍රිකා SOS පිහිටුවා නැත"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"ඔබ අන්තර්ජාලයට සම්බන්ධ වී ඇති බවට වග බලා ගෙන නැවත පිහිටුවීමට උත්සාහ කරන්න"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"චන්‍ද්‍රික SOS ලබා ගත නොහැක"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"චන්ද්‍රිකා SOS මෙම රටෙහි හෝ කලාපයෙහි ලබා ගත නොහැක"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"චන්ද්‍රිකා SOS පිහිටුවා නැත"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"චන්ද්‍රිකා මඟින් පණිවිඩ යැවීමට, Google Messages ඔබේ පෙරනිමි පණිවිඩ යැවීමේ යෙදුම ලෙස සකසන්න"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"චන්‍ද්‍රික SOS ලබා ගත නොහැක"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"මෙම රටෙහි හෝ කලාපය තුළ චන්ද්‍රිකා SOS ලබා ගත හැකි දැයි පරීක්ෂා කිරීමට, ස්ථාන සැකසීම් ක්‍රියාත්මක කරන්න"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත හැක"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"ජංගම හෝ Wi-Fi ජාලයක් නොමැති නම් ඔබට චන්ද්‍රිකාවෙන් පණිවිඩයක් යැවිය හැක. Google Messages ඔබේ පෙරනිමි පණිවිඩකරණ යෙදුම විය යුතු යි."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"චන්ද්‍රිකා පණිවිඩ යැවීමට සහය නොදක්වයි"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"මෙම උපාංගය මත චන්ද්‍රිකා පණිවිඩ යැවීමට සහය නොදක්වයි"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"චන්ද්‍රිකා පණිවිඩ යැවීම පිහිටුවා නැත"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"ඔබ අන්තර්ජාලයට සම්බන්ධ වී ඇති බවට වග බලා ගෙන නැවත පිහිටුවීමට උත්සාහ කරන්න"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත නොහැක"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"චන්ද්‍රිකා පණිවිඩ යැවීම මෙම රටෙහි හෝ කලාපයෙහි ලබා ගත නොහැක"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"චන්ද්‍රිකා පණිවිඩ යැවීම පිහිටුවා නැත"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"චන්ද්‍රිකා මඟින් පණිවිඩ යැවීමට, Google Messages ඔබේ පෙරනිමි පණිවිඩ යැවීමේ යෙදුම ලෙස සකසන්න"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත නොහැක"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"මෙම රටෙහි හෝ කලාපය තුළ චන්ද්‍රිකා පණිවිඩ යැවීම ලබා ගත හැකි දැයි පරීක්ෂා කිරීමට, ස්ථාන සැකසීම් ක්‍රියාත්මක කරන්න"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index e17e25f4734d..d211d8c481f7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Povoľte aplikácii určovať relatívnu polohu medzi zariadeniami s ultraširokopásmovým pripojením v okolí"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interakcia so zariadeniami Wi-Fi v okolí"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Umožňuje aplikácii oznamovať a rozpoznávať relatívnu polohu zariadení Wi‑Fi v okolí a pripájať sa k nim"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"určovať relatívnu polohu medzi zariadeniami v okolí"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Povoľte aplikácii určovať relatívnu polohu medzi zariadeniami v okolí"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferované informácie platenej služby NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Umožňuje aplikácii získavať preferované informácie platenej služby NFC, napríklad o registrovanej pomoci a trasách k cieľu."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ovládať technológiu NFC"</string>
@@ -2437,54 +2435,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnúť"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Prejsť späť"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Pomoc cez satelit je teraz k dispozícii"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Tiesňovej linke môžete poslať správu, keď nie je dostupná mobilná sieť ani sieť Wi‑Fi. Správy Google musíte mať nastavené ako predvolený komunikátor."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Pomoc cez satelit nie je podporovaná"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Pomoc cez satelit nie je v tomto zariadení podporovaná"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Pomoc cez satelit nie je nastavená"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Skontrolujte, či máte internetové pripojenie, a skúste nastavenie zopakovať"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Pomoc cez satelit nie je k dispozícii"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Pomoc cez satelit nie je v tejto krajine alebo regióne k dispozícii"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Pomoc cez satelit nie je nastavená"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Ak chcete posielať správy cez satelit, nastavte Správy Google ako predvolený komunikátor"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Pomoc cez satelit nie je k dispozícii"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ak chcete skontrolovať, či je pomoc cez satelit v tejto krajine alebo regióne k dispozícii, zapnite nastavenia polohy"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Správy cez satelit sú k dispozícii"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Keď nie je dostupná mobilná sieť ani sieť Wi‑Fi, môžete posielať správy cez satelit. Správy Google musíte mať nastavené ako predvolený komunikátor."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Správy cez satelit nie sú podporované"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Správy cez satelit nie sú v tomto zariadení podporované"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Správy cez satelit nie sú nastavené"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Skontrolujte, či máte internetové pripojenie, a skúste nastavenie zopakovať"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Správy cez satelit nie sú k dispozícii"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Správy cez satelit nie sú v tejto krajine alebo regióne k dispozícii"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Správy cez satelit nie sú nastavené"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Ak chcete posielať správy cez satelit, nastavte Správy Google ako predvolený komunikátor"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Správy cez satelit nie sú k dispozícii"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ak chcete skontrolovať, či sú správy cez satelit v tejto krajine alebo regióne k dispozícii, zapnite nastavenia polohy"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index da9f1c189610..ca854340fc43 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami UWB v bližini."</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"komunikacija z napravami Wi‑Fi v bližini"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji dovoljuje objavljanje in določanje relativnega položaja naprav Wi‑Fi v bližini ter povezovanje z njimi."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"določanje relativne oddaljenosti med napravami v bližini"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami v bližini"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikaciji omogoča pridobivanje podatkov o prednostni storitvi za plačevanje prek povezave NFC, kot so registrirani pripomočki in cilj preusmeritve."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"nadzor nad komunikacijo s tehnologijo bližnjega polja"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1b8d0a0095f3..45cf31a9b0e8 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"të ndërveprojë me pajisjet Wi-Fi në afërsi"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lejon që aplikacioni të reklamojë, të lidhet dhe të përcaktojë pozicionin përkatës të pajisjeve Wi-Fi në afërsi"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacionet për shërbimin e preferuar të pagesës me NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lejon aplikacionin të marrë informacione për shërbimin e preferuar të pagesës me NFC si p.sh. ndihmat e regjistruara dhe destinacionin e itinerarit."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
@@ -2186,7 +2184,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth-i do të qëndrojë i aktivizuar gjatë modalitetit të aeroplanit"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Po ngarkohet"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # skedar}other{{file_name} + # skedarë}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nuk ka persona të rekomanduar për ta ndarë"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nuk ka persona të rekomanduar për të ndarë"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista e aplikacioneve"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Këtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Ekrani bazë"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Aktivizo"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Kthehu prapa"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"\"SOS satelitor\" ofrohet tani"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mund t\'u dërgosh mesazhe shërbimeve të urgjencës nëse nuk ka rrjet celular ose Wi-Fi. \"Mesazhet e Google\" duhet të jenë aplikacioni yt i parazgjedhur i mesazheve."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"\"SOS satelitor\" nuk mbështetet"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"\"SOS satelitor\" nuk mbështetet në këtë pajisje"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"\"SOS satelitor\" nuk është konfiguruar"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Sigurohu që të jesh lidhur me internetin dhe provo përsëri konfigurimin"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"\"SOS satelitor\" nuk ofrohet"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"\"SOS satelitor\" nuk ofrohet në këtë shtet ose rajon"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"\"SOS satelitor\" nuk është konfiguruar"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Për të shkëmbyer mesazhe nëpërmjet satelitit, cakto \"Mesazhet e Google\" si aplikacionin e parazgjedhur të mesazheve"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"\"SOS satelitor\" nuk ofrohet"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Për të kontrolluar nëse \"SOS satelitor\" ofrohet në këtë shtet ose rajon, aktivizo cilësimet e vendndodhjes"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Ofrohet shkëmbimi i mesazheve nëpërmjet satelitit"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Mund të shkëmbesh mesazhe nëpërmjet satelitit nëse nuk ka rrjet celular ose Wi-Fi. \"Mesazhet e Google\" duhet të jenë aplikacioni yt i parazgjedhur i mesazheve."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk mbështetet"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk mbështetet në këtë pajisje"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk është konfiguruar"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Sigurohu që të jesh lidhur me internetin dhe provo përsëri konfigurimin"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk ofrohet"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk ofrohet në këtë shtet ose rajon"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk është konfiguruar"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Për të shkëmbyer mesazhe nëpërmjet satelitit, cakto \"Mesazhet e Google\" si aplikacionin e parazgjedhur të mesazheve"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Shkëmbimi i mesazheve nëpërmjet satelitit nuk ofrohet"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Për të kontrolluar nëse shkëmbimi i mesazheve nëpërmjet satelitit ofrohet në këtë shtet ose rajon, aktivizo cilësimet e vendndodhjes"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\""</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index bdf557173391..5a3bae0012bc 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -613,10 +613,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозвољава апликацији да одређује релативну раздаљину између уређаја ултра-широког појаса у близини"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"интеракција са WiFi уређајима у близини"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозвољава апликацији да се оглашава, повезује и утврђује релативну позицију WiFi уређаја у близини"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"одређивање раздаљине између уређаја у близини"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Дозволите апликацији да одређује релативну раздаљину између уређаја у близини"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информације о жељеној NFC услузи за плаћање"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозвољава апликацији да преузима информације о жељеној NFC услузи за плаћање, попут регистрованих идентификатора апликација и одредишта преусмеравања."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контрола комуникације у ужем пољу (Near Field Communication)"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 8bef5ca8a842..fde90235e6ee 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillåt att appen fastställer den relativa positionen mellan Ultra Wideband-enheter i närheten"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagera med wifi-enheter i närheten"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Tillåter appen att sända ut till, ansluta till och fastställa relativ position för wifi-enheter i närheten"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"fastställa relativ position för enheter i närheten"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Tillåt att appen fastställer den relativa positionen mellan enheter i närheten"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information kopplad till standardtjänsten för NFC-betalning"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillåter att appen hämtar information kopplad till standardtjänsten för NFC-betalning, till exempel registrerade hjälpmedel och ruttdestinationer."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollera närfältskommunikationen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 010415eaf313..2a62c87d16d9 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ruhusu programu ibainishe nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tumia vifaa vya Wi‑Fi vilivyo karibu"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Huruhusu programu kutangaza, kuunganisha na kubaini mahali palipokadiriwa vilipo vifaa vya Wi-Fi vilivyo karibu"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"kubainisha nafasi kati ya vifaa vilivyo karibu"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Ruhusu programu ibainishe nafasi kati ya vifaa vilivyo karibu"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maelezo ya Huduma Inayopendelewa ya Malipo ya NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Huruhusu programu kupata maelezo ya huduma inayopendelewa ya malipo ya nfc kama vile huduma zilizosajiliwa na njia."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kudhibiti Mawasiliano ya Vifaa Vilivyokaribu (NFC)"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Washa"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Rudi nyuma"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Kipengele cha Msaada kupitia Setilaiti sasa kinapatikana"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Unaweza kutumia huduma za dharura ujumbe iwapo hakuna mtandao wa simu au wa Wi-Fi. Ni sharti uweke Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Kipengele cha Msaada kupitia Setilaiti hakiwezi kutumika"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Kipengele cha Msaada kupitia Setilaiti hakiwezi kutumika kwenye kifaa hiki"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Mipangilio ya kipengele cha Msaada kupitia Setilaiti haijawekwa"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Hakikisha kuwa umeunganisha kifaa chako kwenye intaneti kisha ujaribu kuweka mipangilio tena"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Kipengele cha Msaada kupitia Setilaiti hakipatikani"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Kipengele cha Msaada kupitia Setilaiti hakipatikani katika nchi au eneo hili"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Mipangilio ya kipengele cha Msaada kupitia Setilaiti haijawekwa"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Ili utume ujumbe kupitia setilaiti, weka Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Kipengele cha Msaada kupitia Setilaiti hakipatikani"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ili uangalie iwapo kipengele cha Msaada kupitia Setilaiti kinapatikana katika nchi au eneo hili, washa mipangilio ya mahali"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Kipengele cha kutuma ujumbe kupitia setilaiti kinapatikana"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Unaweza kutuma ujumbe kupitia setilaiti iwapo hakuna mtandao wa simu au wa Wi-Fi. Ni sharti uweke Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Kipengele cha kutuma ujumbe kupitia setilaiti hakiwezi kutumika"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Kipengele cha kutuma ujumbe kupitia setilaiti hakiwezi kutumika kwenye kifaa hiki"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Mipangilio ya kutuma ujumbe kupitia setilaiti haijawekwa"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Hakikisha kuwa umeunganisha kifaa chako kwenye intaneti kisha ujaribu kuweka mipangilio tena"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Kipengele cha kutuma ujumbe kupitia setilaiti hakipatikani"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Kipengele cha kutuma ujumbe kupitia setilaiti hakipatikani katika nchi au eneo hili"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Mipangilio ya kutuma ujumbe kupitia setilaiti haijawekwa"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Ili utume ujumbe kupitia setilaiti, weka Google Messages iwe programu yako chaguomsingi ya kutuma ujumbe"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Kipengele cha kutuma ujumbe kupitia setilaiti hakipatikani"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ili uangalie iwapo kipengele cha kutuma ujumbe kupitia setilaiti kinapatikana katika nchi au eneo hili, washa mipangilio ya mahali"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 1915f2982611..6ff96c00ea8d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"அருகிலுள்ள அல்ட்ரா-வைடுபேண்ட் சாதனங்களுக்கிடையிலான தூரத்தைத் தீர்மானிக்க ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"அருகிலுள்ள வைஃபை சாதனங்களுடன் தொடர்பு கொள்ளுதல்"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"அருகிலுள்ள வைஃபை சாதனங்களைத் தெரியப்படுத்தவும் இணைக்கவும் இருப்பிடத்தைத் தீர்மானிக்கவும் இது ஆப்ஸை அனுமதிக்கும்"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"அருகிலுள்ள சாதனங்களுக்கான தூரத்தைத் தீர்மானித்தல்"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"அருகிலுள்ள சாதனங்களுக்கு இடையிலான தூரத்தைத் தீர்மானிக்க ஆப்ஸை அனுமதிக்கும்"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்கள்"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"பதிவுசெய்யப்பட்ட கருவிகள், சேருமிடத்திற்கான வழி போன்ற விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"குறுகிய இடைவெளி தகவல்பரிமாற்றத்தைக் கட்டுப்படுத்துதல்"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"இயக்கு"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"பின்செல்"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"சாட்டிலைட் SOS அம்சம் இப்போது கிடைக்கிறது"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"மொபைல்/வைஃபை நெட்வொர்க் இல்லையென்றால், அவசரகால சேவைகளுக்கு மெசேஜ் அனுப்பலாம். Google Messages உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக இருக்க வேண்டும்."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"சாட்டிலைட் SOS ஆதரிக்கப்படவில்லை"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"இந்தச் சாதனத்தில் சாட்டிலைட் SOS ஆதரிக்கப்படவில்லை"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"சாட்டிலைட் SOS அமைக்கப்படவில்லை"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"இணையத்துடன் இணைக்கப்பட்டிருப்பதை உறுதிசெய்துகொண்டு மீண்டும் அமைக்க முயலுங்கள்"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"சாட்டிலைட் SOS கிடைக்கவில்லை"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"இந்த நாடு/பிராந்தியத்தில் சாட்டிலைட் SOS கிடைக்கவில்லை"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"சாட்டிலைட் SOS அமைக்கப்படவில்லை"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"சாட்டிலைட் மூலம் மெசேஜ் செய்ய, Google Messages ஆப்ஸை உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக அமையுங்கள்"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"சாட்டிலைட் SOS கிடைக்கவில்லை"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"இந்த நாட்டிலோ பிராந்தியத்திலோ சாட்டிலைட் SOS கிடைக்கிறதா எனப் பார்க்க இருப்பிட அமைப்புகளை இயக்குங்கள்"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"சாட்டிலைட் மெசேஜிங் கிடைக்கிறது"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"மொபைல்/வைஃபை நெட்வொர்க் இல்லையென்றால் சாட்டிலைட் மூலம் மெசேஜ் அனுப்பலாம். Google Messages உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக இருக்க வேண்டும்."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"சாட்டிலைட் மெசேஜிங் ஆதரிக்கப்படவில்லை"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"இந்தச் சாதனத்தில் சாட்டிலைட் மெசேஜிங் ஆதரிக்கப்படவில்லை"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"சாட்டிலைட் மெசேஜிங் அமைக்கப்படவில்லை"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"இணையத்துடன் இணைக்கப்பட்டிருப்பதை உறுதிசெய்துகொண்டு மீண்டும் அமைக்க முயலுங்கள்"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"சாட்டிலைட் மெசேஜிங் கிடைக்கவில்லை"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"இந்த நாடு/பிராந்தியத்தில் சாட்டிலைட் மெசேஜிங் கிடைக்கவில்லை"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"சாட்டிலைட் மெசேஜிங் அமைக்கப்படவில்லை"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"சாட்டிலைட் மூலம் மெசேஜ் செய்ய, Google Messages ஆப்ஸை உங்கள் இயல்புநிலை மெசேஜிங் ஆப்ஸாக அமையுங்கள்"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"சாட்டிலைட் மெசேஜிங் கிடைக்கவில்லை"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"இந்த நாட்டிலோ பிராந்தியத்திலோ சாட்டிலைட் மெசேஜிங் கிடைக்கிறதா எனப் பார்க்க இருப்பிட அமைப்புகளை இயக்குங்கள்"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6ac81642d41f..68fce1f8175a 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -354,7 +354,7 @@
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"మీరు టైప్ చేస్తున్న వచనాన్ని పరిశీలిస్తుంది"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"క్రెడిట్ కార్డు నంబర్‌లు మరియు పాస్‌వర్డ్‌ల వంటి వ్యక్తిగత డేటాను కలిగి ఉంటుంది."</string>
<string name="capability_title_canControlMagnification" msgid="7701572187333415795">"డిస్‌ప్లే మ్యాగ్నిఫికేషన్‌ను నియంత్రించండి"</string>
- <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"డిస్‌ప్లే జూమ్ స్థాయి మరియు స్థానాన్ని నియంత్రిస్తుంది."</string>
+ <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"డిస్‌ప్లే జూమ్ స్థాయి మరియు లొకేషన్‌ని నియంత్రిస్తుంది."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"సంజ్ఞలను చేయడం"</string>
<string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"నొక్కగలరు, స్వైప్ చేయగలరు, స్క్రీన్‌పై రెండు వేళ్లను ఉంచి ఆ వేళ్లను దగ్గరకు లేదా దూరానికి లాగగలరు మరియు ఇతర సంజ్ఞలను చేయగలరు."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"వేలిముద్ర సంజ్ఞలు"</string>
@@ -608,14 +608,12 @@
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వడానికి యాప్‌ను అనుమతిస్తుంది"</string>
<string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయండి"</string>
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయడానికి యాప్‌కు అనుమతిని ఇస్తుంది"</string>
- <string name="permlab_uwb_ranging" msgid="8141915781475770665">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించండి"</string>
- <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించడానికి యాప్‌ను అనుమతించండి"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సంబంధిత పొజిషన్‌ను నిర్ణయించండి"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"సమీపంలోని అల్ట్రా-వైడ్‌బ్యాండ్ పరికరాల మధ్య సంబంధిత పొజిషన్‌ను నిర్ణయించడానికి యాప్‌ను అనుమతించండి"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"సమీపంలోని Wi-Fi పరికరాలతో ఇంటరాక్ట్ చేస్తుంది"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"అడ్వర్టయిజ్, కనెక్ట్ చేయడానికి, సమీపంలోని Wi-Fi పరికరాల సంబంధిత పొజిషన్‌ను నిర్ణయించడానికి యాప్‌ను అనుమతిస్తుంది"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"సమీపంలో పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించండి"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"సమీపంలోని పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించడానికి యాప్‌ను అనుమతించండి"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారం"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారాన్ని, అంటే రిజిస్టర్ చేయబడిన సహాయక సాధనాలు, మార్గం, గమ్యస్థానం వంటి వాటిని పొందేందుకు యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"సమీప క్షేత్ర కమ్యూనికేషన్‌ను నియంత్రించడం"</string>
@@ -724,7 +722,7 @@
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"బాగా కదుపుతున్నారు. ఫోన్‌ను స్థిరంగా పట్టుకోండి"</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"దయచేసి మీ ముఖాన్ని మళ్లీ నమోదు చేయండి."</string>
<string name="face_acquired_too_different" msgid="4505278456634706967">"ముఖం గుర్తించబడలేదు. మళ్లీ ట్రై చేయండి."</string>
- <string name="face_acquired_too_similar" msgid="8882920552674125694">"మీ తల స్థానాన్ని కొద్దిగా మార్చండి"</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>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"ఆన్ చేయండి"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"వెనుకకు వెళ్లండి"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్‌లో ఉంది..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"ఎమర్జెన్సీ శాటిలైట్ సహాయం ఇప్పుడు అందుబాటులో ఉంది"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"మొబైల్ లేదా Wi-Fi నెట్‌వర్క్ ఏదీ లేనట్లయితే మీరు ఎమర్జెన్సీ సర్వీసులకు మెసేజ్ చేయవచ్చు. Google Messages అనేది తప్పనిసరిగా మీ ఆటోమేటిక్ మెసేజింగ్ యాప్‌గా సెట్ చేసి ఉండాలి."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సపోర్ట్ చేయదు"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"ఈ పరికరంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం సపోర్ట్ చేయదు"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సెటప్ కాలేదు"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"మీరు ఇంటర్నెట్‌కు కనెక్ట్ అయి ఉన్నారని నిర్ధారించుకుని, మళ్లీ సెటప్‌ను ట్రై చేయండి"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"ఈ దేశంలో లేదా ప్రాంతంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"ఎమర్జెన్సీ శాటిలైట్ సహాయం సెటప్ చేయలేదు"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ సెట్టింగ్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో లేదు"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"ఈ దేశంలో లేదా ప్రాంతంలో ఎమర్జెన్సీ శాటిలైట్ సహాయం అందుబాటులో ఉందో లేదో చెక్ చేయడానికి, లొకేషన్ సెట్టింగ్‌లను ఆన్ చేయండి"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"శాటిలైట్ మెసేజింగ్ అందుబాటులో ఉంది"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"మొబైల్ లేదా Wi-Fi నెట్‌వర్క్ లేకుంటే మీరు శాటిలైట్ ద్వారా మెసేజ్‌ను పంపవచ్చు. Google Messages అనేది తప్పనిసరిగా మీ ఆటోమేటిక్ మెసేజింగ్ యాప్‌గా సెట్ చేసి ఉండాలి."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"శాటిలైట్ మెసేజింగ్ సపోర్ట్ చేయదు"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"ఈ పరికరంలో శాటిలైట్ మెసేజింగ్ సపోర్ట్ చేయదు"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"శాటిలైట్ మెసేజింగ్‌ను సెటప్ చేయలేదు"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"మీరు ఇంటర్నెట్‌కు కనెక్ట్ అయి ఉన్నారని నిర్ధారించుకుని, మళ్లీ సెటప్‌ను ట్రై చేయండి"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"ఈ దేశంలో లేదా ప్రాంతంలో శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"శాటిలైట్ మెసేజింగ్‌ను సెటప్ చేయలేదు"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"శాటిలైట్ ద్వారా మెసేజ్ చేయడానికి, Google Messagesను మీ ఆటోమేటిక్ సెట్టింగ్ మెసేజింగ్ యాప్‌గా సెట్ చేయండి"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"శాటిలైట్ మెసేజింగ్ అందుబాటులో లేదు"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"ఈ దేశంలో లేదా ప్రాంతంలో శాటిలైట్ మెసేజింగ్ అందుబాటులో ఉందో లేదో చెక్ చేయడానికి, లొకేషన్ సెట్టింగ్‌లను ఆన్ చేయండి"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>‌ను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‌లను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 763eb6266198..178a76d3a404 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"อนุญาตให้แอประบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่ใช้แถบความถี่กว้างยิ่งยวดซึ่งอยู่ใกล้เคียง"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"โต้ตอบกับอุปกรณ์ Wi-Fi ที่อยู่ใกล้เคียง"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"อนุญาตให้แอปแสดงข้อมูล เชื่อมต่อ และระบุตำแหน่งซึ่งสัมพันธ์กับอุปกรณ์ Wi-Fi ที่อยู่ใกล้เคียง"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"ระบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"อนุญาตให้แอประบุตำแหน่งสัมพันธ์ระหว่างอุปกรณ์ที่อยู่ใกล้เคียง"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ข้อมูลบริการชำระเงิน NFC ที่ต้องการ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"อนุญาตให้แอปรับข้อมูลบริการชำระเงิน NFC ที่ต้องการ เช่น รหัสแอป (AID) ที่ลงทะเบียนและปลายทางของเส้นทาง"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ควบคุม Near Field Communication"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index b44faae4e84f..8e3c5e7433a7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Payagan ang app na tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"makipag-ugnayan sa mga kalapit na Wi‑Fi device"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Nagbibigay-daan sa app na i-advertise ang, kumonekta sa, at tukuyin ang nauugnay na posisyon ng mga kalapit na Wi‑Fi device"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"alamin ang relative position sa kalapit na device"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Payagan ang app na alamin ang relatibong posisyon sa pagitan ng mga kalapit na device"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Impormasyon sa Gustong NFC na Serbisyo sa Pagbabayad"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pinapayagan ang app na makakuha ng impormasyon sa gustong nfc na serbisyo sa pagbabayad tulad ng mga nakarehistrong application ID at destinasyon ng ruta."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e54b8999a1dc..98b1dd3ef245 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Uygulamanın, yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu belirlemesine izin verin"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yakındaki kablosuz cihazlarla etkileşim kur"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Uygulamanın reklam sunmasına, bağlanmasına ve yakındaki kablosuz cihazların göreli konumunu belirlemesine izin verir"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"yakındaki cihazların göreli konumunu belirleme"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Uygulamanın, yakındaki cihazların birbirine göre konumunu belirlemesine izin verin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tercih Edilen NFC Ödeme Hizmeti Bilgileri"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Uygulamaya, kayıtlı yardımlar ve rota hedefi gibi tercih edilen NFC ödeme hizmeti bilgilerini alma izni verir."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Yakın Alan İletişimini denetle"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Etkinleştir"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Geri dön"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Acil Uydu Bağlantısı kullanıma sunuldu"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Mobil veya kablosuz ağ bağlantısı yoksa acil durum hizmetleriyle mesajlaşabilirsiniz. Google Mesajlar varsayılan mesajlaşma uygulamanız olmalıdır."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Acil Uydu Bağlantısı desteklenmiyor"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Acil Uydu Bağlantısı bu cihazda desteklenmiyor"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Acil Uydu Bağlantısı özelliği ayarlanmamış"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"İnternete bağlı olup olmadığınızı kontrol edip tekrar ayarlamayı deneyin"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Acil Uydu Bağlantısı kullanılamıyor"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Acil Uydu Bağlantısı özelliği bu ülkede veya bölgede kullanıma sunulmamıştır"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Acil Uydu Bağlantısı özelliği ayarlanmamış"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Uydu üzerinden mesajlaşmak için Google Mesajlar\'ı varsayılan mesajlaşma uygulamanız olarak ayarlayın"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Acil Uydu Bağlantısı kullanılamıyor"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Acil Uydu Bağlantısı özelliğinin bu ülkede veya bölgede kullanılıp kullanılamadığını kontrol etmek için konum ayarlarını açın"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Uydu üzerinden mesajlaşma özelliği kullanılabilir"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Mobil veya kablosuz ağ bağlantısı yoksa uydu üzerinden mesaj gönderebilirsiniz. Google Mesajlar varsayılan mesajlaşma uygulamanız olmalıdır."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Uydu üzerinden mesajlaşma desteklenmiyor"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Uydu üzerinden mesajlaşma bu cihazda desteklenmiyor"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Uydu üzerinden mesajlaşma özelliği ayarlanmamış"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"İnternete bağlı olup olmadığınızı kontrol edip tekrar ayarlamayı deneyin"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Uydu üzerinden mesajlaşma özelliği kullanılamıyor"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Uydu üzerinden mesajlaşma özelliği bu ülkede veya bölgede kullanılamıyor"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Uydu üzerinden mesajlaşma özelliği ayarlanmamış"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Uydu üzerinden mesajlaşmak için Google Mesajlar\'ı varsayılan mesajlaşma uygulamanız olarak ayarlayın"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Uydu üzerinden mesajlaşma özelliği kullanılamıyor"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Uydu üzerinden mesajlaşma özelliğinin bu ülkede veya bölgede kullanılıp kullanılamadığını kontrol etmek için konum ayarlarını açın"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 344cb28afcb2..d5e6bd81ffcc 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -614,10 +614,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"З цим дозволом додаток може визначати відстань між розташованими поблизу пристроями з надширокосмуговим зв’язком"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"взаємодіяти з пристроями Wi‑Fi поблизу"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Додаток може виявляти пристрої Wi‑Fi поблизу, підключатися до них і визначати їх відносне розташування"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"визначати відстань між пристроями поблизу"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Із цим дозволом додаток може визначати відстань між розташованими поблизу пристроями"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Використання інформації з платіжного NFC-сервісу"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволяє додатку отримувати доступ до інформації потрібного платіжного NFC-сервісу (наприклад, пов\'язаних ідентифікаторів чи даних про маршрутизацію трансакцій)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"контрол. Near Field Communication"</string>
@@ -2437,54 +2435,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Увімкнути"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Назад"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Супутниковий сигнал SOS тепер доступний"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Ви можете надсилати повідомлення службам екстреної допомоги, якщо немає з’єднання з Wi-Fi або мобільною мережею. Потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Супутниковий сигнал SOS не підтримується"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Супутниковий сигнал SOS не підтримується на цьому пристрої"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Супутниковий сигнал SOS не налаштовано"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Переконайтеся, що пристрій підключено до Інтернету, і повторіть спробу налаштування"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Супутниковий сигнал SOS недоступний"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Супутниковий сигнал SOS недоступний у цій країні або регіоні"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Супутниковий сигнал SOS не налаштовано"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Щоб обмінюватися повідомленнями через супутник, потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Супутниковий сигнал SOS недоступний"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Щоб дізнатися, чи доступний супутниковий сигнал SOS у цій країні або регіоні, увімкніть доступ до геоданих"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Доступний супутниковий обмін повідомленнями"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Ви можете надсилати й отримувати повідомлення через супутник, якщо немає з’єднання з Wi-Fi або мобільною мережею. Потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Супутниковий обмін повідомленнями не підтримується"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Супутниковий обмін повідомленнями не підтримується на цьому пристрої"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Супутниковий обмін повідомленнями не налаштовано"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Переконайтеся, що пристрій підключено до Інтернету, і повторіть спробу налаштування"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Супутниковий обмін повідомленнями недоступний"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Супутниковий обмін повідомленнями недоступний у цій країні або регіоні"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Супутниковий обмін повідомленнями не налаштовано"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Щоб обмінюватися повідомленнями через супутник, потрібно зробити Google Повідомлення додатком для обміну повідомленнями за умовчанням"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Супутниковий обмін повідомленнями недоступний"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Щоб дізнатися, чи доступний супутниковий обмін повідомленнями в цій країні або регіоні, увімкніть доступ до геоданих"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 45e1a2347dbb..b26b1c102abc 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ایپ کو قریبی الٹرا وائڈ بینڈ آلات کے مابین متعلقہ پوزیشن کا تعین کرنے کی اجازت دیں"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏قریبی Wi-Fi آلات کے ساتھ تعامل کریں"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏ایپ کو اشتہار دینے، منسلک کرنے اور قریبی Wi-Fi آلات کی متعلقہ پوزیشن کا تعین کرنے کی اجازت دیتا ہے"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"قریبی آلات کے مابین متعلقہ پوزیشن کا تعین کریں"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"ایپ کو قریبی آلات کے مابین متعلقہ پوزیشن کا تعین کرنے کی اجازت دیں"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏ترجیح شدہ NFC ادائیگی کی سروس کی معلومات"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏ایپ کو رجسٹرشدہ ایڈز اور روٹ ڈسٹنیشن جیسی ترجیح شدہ nfc ادائیگی سروس کی معلومات حاصل کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"‏Near Field کمیونیکیشن کنٹرول کریں"</string>
@@ -2409,7 +2407,7 @@
<string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> پر سیٹ ہے… تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"فزیکل کی بورڈز کنفیگر کئے گئے"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"کی بورڈز دیکھنے کے لیے تھپتھپائیں"</string>
- <string name="profile_label_private" msgid="6463418670715290696">"نجی"</string>
+ <string name="profile_label_private" msgid="6463418670715290696">"پرائیویٹ"</string>
<string name="profile_label_clone" msgid="769106052210954285">"کلون"</string>
<string name="profile_label_work" msgid="3495359133038584618">"دفتری پروفائل"</string>
<string name="profile_label_work_2" msgid="4691533661598632135">"دوسری دفتری پروفائل"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index f123bea572b1..97e044887d7e 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ilovaga yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlashga ruxsat beradi"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Yaqin-atrofdagi Wi-Fi qurilmalar bilan ishlash"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ilovaga yaqin-atrofdagi Wi-Fi qurilmalarga reklama yuborish, ulanish va ularning taxminiy joylashuvini aniqlash imkonini beradi."</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"atrofdagi qurilmalarning nisbiy joylashuvini aniqlash"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Ilova atrofdagi qurilmalarning nisbiy joylashuvini aniqlashi mumkin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Asosiy NFC toʻlov xizmati haqidagi axborot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Bu ilovaga asosiy NFC toʻlov xizmati haqidagi axborotni olish imkonini beradi (masalan, qayd qilingan AID identifikatorlari va marshrutning yakuniy manzili)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ef50a9badc4c..1ebff32f7d20 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Cho phép ứng dụng xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tương tác với các thiết bị Wi‑Fi lân cận"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Cho phép ứng dụng này thông báo, kết nối và xác định vị trí tương đối của các thiết bị Wi‑Fi lân cận"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"xác định vị trí tương đối giữa các thiết bị ở gần"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Cho phép ứng dụng xác định vị trí tương đối giữa các thiết bị ở gần"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Cho phép ứng dụng nhận thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần mà bạn ưu tiên, chẳng hạn như các hình thức hỗ trợ đã đăng ký và điểm đến trong hành trình."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Bật"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Quay lại"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Tính năng Liên lạc khẩn cấp qua vệ tinh đang hoạt động"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Bạn có thể nhắn tin cho dịch vụ khẩn cấp khi không có mạng di động hay mạng Wi-Fi. Google Tin nhắn phải là ứng dụng nhắn tin mặc định của bạn."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Chưa hỗ trợ tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Thiết bị này chưa hỗ trợ tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Chưa thiết lập tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Hãy kiểm tra để chắc chắn rằng bạn đã kết nối Internet, rồi thử thiết lập lại"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Tính năng Liên lạc khẩn cấp qua vệ tinh chưa hoạt động"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Tính năng Liên lạc khẩn cấp qua vệ tinh chưa hoạt động ở quốc gia hoặc khu vực này"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Chưa thiết lập tính năng Liên lạc khẩn cấp qua vệ tinh"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Để nhắn tin qua vệ tinh, hãy đặt Google Tin nhắn làm ứng dụng nhắn tin mặc định của bạn"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Tính năng Liên lạc khẩn cấp qua vệ tinh chưa hoạt động"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Để kiểm tra xem tính năng Liên lạc khẩn cấp qua vệ tinh có hoạt động ở quốc gia hoặc khu vực này không, hãy bật chế độ cài đặt vị trí"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Tính năng nhắn tin qua vệ tinh đang hoạt động"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Bạn có thể nhắn tin qua vệ tinh khi không có mạng di động hay mạng Wi-Fi. Google Tin nhắn phải là ứng dụng nhắn tin mặc định của bạn."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Chưa hỗ trợ tính năng nhắn tin qua vệ tinh"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Thiết bị này chưa hỗ trợ tính năng nhắn tin qua vệ tinh"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Chưa thiết lập tính năng nhắn tin qua vệ tinh"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Hãy kiểm tra để chắc chắn rằng bạn đã kết nối Internet, rồi thử thiết lập lại"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Tính năng nhắn tin qua vệ tinh chưa hoạt động"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Tính năng nhắn tin qua vệ tinh chưa hoạt động ở quốc gia hoặc khu vực này"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Chưa thiết lập tính năng nhắn tin qua vệ tinh"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Để nhắn tin qua vệ tinh, hãy đặt Google Tin nhắn làm ứng dụng nhắn tin mặc định của bạn"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Tính năng nhắn tin qua vệ tinh chưa hoạt động"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Để kiểm tra xem tính năng nhắn tin qua vệ tinh có hoạt động ở quốc gia hoặc khu vực này không, hãy bật chế độ cài đặt vị trí"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Thiết lập lại tính năng Mở khoá bằng vân tay"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa."</string>
diff --git a/core/res/res/values-watch-v36/config.xml b/core/res/res/values-watch-v36/config.xml
index bb9da177e4fd..1143ae30fe9d 100644
--- a/core/res/res/values-watch-v36/config.xml
+++ b/core/res/res/values-watch-v36/config.xml
@@ -15,7 +15,6 @@
-->
<resources>
- <!-- Overrides system value -->
- <dimen name="config_buttonCornerRadius">26dp</dimen>
+ <dimen name="config_wearMaterial3_buttonCornerRadius">26dp</dimen>
<dimen name="config_bottomDialogCornerRadius">18dp</dimen>
</resources>
diff --git a/core/res/res/values-watch-v36/styles_material.xml b/core/res/res/values-watch-v36/styles_material.xml
index b2760e7c10a7..00f3f092b768 100644
--- a/core/res/res/values-watch-v36/styles_material.xml
+++ b/core/res/res/values-watch-v36/styles_material.xml
@@ -18,13 +18,13 @@
<resources>
<!-- Button Styles -->
<!-- Material Button - Filled -->
- <style name="Widget.DeviceDefault.Button.Filled" parent="Widget.DeviceDefault.Button">
+ <style name="Widget.DeviceDefault.Button.Filled" parent="Widget.DeviceDefault.Button.WearMaterial3">
<item name="android:background">@drawable/btn_background_material_filled</item>
<item name="textAppearance">@style/TextAppearance.Widget.Button.Material.Filled</item>
</style>
<!-- Material Button - Filled Tonal(Override system default button styles) -->
- <style name="Widget.DeviceDefault.Button">
+ <style name="Widget.DeviceDefault.Button.WearMaterial3">
<item name="background">@drawable/btn_background_material_filled_tonal</item>
<item name="textAppearance">@style/TextAppearance.Widget.Button.Material</item>
<item name="minHeight">@dimen/btn_material_height</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index e2f66fc93c08..64c2f70be73e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允许应用确定附近超宽带设备之间的相对位置"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"与附近的 WLAN 设备互动"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允许该应用向附近的 WLAN 设备进行广播、连接到这些设备以及确定这些设备的相对位置"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"确定附近的设备之间的相对位置"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"允许应用确定附近的设备之间的相对位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首选 NFC 付款服务信息"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允许应用获取首选 NFC 付款服务信息,例如注册的应用标识符和路线目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距离通信"</string>
@@ -659,7 +657,7 @@
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用屏幕锁定凭据"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"输入您的屏幕锁定凭据才能继续"</string>
<string name="fingerprint_acquired_partial" msgid="4323789264604479684">"请用力按住传感器"</string>
- <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"无法识别指纹。请重试。"</string>
+ <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"无法识别指纹,请重试。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"请清洁指纹传感器,然后重试"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"请清洁传感器,然后重试"</string>
<string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"请用力按住传感器"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index a2d32805df76..53c5d155cd27 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置之間的相對位置"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"與附近的 Wi‑Fi 裝置互動"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式向附近的 Wi-Fi 裝置顯示此裝置、連接這些裝置並判斷其相對位置"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"判斷附近裝置之間的相對位置"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"允許應用程式判斷附近裝置之間的相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得由用戶允許授權的 NFC 付款服務資訊 (如已註冊的付款輔助功能和最終付款對象)。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"開啟"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"「緊急衛星連接」現已推出"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"在沒有流動網絡或 Wi-Fi 網絡的情況下,你可向緊急服務收發訊息,但你必須將「Google 訊息」設定為預設訊息應用程式。"</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"不支援「緊急衛星連接」"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"此裝置不支援「緊急衛星連接」"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"未設定「緊急衛星連接」"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"請確保已連接互聯網,然後再試一次"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"無法使用「緊急衛星連接」"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"此國家或地區不支援「緊急衛星連接」"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"未設定「緊急衛星連接」"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"你必須將「Google 訊息」設定為預設訊息應用程式,才能透過衛星收發訊息"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"無法使用「緊急衛星連接」"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"如要查看此國家或地區是否可以使用緊急衛星連接功能,請開啟位置設定"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"可以使用衛星訊息功能"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"在沒有流動網絡或 Wi-Fi 網絡的情況下,你可透過衛星收發訊息,但你必須將「Google 訊息」設定為預設訊息應用程式。"</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"無法使用衛星訊息功能"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"此裝置不支援衛星訊息功能"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"未設定衛星訊息功能"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"請確保已連接互聯網,然後再試一次"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"無法使用衛星訊息功能"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"此國家或地區不支援衛星訊息功能"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"未設定衛星訊息功能"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"你必須將「Google 訊息」設定為預設訊息應用程式,才能透過衛星收發訊息"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"無法使用衛星訊息功能"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"如要查看此國家或地區是否支援衛星訊息功能,請開啟位置設定"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d1f8b5a289ed..cbd6bd2fb48f 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置間的相對位置"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"與鄰近的 Wi-Fi 裝置互動"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式顯示鄰近的 Wi-Fi 裝置的資料、與其連線並判斷相對位置"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"判斷鄰近裝置間的相對位置"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"允許應用程式判斷鄰近裝置間的相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得首選 NFC 付費服務資訊,例如已註冊的輔助工具和路線目的地。"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"開啟"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"返回"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"現在可使用「緊急衛星連線」"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"如果沒有行動網路或 Wi-Fi 網路,也可以傳訊息給緊急救援服務。Google 訊息必須是預設訊息應用程式,你才能使用這項功能。"</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"不支援「緊急衛星連線」"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"這部裝置不支援「緊急衛星連線」"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"未設定「緊急衛星連線」"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"請確定已連上網際網路,然後再重新嘗試設定"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"「緊急衛星連線」無法使用"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"無法在這個國家/地區使用「緊急衛星連線」"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"未設定「緊急衛星連線」"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"如要透過衛星傳送訊息,請將 Google 訊息設為預設訊息應用程式"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"「緊急衛星連線」無法使用"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"如要確認「緊急衛星連線」能否在這個國家/地區使用,請開啟位置資訊設定"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"現在可使用「衛星訊息」"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"如果沒有行動網路或 Wi-Fi 網路,可以透過衛星傳送訊息。Google 訊息必須是預設訊息應用程式,你才能使用這項功能。"</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"不支援「衛星訊息」"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"這部裝置不支援「衛星訊息」"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"未設定「衛星訊息」"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"請確定已連上網際網路,然後再重新嘗試設定"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"「衛星訊息」無法使用"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"無法在這個國家/地區使用「衛星訊息」"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"未設定「衛星訊息」"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"如要透過衛星傳送訊息,請將 Google 訊息設為預設訊息應用程式"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"「衛星訊息」無法使用"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"如要確認「衛星訊息」能否在這個國家/地區使用,請開啟位置資訊設定"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」。"</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index d1b7e510168e..f498fe24267c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -612,10 +612,8 @@
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Vumela i-app inqume indawo ehambelanayo phakathi kwamadivayisi e-Ultra-Wideband aseduze"</string>
<string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"xhumana namadivayisi we-Wi‑Fi aseduze"</string>
<string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ivumela i-app ikhangise, ixhume, futhi inqume isimo esihambisanayo samadivayisi we-Wi-Fi aseduze"</string>
- <!-- no translation found for permlab_ranging (2854543350668593390) -->
- <skip />
- <!-- no translation found for permdesc_ranging (6703905535621521710) -->
- <skip />
+ <string name="permlab_ranging" msgid="2854543350668593390">"nquma indawo ehlobene phakathi kwamadivayisi aseduze"</string>
+ <string name="permdesc_ranging" msgid="6703905535621521710">"Vumela i-app inqume indawo ehambelanayo phakathi kwamadivayisi aseduze"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ulwazi Lwesevisi Yenkokhelo Ye-NFC Okhethwayo"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ivuemela uhlelo lokusebenza ukuthola ulwazi lesevisi yenkokhelo ye-nfc njengezinsiza zokubhalisa nezindawo zomzila."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"lawula Uxhumano Lwenkambu Eseduze"</string>
@@ -2435,54 +2433,30 @@
<string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Vula"</string>
<string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Iya emuva"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
- <!-- no translation found for satellite_sos_available_notification_title (5396708154268096124) -->
- <skip />
- <!-- no translation found for satellite_sos_available_notification_summary (1727088812951848330) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_title (2659100983227637285) -->
- <skip />
- <!-- no translation found for satellite_sos_not_supported_notification_summary (1071762454665310549) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_title (8564738683795406715) -->
- <skip />
- <!-- no translation found for satellite_sos_not_provisioned_notification_summary (3127320958911180629) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_title (3164093193467075926) -->
- <skip />
- <!-- no translation found for satellite_sos_not_in_allowed_region_notification_summary (7686947667515679672) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_title (292528603128702080) -->
- <skip />
- <!-- no translation found for satellite_sos_unsupported_default_sms_app_notification_summary (3165168393504548437) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_title (5427987916850950591) -->
- <skip />
- <!-- no translation found for satellite_sos_location_disabled_notification_summary (1544937460641058567) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_title (3366657987618784706) -->
- <skip />
- <!-- no translation found for satellite_messaging_available_notification_summary (7573949038500243670) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_title (8202139632766878610) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_supported_notification_summary (61629858627638545) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_title (961909101918169727) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_provisioned_notification_summary (1060961852174442155) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_title (2035303593479031655) -->
- <skip />
- <!-- no translation found for satellite_messaging_not_in_allowed_region_notification_summary (5270294879531815854) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_title (1004808759472360189) -->
- <skip />
- <!-- no translation found for satellite_messaging_unsupported_default_sms_app_notification_summary (17084124893763593) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_title (7270641894250928494) -->
- <skip />
- <!-- no translation found for satellite_messaging_location_disabled_notification_summary (1450824950686221810) -->
- <skip />
+ <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Isethelayithi yokuxhumana ngezimo eziphuthumayo isiyatholakala manje"</string>
+ <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Ungathumela imiyalezo kumasevisi ezimo eziphuthumayo uma ingekho inethiwekhi yeselula noma ye-Wi-Fi. IGoogle Messages kumelwe kube iyona app yakho yemiyalezo ezenzekelayo."</string>
+ <string name="satellite_sos_not_supported_notification_title" msgid="2659100983227637285">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisekelwe"</string>
+ <string name="satellite_sos_not_supported_notification_summary" msgid="1071762454665310549">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisekelwe kule divayisi"</string>
+ <string name="satellite_sos_not_provisioned_notification_title" msgid="8564738683795406715">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisethiwe"</string>
+ <string name="satellite_sos_not_provisioned_notification_summary" msgid="3127320958911180629">"Qiniseka ukuthi uxhumeke ku-inthanethi bese uzama ukusetha futhi"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_title" msgid="3164093193467075926">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayitholakali"</string>
+ <string name="satellite_sos_not_in_allowed_region_notification_summary" msgid="7686947667515679672">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayitholakali kuleli zwe noma kulesi sifunda"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_title" msgid="292528603128702080">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayisethiwe"</string>
+ <string name="satellite_sos_unsupported_default_sms_app_notification_summary" msgid="3165168393504548437">"Ukuze uthumele umlayezo ngesathelayithi, setha iGoogle Messages ngenge-app yakho yemilayezo ezenzakalelayo"</string>
+ <string name="satellite_sos_location_disabled_notification_title" msgid="5427987916850950591">"Isethelayithi yokuxhumana ngezimo eziphuthumayo ayitholakali"</string>
+ <string name="satellite_sos_location_disabled_notification_summary" msgid="1544937460641058567">"Ukuze uhlole ukuthi isethelayithi yokuxhumana ngezimo eziphuthumayo iyatholakala yini kuleli zwe noma kulesi sifunda, vula amasethingi endawo"</string>
+ <string name="satellite_messaging_available_notification_title" msgid="3366657987618784706">"Ukuthumela umyalezo ngesethelayithi kuyatholakala"</string>
+ <string name="satellite_messaging_available_notification_summary" msgid="7573949038500243670">"Ungathumela umlayezo ngesathelayithi uma ingekho inethiwekhi yeselula noma ye-Wi-Fi. IGoogle Messages kumelwe kube iyona app yakho yemiyalezo ezenzekelayo."</string>
+ <string name="satellite_messaging_not_supported_notification_title" msgid="8202139632766878610">"Ukuthumela umyalezo ngesethelayithi akusekelwe"</string>
+ <string name="satellite_messaging_not_supported_notification_summary" msgid="61629858627638545">"Ukuthumela umyalezo ngesethelayithi akusekelwe kule divayisi"</string>
+ <string name="satellite_messaging_not_provisioned_notification_title" msgid="961909101918169727">"Ukuthumela umyalezo ngesethelayithi akusethiwe"</string>
+ <string name="satellite_messaging_not_provisioned_notification_summary" msgid="1060961852174442155">"Qiniseka ukuthi uxhumeke ku-inthanethi bese uzama ukusetha futhi"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_title" msgid="2035303593479031655">"Ukuthumela umyalezo ngesethelayithi akutholakali"</string>
+ <string name="satellite_messaging_not_in_allowed_region_notification_summary" msgid="5270294879531815854">"Ukuthumela umyalezo ngesethelayithi akutholakali kuleli zwe noma kulesi sifunda"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_title" msgid="1004808759472360189">"Ukuthumela umyalezo ngesethelayithi akusethiwe"</string>
+ <string name="satellite_messaging_unsupported_default_sms_app_notification_summary" msgid="17084124893763593">"Ukuze uthumele umlayezo ngesathelayithi, setha iGoogle Messages ngenge-app yakho yemilayezo ezenzakalelayo"</string>
+ <string name="satellite_messaging_location_disabled_notification_title" msgid="7270641894250928494">"Ukuthumela umyalezo ngesethelayithi akutholakali"</string>
+ <string name="satellite_messaging_location_disabled_notification_summary" msgid="1450824950686221810">"Ukuze uhlole ukuthi ukuthumela umyalezo ngesethelayithi kuyatholakala yini kuleli zwe noma kulesi sifunda, vula amasethingi endawo"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa."</string>
<string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa."</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3f4ea2df9266..7f2c816e5654 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -7184,6 +7184,10 @@
screen. -->
<bool name="config_dragToMaximizeInDesktopMode">false</bool>
+ <!-- Whether showing the app handle is supported on this device.
+ If config_isDesktopModeSupported, then this has no effect -->
+ <bool name="config_enableAppHandle">false</bool>
+
<!-- Frame rate compatibility value for Wallpaper
FRAME_RATE_COMPATIBILITY_MIN (102) is used by default for lower power consumption -->
<integer name="config_wallpaperFrameRateCompatibility">102</integer>
@@ -7225,12 +7229,18 @@
<!-- Package for opening identity check settings page [CHAR LIMIT=NONE] [DO NOT TRANSLATE] -->
<string name="identity_check_settings_package_name">com\u002eandroid\u002esettings</string>
- <!-- The name of the service for forensic event transport. -->
- <string name="config_forensicEventTransport" translatable="false"></string>
+ <!-- The name of the service for intrusion detection event transport. -->
+ <string name="config_intrusionDetectionEventTransport" translatable="false"></string>
<!-- Whether to enable fp unlock when screen turns off on udfps devices -->
<bool name="config_screen_off_udfps_enabled">false</bool>
<!-- The name of the system package that will hold the dependency installer role. -->
<string name="config_systemDependencyInstaller" translatable="false" />
+
+ <!-- Whether allow normal brightness when doze policy can be requested. When this is false,
+ brightness follows the display state i.e. ON means bright, DOZE means dim. If true,
+ POLICY_DOZE can also dim the screen unless parameter useNormalBrightnessForDoze of
+ DreamService#setDozeScreenState requests an exception. -->
+ <bool name="config_allowNormalBrightnessForDozePolicy">false</bool>
</resources>
diff --git a/core/res/res/values/config_display.xml b/core/res/res/values/config_display.xml
index 2e66060926fd..c458d0e9a3c0 100644
--- a/core/res/res/values/config_display.xml
+++ b/core/res/res/values/config_display.xml
@@ -29,5 +29,7 @@
<!-- Whether even dimmer feature is enabled. -->
<bool name="config_evenDimmerEnabled">false</bool>
+ <!-- Jar file path to look for PluginProvider -->
+ <string name="config_pluginsProviderJarPath"/>
</resources>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 4ec27a31df8c..e8063a27d77b 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -466,6 +466,11 @@
<integer name="config_satellite_location_query_throttle_interval_minutes">10</integer>
<java-symbol type="integer" name="config_satellite_location_query_throttle_interval_minutes" />
+ <!-- The file contains satellite access configuration like supported frequencies, bands,
+ satellite positions, and so on -->
+ <string name="satellite_access_config_file" translatable="false"></string>
+ <java-symbol type="string" name="satellite_access_config_file" />
+
<!-- Boolean indicating whether to enable MT SMS polling for NB IOT NTN. -->
<bool name="config_enabled_mt_sms_polling">true</bool>
<java-symbol type="bool" name="config_enabled_mt_sms_polling" />
@@ -484,7 +489,7 @@
<!-- Whether to show the system notification to users whenever there is a change
in the satellite availability state at the current location. -->
- <bool name="config_satellite_should_notify_availability">false</bool>
+ <bool name="config_satellite_should_notify_availability">true</bool>
<java-symbol type="bool" name="config_satellite_should_notify_availability" />
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 375748786817..c8df662eed6d 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -1055,12 +1055,12 @@
<dimen name="controls_thumbnail_image_max_width">280dp</dimen>
<!-- System-provided radius for the background view of app widgets. The resolved value of this resource may change at runtime. -->
- <dimen name="system_app_widget_background_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_radius">28dp</dimen>
- <dimen name="system_app_widget_background_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_radius">24dp</dimen>
+ <dimen name="system_app_widget_background_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_system_radius">28dp</dimen>
+ <dimen name="system_app_widget_background_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_system_radius">24dp</dimen>
<!-- System-provided radius for inner views on app widgets that are positioned 8dp within the widget background view. The resolved value of this resource may change at runtime. -->
- <dimen name="system_app_widget_inner_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_radius">20dp</dimen>
+ <dimen name="system_app_widget_inner_radius" android:featureFlag="!android.appwidget.flags.use_smaller_app_widget_system_radius">20dp</dimen>
<!-- System-provided radius for inner views on app widgets that are positioned 8dp within the widget background view. The resolved value of this resource may change at runtime. -->
- <dimen name="system_app_widget_inner_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_radius">16dp</dimen>
+ <dimen name="system_app_widget_inner_radius" android:featureFlag="android.appwidget.flags.use_smaller_app_widget_system_radius">16dp</dimen>
<!-- System-provided padding for inner views on app widgets. The resolved value of this resource may change at runtime. @removed -->
<dimen name="__removed_system_app_widget_internal_padding">16dp</dimen>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 3b2f24409a88..acc1ff8fb9db 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -43,6 +43,7 @@ easier.
<item name="textAppearance">?attr/textAppearanceButton</item>
<item name="textColor">@color/btn_colored_text_material</item>
</style>
+ <style name="Widget.DeviceDefault.Button.WearMaterial3"/>
<style name="Widget.DeviceDefault.TextView" parent="Widget.Material.TextView" />
<style name="Widget.DeviceDefault.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
<style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a2a19a23d431..b49e142e4cee 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2390,6 +2390,7 @@
<java-symbol type="layout" name="notification_material_action_list" />
<java-symbol type="layout" name="notification_material_action_tombstone" />
<java-symbol type="layout" name="notification_2025_template_collapsed_base" />
+ <java-symbol type="layout" name="notification_2025_template_heads_up_base" />
<java-symbol type="layout" name="notification_2025_template_header" />
<java-symbol type="layout" name="notification_template_material_base" />
<java-symbol type="layout" name="notification_template_material_heads_up_base" />
@@ -5317,6 +5318,91 @@
<java-symbol type="integer" name="config_accumulatedBatteryUsageStatsSpanSize" />
<!--Dynamic Tokens-->
+ <java-symbol name="materialColorBackground" type="color"/>
+ <java-symbol name="materialColorControlActivated" type="color"/>
+ <java-symbol name="materialColorControlHighlight" type="color"/>
+ <java-symbol name="materialColorControlNormal" type="color"/>
+ <java-symbol name="materialColorError" type="color"/>
+ <java-symbol name="materialColorErrorContainer" type="color"/>
+ <java-symbol name="materialColorInverseOnSurface" type="color"/>
+ <java-symbol name="materialColorInversePrimary" type="color"/>
+ <java-symbol name="materialColorInverseSurface" type="color"/>
+ <java-symbol name="materialColorOnBackground" type="color"/>
+ <java-symbol name="materialColorOnError" type="color"/>
+ <java-symbol name="materialColorOnErrorContainer" type="color"/>
+ <java-symbol name="materialColorOnPrimary" type="color"/>
+ <java-symbol name="materialColorOnPrimaryContainer" type="color"/>
+ <java-symbol name="materialColorOnSecondary" type="color"/>
+ <java-symbol name="materialColorOnSecondaryContainer" type="color"/>
+ <java-symbol name="materialColorOnSurface" type="color"/>
+ <java-symbol name="materialColorOnSurfaceVariant" type="color"/>
+ <java-symbol name="materialColorOnTertiary" type="color"/>
+ <java-symbol name="materialColorOnTertiaryContainer" type="color"/>
+ <java-symbol name="materialColorOutline" type="color"/>
+ <java-symbol name="materialColorOutlineVariant" type="color"/>
+ <java-symbol name="materialColorPaletteKeyColorNeutral" type="color"/>
+ <java-symbol name="materialColorPaletteKeyColorNeutralVariant" type="color"/>
+ <java-symbol name="materialColorPaletteKeyColorPrimary" type="color"/>
+ <java-symbol name="materialColorPaletteKeyColorSecondary" type="color"/>
+ <java-symbol name="materialColorPaletteKeyColorTertiary" type="color"/>
+ <java-symbol name="materialColorPrimary" type="color"/>
+ <java-symbol name="materialColorPrimaryContainer" type="color"/>
+ <java-symbol name="materialColorScrim" type="color"/>
+ <java-symbol name="materialColorSecondary" type="color"/>
+ <java-symbol name="materialColorSecondaryContainer" type="color"/>
+ <java-symbol name="materialColorShadow" type="color"/>
+ <java-symbol name="materialColorSurface" type="color"/>
+ <java-symbol name="materialColorSurfaceBright" type="color"/>
+ <java-symbol name="materialColorSurfaceContainer" type="color"/>
+ <java-symbol name="materialColorSurfaceContainerHigh" type="color"/>
+ <java-symbol name="materialColorSurfaceContainerHighest" type="color"/>
+ <java-symbol name="materialColorSurfaceContainerLow" type="color"/>
+ <java-symbol name="materialColorSurfaceContainerLowest" type="color"/>
+ <java-symbol name="materialColorSurfaceDim" type="color"/>
+ <java-symbol name="materialColorSurfaceTint" type="color"/>
+ <java-symbol name="materialColorSurfaceVariant" type="color"/>
+ <java-symbol name="materialColorTertiary" type="color"/>
+ <java-symbol name="materialColorTertiaryContainer" type="color"/>
+ <java-symbol name="materialColorTextHintInverse" type="color"/>
+ <java-symbol name="materialColorTextPrimaryInverse" type="color"/>
+ <java-symbol name="materialColorTextPrimaryInverseDisableOnly" type="color"/>
+ <java-symbol name="materialColorTextSecondaryAndTertiaryInverse" type="color"/>
+ <java-symbol name="materialColorTextSecondaryAndTertiaryInverseDisabled" type="color"/>
+ <java-symbol name="materialColorOnPrimaryFixed" type="color"/>
+ <java-symbol name="materialColorOnPrimaryFixedVariant" type="color"/>
+ <java-symbol name="materialColorOnSecondaryFixed" type="color"/>
+ <java-symbol name="materialColorOnSecondaryFixedVariant" type="color"/>
+ <java-symbol name="materialColorOnTertiaryFixed" type="color"/>
+ <java-symbol name="materialColorOnTertiaryFixedVariant" type="color"/>
+ <java-symbol name="materialColorPrimaryFixed" type="color"/>
+ <java-symbol name="materialColorPrimaryFixedDim" type="color"/>
+ <java-symbol name="materialColorSecondaryFixed" type="color"/>
+ <java-symbol name="materialColorSecondaryFixedDim" type="color"/>
+ <java-symbol name="materialColorTertiaryFixed" type="color"/>
+ <java-symbol name="materialColorTertiaryFixedDim" type="color"/>
+ <java-symbol name="customColorBrandA" type="color"/>
+ <java-symbol name="customColorBrandB" type="color"/>
+ <java-symbol name="customColorBrandC" type="color"/>
+ <java-symbol name="customColorBrandD" type="color"/>
+ <java-symbol name="customColorClockHour" type="color"/>
+ <java-symbol name="customColorClockMinute" type="color"/>
+ <java-symbol name="customColorClockSecond" type="color"/>
+ <java-symbol name="customColorOnShadeActive" type="color"/>
+ <java-symbol name="customColorOnShadeActiveVariant" type="color"/>
+ <java-symbol name="customColorOnShadeInactive" type="color"/>
+ <java-symbol name="customColorOnShadeInactiveVariant" type="color"/>
+ <java-symbol name="customColorOnThemeApp" type="color"/>
+ <java-symbol name="customColorOverviewBackground" type="color"/>
+ <java-symbol name="customColorShadeActive" type="color"/>
+ <java-symbol name="customColorShadeDisabled" type="color"/>
+ <java-symbol name="customColorShadeInactive" type="color"/>
+ <java-symbol name="customColorThemeApp" type="color"/>
+ <java-symbol name="customColorThemeAppRing" type="color"/>
+ <java-symbol name="customColorThemeNotif" type="color"/>
+ <java-symbol name="customColorUnderSurface" type="color"/>
+ <java-symbol name="customColorWeatherTemp" type="color"/>
+ <java-symbol name="customColorWidgetBackground" type="color"/>
+
<java-symbol type="attr" name="materialColorBackground"/>
<java-symbol type="attr" name="materialColorControlActivated"/>
<java-symbol type="attr" name="materialColorControlHighlight"/>
@@ -5606,6 +5692,7 @@
<!-- DisplayManager configs. -->
<java-symbol type="bool" name="config_evenDimmerEnabled" />
+ <java-symbol type="string" name="config_pluginsProviderJarPath" />
<java-symbol type="bool" name="config_watchlistUseFileHashesCache" />
<java-symbol type="string" name="config_defaultContextualSearchPackageName" />
@@ -5634,6 +5721,9 @@
screen. -->
<java-symbol type="bool" name="config_dragToMaximizeInDesktopMode" />
+ <!-- Whether showing the app handle is supported on this device -->
+ <java-symbol type="bool" name="config_enableAppHandle" />
+
<!-- Frame rate compatibility value for Wallpaper -->
<java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" />
@@ -5702,9 +5792,14 @@
<java-symbol type="string" name="identity_check_settings_action" />
<java-symbol type="string" name="identity_check_settings_package_name" />
- <!-- Forensic event transport -->
- <java-symbol type="string" name="config_forensicEventTransport" />
+ <!-- Intrusion detection event transport -->
+ <java-symbol type="string" name="config_intrusionDetectionEventTransport" />
<!-- Fingerprint screen off unlock config -->
<java-symbol type="bool" name="config_screen_off_udfps_enabled" />
+
+ <!-- Style for Wear Material3 Button. Will only be used for sdk 36 or above. -->
+ <java-symbol type="style" name="Widget.DeviceDefault.Button.WearMaterial3" />
+
+ <java-symbol type="bool" name="config_allowNormalBrightnessForDozePolicy" />
</resources>
diff --git a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
index fe54aa8d87f0..945147db1ef5 100644
--- a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
+++ b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java
@@ -18,6 +18,8 @@ package com.android.frameworks.coretests.bfscctestapp;
import android.app.Service;
import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.RemoteException;
@@ -36,6 +38,7 @@ public class BfsccTestAppCmdService extends Service {
@Override
public void listenTo(IBinder binder) throws RemoteException {
binder.addFrozenStateChangeCallback(
+ new HandlerExecutor(Handler.getMain()),
(IBinder who, int state) -> mNotifications.offer(state));
}
diff --git a/core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java b/core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java
deleted file mode 100644
index f1e1df5ae3fb..000000000000
--- a/core/tests/coretests/src/android/content/pm/verify/VerificationSessionTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify;
-
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.content.pm.VersionedPackage;
-import android.content.pm.verify.pkg.IVerificationSessionInterface;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-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.Collections;
-import java.util.List;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerificationSessionTest {
- private static final int TEST_ID = 100;
- private static final int TEST_INSTALL_SESSION_ID = 33;
- private static final String TEST_PACKAGE_NAME = "com.foo";
- private static final Uri TEST_PACKAGE_URI = Uri.parse("test://test");
- private static final SigningInfo TEST_SIGNING_INFO = new SigningInfo();
- private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO1 =
- new SharedLibraryInfo("sharedLibPath1", TEST_PACKAGE_NAME,
- Collections.singletonList("path1"), "sharedLib1", 101,
- SharedLibraryInfo.TYPE_DYNAMIC, new VersionedPackage(TEST_PACKAGE_NAME, 1),
- null, null, false);
- private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO2 =
- new SharedLibraryInfo("sharedLibPath2", TEST_PACKAGE_NAME,
- Collections.singletonList("path2"), "sharedLib2", 102,
- SharedLibraryInfo.TYPE_DYNAMIC,
- new VersionedPackage(TEST_PACKAGE_NAME, 2), null, null, false);
- private static final long TEST_TIMEOUT_TIME = System.currentTimeMillis();
- private static final long TEST_EXTEND_TIME = 2000L;
- private static final String TEST_KEY = "test key";
- private static final String TEST_VALUE = "test value";
- private static final int TEST_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-
- private final ArrayList<SharedLibraryInfo> mTestDeclaredLibraries = new ArrayList<>();
- private final PersistableBundle mTestExtensionParams = new PersistableBundle();
- @Mock
- private IVerificationSessionInterface mTestSessionInterface;
- private VerificationSession mTestSession;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO1);
- mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO2);
- mTestExtensionParams.putString(TEST_KEY, TEST_VALUE);
- mTestSession = new VerificationSession(TEST_ID, TEST_INSTALL_SESSION_ID,
- TEST_PACKAGE_NAME, TEST_PACKAGE_URI, TEST_SIGNING_INFO, mTestDeclaredLibraries,
- mTestExtensionParams, TEST_POLICY, mTestSessionInterface);
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- mTestSession.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- VerificationSession sessionFromParcel =
- VerificationSession.CREATOR.createFromParcel(parcel);
- assertThat(sessionFromParcel.getId()).isEqualTo(TEST_ID);
- assertThat(sessionFromParcel.getInstallSessionId()).isEqualTo(TEST_INSTALL_SESSION_ID);
- assertThat(sessionFromParcel.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(sessionFromParcel.getStagedPackageUri()).isEqualTo(TEST_PACKAGE_URI);
- assertThat(sessionFromParcel.getSigningInfo().getSigningDetails())
- .isEqualTo(TEST_SIGNING_INFO.getSigningDetails());
- List<SharedLibraryInfo> declaredLibrariesFromParcel =
- sessionFromParcel.getDeclaredLibraries();
- assertThat(declaredLibrariesFromParcel).hasSize(2);
- // SharedLibraryInfo doesn't have a "equals" method, so we have to check it indirectly
- assertThat(declaredLibrariesFromParcel.getFirst().toString())
- .isEqualTo(TEST_SHARED_LIBRARY_INFO1.toString());
- assertThat(declaredLibrariesFromParcel.get(1).toString())
- .isEqualTo(TEST_SHARED_LIBRARY_INFO2.toString());
- // We can't directly test with PersistableBundle.equals() because the parceled bundle's
- // structure is different, but all the key/value pairs should be preserved as before.
- assertThat(sessionFromParcel.getExtensionParams().getString(TEST_KEY))
- .isEqualTo(mTestExtensionParams.getString(TEST_KEY));
- assertThat(sessionFromParcel.getVerificationPolicy()).isEqualTo(TEST_POLICY);
- }
-
- @Test
- public void testInterface() throws Exception {
- when(mTestSessionInterface.getTimeoutTime(anyInt())).thenAnswer(i -> TEST_TIMEOUT_TIME);
- when(mTestSessionInterface.extendTimeRemaining(anyInt(), anyLong())).thenAnswer(
- i -> i.getArguments()[1]);
-
- assertThat(mTestSession.getTimeoutTime()).isEqualTo(TEST_TIMEOUT_TIME);
- verify(mTestSessionInterface, times(1)).getTimeoutTime(eq(TEST_ID));
- assertThat(mTestSession.extendTimeRemaining(TEST_EXTEND_TIME)).isEqualTo(TEST_EXTEND_TIME);
- verify(mTestSessionInterface, times(1)).extendTimeRemaining(
- eq(TEST_ID), eq(TEST_EXTEND_TIME));
-
- PersistableBundle response = new PersistableBundle();
- response.putString("test key", "test value");
- final VerificationStatus status =
- new VerificationStatus.Builder().setVerified(true).build();
- mTestSession.reportVerificationComplete(status);
- verify(mTestSessionInterface, times(1)).reportVerificationComplete(
- eq(TEST_ID), eq(status), eq(null));
- mTestSession.reportVerificationComplete(status, response);
- verify(mTestSessionInterface, times(1))
- .reportVerificationComplete(
- eq(TEST_ID), eq(status), eq(response));
-
- final int reason = VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN;
- mTestSession.reportVerificationIncomplete(reason);
- verify(mTestSessionInterface, times(1)).reportVerificationIncomplete(
- eq(TEST_ID), eq(reason));
- }
-
- @Test
- public void testPolicyNoOverride() {
- assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
- // This "set" is a no-op
- assertThat(mTestSession.setVerificationPolicy(TEST_POLICY)).isTrue();
- assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
- verifyZeroInteractions(mTestSessionInterface);
- }
-
- @Test
- public void testPolicyOverrideFail() throws Exception {
- final int newPolicy = VERIFICATION_POLICY_BLOCK_FAIL_WARN;
- when(mTestSessionInterface.setVerificationPolicy(anyInt(), anyInt())).thenReturn(false);
- assertThat(mTestSession.setVerificationPolicy(newPolicy)).isFalse();
- verify(mTestSessionInterface, times(1))
- .setVerificationPolicy(eq(TEST_ID), eq(newPolicy));
- // Next "get" should not trigger binder call because the previous "set" has failed
- assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
- verifyNoMoreInteractions(mTestSessionInterface);
- }
-
- @Test
- public void testPolicyOverrideSuccess() throws Exception {
- final int newPolicy = VERIFICATION_POLICY_BLOCK_FAIL_WARN;
- when(mTestSessionInterface.setVerificationPolicy(anyInt(), anyInt())).thenReturn(true);
- assertThat(mTestSession.setVerificationPolicy(newPolicy)).isTrue();
- verify(mTestSessionInterface, times(1))
- .setVerificationPolicy(eq(TEST_ID), eq(newPolicy));
- assertThat(mTestSession.getVerificationPolicy()).isEqualTo(newPolicy);
- assertThat(mTestSession.getVerificationPolicy()).isEqualTo(newPolicy);
-
- // Setting back to the original policy should still trigger binder calls
- assertThat(mTestSession.setVerificationPolicy(TEST_POLICY)).isTrue();
- verify(mTestSessionInterface, times(1))
- .setVerificationPolicy(eq(TEST_ID), eq(TEST_POLICY));
- assertThat(mTestSession.getVerificationPolicy()).isEqualTo(TEST_POLICY);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java b/core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java
deleted file mode 100644
index 67d407a72925..000000000000
--- a/core/tests/coretests/src/android/content/pm/verify/VerificationStatusTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerificationStatusTest {
- private static final boolean TEST_VERIFIED = true;
- private static final int TEST_ASL_STATUS = VerificationStatus.VERIFIER_STATUS_ASL_GOOD;
- private static final String TEST_FAILURE_MESSAGE = "test test";
- private static final String TEST_KEY = "test key";
- private static final String TEST_VALUE = "test value";
- private final PersistableBundle mTestExtras = new PersistableBundle();
- private VerificationStatus mStatus;
-
- @Before
- public void setUpWithBuilder() {
- mTestExtras.putString(TEST_KEY, TEST_VALUE);
- mStatus = new VerificationStatus.Builder()
- .setAslStatus(TEST_ASL_STATUS)
- .setFailureMessage(TEST_FAILURE_MESSAGE)
- .setVerified(TEST_VERIFIED)
- .build();
- }
-
- @Test
- public void testGetters() {
- assertThat(mStatus.isVerified()).isEqualTo(TEST_VERIFIED);
- assertThat(mStatus.getAslStatus()).isEqualTo(TEST_ASL_STATUS);
- assertThat(mStatus.getFailureMessage()).isEqualTo(TEST_FAILURE_MESSAGE);
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- mStatus.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- VerificationStatus statusFromParcel = VerificationStatus.CREATOR.createFromParcel(parcel);
- assertThat(statusFromParcel.isVerified()).isEqualTo(TEST_VERIFIED);
- assertThat(statusFromParcel.getAslStatus()).isEqualTo(TEST_ASL_STATUS);
- assertThat(statusFromParcel.getFailureMessage()).isEqualTo(TEST_FAILURE_MESSAGE);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java b/core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java
deleted file mode 100644
index 56fc66a286c3..000000000000
--- a/core/tests/coretests/src/android/content/pm/verify/VerifierServiceTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm.verify;
-
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.SigningInfo;
-import android.content.pm.verify.pkg.IVerificationSessionInterface;
-import android.content.pm.verify.pkg.IVerifierService;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerifierService;
-import android.net.Uri;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerifierServiceTest {
- private static final int TEST_ID = 100;
- private static final int TEST_INSTALL_SESSION_ID = 33;
- private static final String TEST_PACKAGE_NAME = "com.foo";
- private static final Uri TEST_PACKAGE_URI = Uri.parse("test://test");
- private static final SigningInfo TEST_SIGNING_INFO = new SigningInfo();
- private static final int TEST_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
- private VerifierService mService;
- private VerificationSession mSession;
-
- @Before
- public void setUp() {
- mService = Mockito.mock(VerifierService.class, Answers.CALLS_REAL_METHODS);
- mSession = new VerificationSession(TEST_ID, TEST_INSTALL_SESSION_ID,
- TEST_PACKAGE_NAME, TEST_PACKAGE_URI, TEST_SIGNING_INFO,
- new ArrayList<>(), new PersistableBundle(), TEST_POLICY, Mockito.mock(
- IVerificationSessionInterface.class));
- }
-
- @Test
- public void testBind() throws Exception {
- Intent intent = Mockito.mock(Intent.class);
- when(intent.getAction()).thenReturn(PackageManager.ACTION_VERIFY_PACKAGE);
- IVerifierService binder =
- (IVerifierService) mService.onBind(intent);
- assertThat(binder).isNotNull();
- binder.onPackageNameAvailable(TEST_PACKAGE_NAME);
- verify(mService).onPackageNameAvailable(eq(TEST_PACKAGE_NAME));
- binder.onVerificationCancelled(TEST_PACKAGE_NAME);
- verify(mService).onVerificationCancelled(eq(TEST_PACKAGE_NAME));
- binder.onVerificationRequired(mSession);
- verify(mService).onVerificationRequired(eq(mSession));
- binder.onVerificationRetry(mSession);
- verify(mService).onVerificationRetry(eq(mSession));
- binder.onVerificationTimeout(TEST_ID);
- verify(mService).onVerificationTimeout(eq(TEST_ID));
- }
-
- @Test
- public void testBindFailsWithWrongIntent() {
- Intent intent = Mockito.mock(Intent.class);
- when(intent.getAction()).thenReturn(Intent.ACTION_SEND);
- assertThat(mService.onBind(intent)).isNull();
- }
-}
diff --git a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
index 195a18a5f521..523fe1a8aa5d 100644
--- a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
+++ b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
@@ -200,7 +200,7 @@ public class BinderFrozenStateChangeNotificationTest {
IBinder.FrozenStateChangeCallback callback =
(IBinder who, int state) -> results.offer(who);
try {
- binder.addFrozenStateChangeCallback(callback);
+ binder.addFrozenStateChangeCallback(new HandlerExecutor(Handler.getMain()), callback);
} catch (UnsupportedOperationException e) {
return;
}
@@ -227,7 +227,7 @@ public class BinderFrozenStateChangeNotificationTest {
final IBinder.FrozenStateChangeCallback callback =
(IBinder who, int state) ->
queue.offer(state == IBinder.FrozenStateChangeCallback.STATE_FROZEN);
- binder.addFrozenStateChangeCallback(callback);
+ binder.addFrozenStateChangeCallback(new HandlerExecutor(Handler.getMain()), callback);
return callback;
} catch (UnsupportedOperationException e) {
return null;
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
index 67de25eede42..75118873dd75 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
@@ -42,6 +42,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.FileDescriptor;
+import java.util.concurrent.Executor;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -125,7 +126,7 @@ public class BinderDeathDispatcherTest {
}
@Override
- public void addFrozenStateChangeCallback(FrozenStateChangeCallback callback)
+ public void addFrozenStateChangeCallback(Executor e, FrozenStateChangeCallback callback)
throws RemoteException {
}
diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
index 40d0bef2fb0f..28d6545c8a5b 100644
--- a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
+++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
@@ -210,21 +210,6 @@ public class OverlayManagerImplTest {
}
@Test
- public void registerOverlay_forAndroidPackage_shouldFail() {
- FabricatedOverlayInternal overlayInternal =
- createOverlayWithName(
- mOverlayName,
- SYSTEM_APP_OVERLAYABLE,
- "android",
- List.of(Pair.create("color/white", Pair.create(null, Color.BLACK))));
-
- assertThrows(
- "Wrong target package name",
- IllegalArgumentException.class,
- () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
- }
-
- @Test
public void getOverlayInfosForTarget_defaultShouldBeZero() {
List<OverlayInfo> overlayInfos =
mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName());
diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 75aca1b8820c..7ce2ed823540 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -23,10 +23,11 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.platform.test.ravenwood.RavenwoodConfig;
+import android.platform.test.ravenwood.RavenwoodRule;
import androidx.test.filters.SmallTest;
+import org.junit.Rule;
import org.junit.Test;
import java.util.Objects;
@@ -39,8 +40,8 @@ public class SystemPropertiesTest {
private static final String PERSIST_KEY = "persist.sys.testkey";
private static final String NONEXIST_KEY = "doesnotexist_2341431";
- @RavenwoodConfig.Config
- public static final RavenwoodConfig mRavenwood = new RavenwoodConfig.Builder()
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
.setSystemPropertyMutable(KEY, null)
.setSystemPropertyMutable(UNSET_KEY, null)
.setSystemPropertyMutable(PERSIST_KEY, null)
diff --git a/core/tests/vibrator/src/android/os/VibrationEffectTest.java b/core/tests/vibrator/src/android/os/VibrationEffectTest.java
index ccc5108abc19..5f3754b9933a 100644
--- a/core/tests/vibrator/src/android/os/VibrationEffectTest.java
+++ b/core/tests/vibrator/src/android/os/VibrationEffectTest.java
@@ -418,20 +418,45 @@ public class VibrationEffectTest {
// Effects created via waveformEnvelopeBuilder are not expected to be converted to long[]
// patterns, as they are not configured to always play with the default amplitude.
VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+ .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
.build();
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
effect = new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 60)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+ .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
+ .build();
+
+ assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public void computeLegacyPattern_effectsViaBasicEnvelopeBuilder() {
+ // Effects created via BasicEnvelopeBuilder are not expected to be converted to long[]
+ // patterns, as they are not configured to always play with the default amplitude.
+ VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
+ .build();
+
+ assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
+
+ effect = new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.1f)
+ .addControlPoint(/*intensity=*/ 0.2f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
.build();
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
@@ -646,43 +671,43 @@ public class VibrationEffectTest {
@EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public void testValidateWaveformEnvelopeBuilder() {
new VibrationEffect.WaveformEnvelopeBuilder()
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+ .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
.build()
.validate();
new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 50)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 80)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 40)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 50)
+ .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 80)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 40)
.build()
.validate();
VibrationEffect.createRepeatingEffect(
/*preamble=*/ new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f,
- /*timeMillis=*/ 50)
+ /*durationMillis=*/ 50)
.build(),
/*repeatingEffect=*/ new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.addControlPoint(/*amplitude=*/ 0.5f, /*frequencyHz=*/ 150f,
- /*timeMillis=*/ 100)
+ /*durationMillis=*/ 100)
.build()
).validate();
VibrationEffect.createRepeatingEffect(
/*effect=*/ new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.addControlPoint(/*amplitude=*/ 0.5f, /*frequencyHz=*/ 150f,
- /*timeMillis=*/ 100)
+ /*durationMillis=*/ 100)
.build()
).validate();
@@ -691,25 +716,25 @@ public class VibrationEffectTest {
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ -1.0f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ 1.1f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 0f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f,
- /*timeMillis=*/ 0)
+ /*durationMillis=*/ 0)
.build()
.validate());
@@ -721,39 +746,156 @@ public class VibrationEffectTest {
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
.addControlPoint(/*amplitude=*/ -1.0f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
.addControlPoint(/*amplitude=*/ 1.1f, /*frequencyHz=*/ 60f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
.addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 0f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
.addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f,
- /*timeMillis=*/ 0)
+ /*durationMillis=*/ 0)
.build()
.validate());
assertThrows(IllegalArgumentException.class,
() -> new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 0)
.addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f,
- /*timeMillis=*/ 20)
+ /*durationMillis=*/ 20)
.build().validate());
}
@Test
+ @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public void testValidateBasicEnvelopeBuilder() {
+ new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
+ .build()
+ .validate();
+
+ new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.1f)
+ .addControlPoint(/*intensity=*/ 0.2f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 20)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 50)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 80)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 40)
+ .build()
+ .validate();
+
+ VibrationEffect.createRepeatingEffect(
+ /*preamble=*/ new VibrationEffect.BasicEnvelopeBuilder()
+ // intensity, sharpness, durationMillis
+ .addControlPoint(0.3f, 0.5f, 60)
+ .addControlPoint(0.0f, 0.5f, 100)
+ .build(),
+ /*repeatingEffect=*/ new VibrationEffect.BasicEnvelopeBuilder()
+ // intensity, sharpness, durationMillis
+ .addControlPoint(0.5f, 0.8f, 60)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ ).validate();
+
+ VibrationEffect.createRepeatingEffect(
+ new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ // intensity, sharpness, durationMillis
+ .addControlPoint(0.5f, 0.8f, 60)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ ).validate();
+
+ assertThrows(IllegalStateException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder().build().validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(-1.0f, 0.5f, 20)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(1.1f, 0.5f, 20)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(0.8f, -0.1f, 20)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(0.8f, 0.5f, 0)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ // Waveform effects created using the basic builder must end with a zero intensity
+ // control point.
+ assertThrows(IllegalStateException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(0.8f, 0.5f, 100)
+ .build()
+ .validate());
+
+ assertThrows(IllegalStateException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/0.2f).build().validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(-1.0f, 0.5f, 20)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(1.1f, 0.5f, 20)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(0.8f, -0.1f, 20)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ assertThrows(IllegalArgumentException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(0.8f, 0.5f, 0)
+ .addControlPoint(0.0f, 0.3f, 100)
+ .build()
+ .validate());
+ // Waveform effects created using the basic builder must end with a zero intensity
+ // control point.
+ assertThrows(IllegalStateException.class,
+ () -> new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(0.8f, 0.5f, 100)
+ .build()
+ .validate());
+ }
+
+ @Test
public void testValidateWaveformBuilder() {
// Cover builder methods
VibrationEffect.startWaveform(targetAmplitude(1))
@@ -1395,18 +1537,36 @@ public class VibrationEffectTest {
@EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public void testIsHapticFeedbackCandidate_longEnvelopeEffects_notCandidates() {
assertFalse(new VibrationEffect.WaveformEnvelopeBuilder()
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 200)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 800)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
+ //amplitude, frequencyHz, durationMillis
+ .addControlPoint(0.0f, 60f, 200)
+ .addControlPoint(0.3f, 100f, 500)
+ .addControlPoint(0.4f, 120f, 800)
+ .addControlPoint(0.0f, 120f, 400)
.build()
.isHapticFeedbackCandidate());
assertFalse(new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 40)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 200)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 800)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
+ //amplitude, frequencyHz, durationMillis
+ .addControlPoint(0.0f, 60f, 200)
+ .addControlPoint(0.3f, 100f, 500)
+ .addControlPoint(0.4f, 120f, 800)
+ .addControlPoint(0.0f, 120f, 400)
+ .build()
+ .isHapticFeedbackCandidate());
+
+ assertFalse(new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 200)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 800)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 400)
+ .build()
+ .isHapticFeedbackCandidate());
+ assertFalse(new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(/*intensity=*/ 0.1f, /*sharpness=*/ 0.2f, /*durationMillis=*/ 200)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 800)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 400)
.build()
.isHapticFeedbackCandidate());
}
@@ -1428,16 +1588,31 @@ public class VibrationEffectTest {
@EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public void testIsHapticFeedbackCandidate_shortEnvelopeEffects_areCandidates() {
assertTrue(new VibrationEffect.WaveformEnvelopeBuilder()
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 100)
+ //amplitude, frequencyHz, durationMillis
+ .addControlPoint(0.3f, 100f, 500)
+ .addControlPoint(0.4f, 120f, 400)
+ .addControlPoint(0.0f, 120f, 100)
.build()
.isHapticFeedbackCandidate());
assertTrue(new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 500)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 400)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 100)
+ .addControlPoint(0.3f, 100f, 500)
+ .addControlPoint(0.4f, 120f, 400)
+ .addControlPoint(0.0f, 120f, 100)
+ .build()
+ .isHapticFeedbackCandidate());
+
+ assertTrue(new VibrationEffect.BasicEnvelopeBuilder()
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 400)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 100)
+ .build()
+ .isHapticFeedbackCandidate());
+ assertTrue(new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 0.2f)
+ .addControlPoint(/*intensity=*/ 0.3f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 500)
+ .addControlPoint(/*intensity=*/ 0.4f, /*sharpness=*/ 0.5f, /*durationMillis=*/ 400)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 0.3f, /*durationMillis=*/ 100)
.build()
.isHapticFeedbackCandidate());
}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index fea7cb4b422c..af690f4449af 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -533,6 +533,8 @@ applications that come with the platform
<permission name="com.android.cellbroadcastservice.FULL_ACCESS_CELL_BROADCAST_HISTORY" />
<!-- Permission required for ATS test - CarDevicePolicyManagerTest -->
<permission name="android.permission.LOCK_DEVICE" />
+ <!-- Permission required for AuthenticationPolicyManagerTest -->
+ <permission name="android.permission.MANAGE_SECURE_LOCK_DEVICE" />
<!-- Permissions required for CTS test - CtsSafetyCenterTestCases -->
<permission name="android.permission.SEND_SAFETY_CENTER_UPDATE" />
<permission name="android.permission.READ_SAFETY_CENTER_STATUS" />
@@ -581,7 +583,6 @@ applications that come with the platform
<permission name="android.permission.READ_BLOCKED_NUMBERS" />
<!-- Permission required for CTS test - PackageManagerTest -->
<permission name="android.permission.DOMAIN_VERIFICATION_AGENT"/>
- <permission name="android.permission.VERIFICATION_AGENT"/>
<!-- Permission required for CTS test CtsInputTestCases -->
<permission name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" />
<!-- Permission required for CTS test - PackageManagerShellCommandInstallTest -->
@@ -598,14 +599,14 @@ applications that come with the platform
<!-- Permission required for CTS test - CtsAppTestCases -->
<permission name="android.permission.KILL_UID" />
<!-- Permission required for CTS test - AdvancedProtectionManagerTest -->
- <permission name="android.permission.SET_ADVANCED_PROTECTION_MODE" />
+ <permission name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE" />
<permission name="android.permission.QUERY_ADVANCED_PROTECTION_MODE" />
<!-- Permissions required for CTS test - SettingsPreferenceServiceClientTest -->
<permission name="android.permission.READ_SYSTEM_PREFERENCES" />
<permission name="android.permission.WRITE_SYSTEM_PREFERENCES" />
- <!-- Permission required for CTS test - ForensicManagerTest -->
- <permission name="android.permission.READ_FORENSIC_STATE" />
- <permission name="android.permission.MANAGE_FORENSIC_STATE" />
+ <!-- Permission required for CTS test - IntrusionDetectionManagerTest -->
+ <permission name="android.permission.READ_INTRUSION_DETECTION_STATE" />
+ <permission name="android.permission.MANAGE_INTRUSION_DETECTION_STATE" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 42188dec4236..a354bf78bb39 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -156,51 +156,6 @@ java_library {
},
}
-filegroup {
- name: "wm_shell-shared-utils",
- srcs: [
- "shared/src/com/android/wm/shell/shared/TransitionUtil.java",
- ],
-}
-
-filegroup {
- name: "wm_shell-shared-aidls",
-
- srcs: [
- "shared/**/*.aidl",
- ],
-
- path: "shared/src",
-}
-
-java_library {
- name: "WindowManager-Shell-shared",
-
- srcs: [
- "shared/**/*.java",
- "shared/**/*.kt",
- ":wm_shell-shared-aidls",
- ],
- static_libs: [
- "androidx.core_core-animation",
- "androidx.dynamicanimation_dynamicanimation",
- "jsr330",
- ],
- kotlincflags: ["-Xjvm-default=all"],
-}
-
-java_library {
- name: "WindowManager-Shell-shared-desktopMode",
-
- srcs: [
- "shared/**/desktopmode/*.java",
- "shared/**/desktopmode/*.kt",
- ],
- static_libs: [
- "com.android.window.flags.window-aconfig-java",
- ],
-}
-
android_library {
name: "WindowManager-Shell",
srcs: [
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
index 5e41865cd31e..375968ab0ad2 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
@@ -113,7 +113,7 @@
style="?android:attr/buttonBarButtonStyle"
android:layout_width="41dp"
android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
- android:layout_marginRight="4dp"
+ android:layout_marginEnd="4dp"
android:background="@drawable/desktop_mode_maximize_menu_button_background"
android:importantForAccessibility="yes"
android:contentDescription="@string/desktop_mode_maximize_menu_snap_left_button_text"
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index a4aa3480fb46..9a1a3da06a77 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Kies"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skermskoot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Maak in blaaier oop"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Maak in app oop"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nuwe venster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Bestuur vensters"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Verander aspekverhouding"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Maak kieslys oop"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gryp skerm vas"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Meesleurend"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Stel terug"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 1cd980460cee..9d22fef66636 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ምረጥ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገፅ ዕይታ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"በአሳሽ ውስጥ ክፈት"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"መተግበሪያ ውስጥ ክፈት"</string>
<string name="new_window_text" msgid="6318648868380652280">"አዲስ መስኮት"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"መስኮቶችን አስተዳድር"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ምጥጥነ ገፅታ ለውጥ"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ምናሌን ክፈት"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ማያ ገጹን አሳድግ"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"አስማጭ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ወደነበረበት መልስ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 41ebfcd0ee85..46ab090e310e 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"اختيار"</string>
<string name="screenshot_text" msgid="1477704010087786671">"لقطة شاشة"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"فتح في المتصفِّح"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"فتح في التطبيق"</string>
<string name="new_window_text" msgid="6318648868380652280">"نافذة جديدة"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"إدارة النوافذ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغيير نسبة العرض إلى الارتفاع"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"فتح القائمة"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"التقاط صورة للشاشة"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"مجسَّم"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"استعادة"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 203fed0aecef..1e35d6ed132f 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"বাছনি কৰক"</string>
<string name="screenshot_text" msgid="1477704010087786671">"স্ক্ৰীনশ্বট"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ব্ৰাউজাৰত খোলক"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"এপত খোলক"</string>
<string name="new_window_text" msgid="6318648868380652280">"নতুন ৱিণ্ড’"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ৱিণ্ড’ পৰিচালনা কৰক"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"আকাৰৰ অনুপাত সলনি কৰক"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খোলক"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্ৰীন স্নেপ কৰক"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্‌টো আনিব নোৱাৰি"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ইমাৰ্ছিভ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"পুনঃস্থাপন কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 31ddc9b78b68..136d4c18c3d5 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Seçin"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skrinşot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerdə açın"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Tətbiqdə açın"</string>
<string name="new_window_text" msgid="6318648868380652280">"Yeni pəncərə"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pəncərələri idarə edin"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tərəflər nisbətini dəyişin"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyunu açın"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranı çəkin"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Tətbiqi bura köçürmək mümkün deyil"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"İmmersiv"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Bərpa edin"</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 486b3cfbfee4..10a33bb6aca7 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Izaberite"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvorite u pregledaču"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Otvorite u aplikaciji"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljajte prozorima"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promenite razmeru"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvorite meni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Uklopi ekran"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imerzivne"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index cc42da947c36..163fbddbc967 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Выбраць"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Здымак экрана"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Адкрыць у браўзеры"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Адкрыць у праграме"</string>
<string name="new_window_text" msgid="6318648868380652280">"Новае акно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Кіраваць вокнамі"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змяніць суадносіны бакоў"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Адкрыць меню"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Размясціць на палавіне экрана"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"З эфектам прысутнасці"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Аднавіць"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index c12b37b34d5a..d7da3aef02bb 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Избиране"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Екранна снимка"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Отваряне в браузър"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Отваряне в приложение"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управление на прозорците"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промяна на съотношението"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отваряне на менюто"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Прилепване на екрана"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Възстановяване"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index aca5b34ae4c0..9c2fc6e98818 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"বেছে নিন"</string>
<string name="screenshot_text" msgid="1477704010087786671">"স্ক্রিনশট"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ব্রাউজারে খুলুন"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"অ্যাপে খুলুন"</string>
<string name="new_window_text" msgid="6318648868380652280">"নতুন উইন্ডো"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"উইন্ডো ম্যানেজ করুন"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"মেনু খুলুন"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্রিন বড় করুন"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্রিনে অ্যাপ মানানসই হিসেবে ছোট বড় করুন"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"অ্যাপটি এখানে সরানো যাবে না"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ইমারসিভ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ফিরিয়ে আনুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 6bd6473a5f13..911285d060f1 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Odabir"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvaranje u pregledniku"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Otvaranje u aplikaciji"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promjena formata slike"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje menija"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snimi ekran"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Uvjerljivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vraćanje"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index d9ad5a68d163..4249373e0a3d 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Selecciona"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Obre al navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Obre a l\'aplicació"</string>
<string name="new_window_text" msgid="6318648868380652280">"Finestra nova"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestiona les finestres"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Canvia la relació d\'aspecte"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Obre el menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajusta la pantalla"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiu"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaura"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index ab51b666cdda..a12534372135 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Vybrat"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snímek obrazovky"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Otevřít v prohlížeči"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Otevřít v aplikaci"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Spravovat okna"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Změnit poměr stran"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otevřít nabídku"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Rozpůlit obrazovku"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pohlcující"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovit"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 443620804e10..5b657f4c9bb6 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Vælg"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Åbn i browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Åbn i app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nyt vindue"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduer"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Skift billedformat"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åbn menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tilpas skærm"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Opslugende"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Gendan"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index b6e89c0eeb8e..6d360e8e0af2 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Auswählen"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Im Browser öffnen"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"In der App öffnen"</string>
<string name="new_window_text" msgid="6318648868380652280">"Neues Fenster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Fenster verwalten"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Seitenverhältnis ändern"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü öffnen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Bildschirm teilen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Wiederherstellen"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 601c0ceee27f..85a44f6d760d 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Επιλογή"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Στιγμιότυπο οθόνης"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Άνοιγμα σε πρόγραμμα περιήγησης"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Άνοιγμα στην εφαρμογή"</string>
<string name="new_window_text" msgid="6318648868380652280">"Νέο παράθυρο"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Διαχείριση παραθύρων"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Άνοιγμα μενού"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Προβολή στο μισό της οθόνης"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Καθηλωτικό"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Επαναφορά"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index fd6317530109..3e30ff048c6d 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Open in app"</string>
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index dac1b9a1460d..0d7189bd16b3 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Open in App"</string>
<string name="new_window_text" msgid="6318648868380652280">"New Window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage Windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap Screen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index fd6317530109..3e30ff048c6d 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Open in app"</string>
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index fd6317530109..3e30ff048c6d 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Select"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Open in browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Open in app"</string>
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Open menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index e67fc8e2c63c..6a1a2e5a4d39 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir en el navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Abrir en la app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nueva ventana"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrar ventanas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir el menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restablecer"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 2f5ec64be629..f93cf5a2fefd 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir en el navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Abrir en la aplicación"</string>
<string name="new_window_text" msgid="6318648868380652280">"Ventana nueva"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestionar ventanas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar pantalla"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"La aplicación no se puede mover aquí"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Inmersivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index dd78628093d4..f0d1d4e60392 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Vali"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekraanipilt"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Avamine brauseris"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Ava rakenduses"</string>
<string name="new_window_text" msgid="6318648868380652280">"Uus aken"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Akende haldamine"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Kuvasuhte muutmine"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ava menüü"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Kuva poolel ekraanil"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Kaasahaarav"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Taasta"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 1cfc69457ce9..c6a7f2eca877 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Hautatu"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Pantaila-argazkia"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Ireki arakatzailean"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Ireki aplikazioan"</string>
<string name="new_window_text" msgid="6318648868380652280">"Leiho berria"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Kudeatu leihoak"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Aldatu aspektu-erlazioa"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ireki menua"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Handitu pantaila"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zatitu pantaila"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikazioa ezin da hona ekarri"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Murgiltzailea"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Leheneratu"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index f76f67d2e796..d10a02d75c18 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"انتخاب"</string>
<string name="screenshot_text" msgid="1477704010087786671">"نماگرفت"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"باز کردن در مرورگر"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"باز کردن در برنامه"</string>
<string name="new_window_text" msgid="6318648868380652280">"پنجره جدید"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"مدیریت کردن پنجره‌ها"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغییر نسبت ابعادی"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"باز کردن منو"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"بزرگ کردن صفحه"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمی‌توان به اینجا منتقل کرد"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"فراگیر"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بازیابی"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index a1ec0150ffae..0655f9a390a0 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Valitse"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Kuvakaappaus"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Avaa selaimessa"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Avaa sovelluksessa"</string>
<string name="new_window_text" msgid="6318648868380652280">"Uusi ikkuna"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Hallinnoi ikkunoita"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Vaihda kuvasuhdetta"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Avaa valikko"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Jaa näyttö"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiivinen"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Palauta"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 1b9b74a45671..b9bdbd73aed6 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Ouvrir dans le navigateur"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Ouvrir dans l\'appli"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier les proportions"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aligner l\'écran"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersif"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurer"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 7e0a0b1acb7b..a1eb028a4f9c 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Ouvrir dans un navigateur"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Ouvrir dans l\'appli"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier le format"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Ouvrir le menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fractionner l\'écran"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersif"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurer"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index bdd07476efcf..22a7f7fcb35b 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Abrir na aplicación"</string>
<string name="new_window_text" msgid="6318648868380652280">"Ventá nova"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Xestionar as ventás"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar a proporción"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menú"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar pantalla"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Non se pode mover aquí a aplicación"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index d23c4fd8f0e0..06c21b46a97e 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"પસંદ કરો"</string>
<string name="screenshot_text" msgid="1477704010087786671">"સ્ક્રીનશૉટ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"બ્રાઉઝરમાં ખોલો"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ઍપમાં ખોલો"</string>
<string name="new_window_text" msgid="6318648868380652280">"નવી વિન્ડો"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"વિન્ડો મેનેજ કરો"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"સાપેક્ષ ગુણોત્તર બદલો"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"મેનૂ ખોલો"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"સ્ક્રીન સ્નૅપ કરો"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ઇમર્સિવ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"રિસ્ટોર કરો"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 4eec6f877fab..0eab10c34606 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"चुनें"</string>
<string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउज़र में खोलें"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ऐप्लिकेशन में खोलें"</string>
<string name="new_window_text" msgid="6318648868380652280">"नई विंडो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विंडो मैनेज करें"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेन्यू खोलें"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्नैप स्क्रीन"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"वापस लाएं"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index a119d9e7f782..bf756f63395b 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Odaberite"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snimka zaslona"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvori u pregledniku"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Otvori u aplikaciji"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promijeni omjer slike"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvaranje izbornika"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Izradi snimku zaslona"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Interaktivno"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index c07b6c3b9f1d..b02be18cb6f2 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Kiválasztás"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Képernyőkép"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Megnyitás böngészőben"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Megnyitás alkalmazásban"</string>
<string name="new_window_text" msgid="6318648868380652280">"Új ablak"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Ablakok kezelése"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Méretarány módosítása"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menü megnyitása"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Igazodás a képernyő adott részéhez"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Magával ragadó"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Visszaállítás"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 52eb18580de1..59a95f0c1393 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Ընտրել"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Սքրինշոթ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Բացել դիտարկիչում"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Բացել հավելվածում"</string>
<string name="new_window_text" msgid="6318648868380652280">"Նոր պատուհան"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Կառավարել պատուհանները"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Փոխել կողմերի հարաբերակցությունը"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Բացել ընտրացանկը"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ծալել էկրանը"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Ներկայության էֆեկտով"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Վերականգնել"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index f8f9d5e16439..baa1d0ec6bae 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Pilih"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Buka di browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Buka di Aplikasi"</string>
<string name="new_window_text" msgid="6318648868380652280">"Jendela Baru"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Kelola Jendela"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ubah rasio aspek"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Gabungkan Layar"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersif"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Pulihkan"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 8a9e3c0ca0a4..c3ad5d66e17a 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Velja"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skjámynd"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Opna í vafra"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Opna í forriti"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nýr gluggi"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Stjórna gluggum"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Breyta myndhlutfalli"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Opna valmynd"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Smelluskjár"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ekki er hægt að færa forritið hingað"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Umlykjandi"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Endurheimta"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 138adefed160..b75c041afdab 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Seleziona"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Apri nel browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Apri nell\'app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nuova finestra"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestisci finestre"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambia proporzioni"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Apri il menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aggancia schermo"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Ripristina"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 917738dc1575..5f37590298de 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"בחירה"</string>
<string name="screenshot_text" msgid="1477704010087786671">"צילום מסך"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"פתיחה בדפדפן"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"פתיחה באפליקציה"</string>
<string name="new_window_text" msgid="6318648868380652280">"חלון חדש"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ניהול החלונות"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"שינוי של יחס גובה-רוחב"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"פתיחת התפריט"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"הגדלת המסך"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"כיווץ המסך"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"לא ניתן להעביר את האפליקציה לכאן"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"סוחף"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"שחזור"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 35c48212cf39..2960a19cef0a 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"選択"</string>
<string name="screenshot_text" msgid="1477704010087786671">"スクリーンショット"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ブラウザで開く"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"アプリで開く"</string>
<string name="new_window_text" msgid="6318648868380652280">"新しいウィンドウ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ウィンドウを管理する"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"アスペクト比を変更"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"メニューを開く"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"画面のスナップ"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"没入モード"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"復元"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 9b9966f152ee..6420bf531f24 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"არჩევა"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ეკრანის ანაბეჭდი"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ბრაუზერში გახსნა"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"აპში გახსნა"</string>
<string name="new_window_text" msgid="6318648868380652280">"ახალი ფანჯარა"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ფანჯრების მართვა"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"თანაფარდობის შეცვლა"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"მენიუს გახსნა"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"აპლიკაციის დაპატარავება ეკრანზე"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"იმერსიული"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"აღდგენა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 8618ba9b2b0f..ef169537a899 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Таңдау"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Браузерден ашу"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Қолданбада ашу"</string>
<string name="new_window_text" msgid="6318648868380652280">"Жаңа терезе"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Терезелерді басқару"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Арақатынасты өзгерту"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Мәзірді ашу"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды бөлу"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Әсерлі"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Қалпына келтіру"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 7f853f3e1e2f..a625201261b1 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ជ្រើសរើស"</string>
<string name="screenshot_text" msgid="1477704010087786671">"រូបថតអេក្រង់"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"បើកក្នុងកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"បើក​នៅ​ក្នុង​កម្មវិធី"</string>
<string name="new_window_text" msgid="6318648868380652280">"វិនដូ​ថ្មី"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"គ្រប់គ្រង​វិនដូ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ប្ដូរ​​សមាមាត្រ"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"បើកម៉ឺនុយ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ថតអេក្រង់"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ជក់ចិត្ត"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ស្ដារ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 456dea2fdb0f..b2bf3a50d505 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ಬ್ರೌಸರ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ಹೊಸ ವಿಂಡೋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ವಿಂಡೋಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ಮೆನು ತೆರೆಯಿರಿ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ಸ್ನ್ಯಾಪ್ ಸ್ಕ್ರೀನ್"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ಇಮ್ಮರ್ಸಿವ್"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 763cda738541..ad0368a57460 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"선택"</string>
<string name="screenshot_text" msgid="1477704010087786671">"스크린샷"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"브라우저에서 열기"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"앱에서 열기"</string>
<string name="new_window_text" msgid="6318648868380652280">"새 창"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"창 관리"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"가로세로 비율 변경"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"메뉴 열기"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"화면 분할"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"몰입형"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"복원"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index bffc3b1d11a8..0b4eb934ff99 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Тандоо"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Серепчиден ачуу"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Колдонмодо ачуу"</string>
<string name="new_window_text" msgid="6318648868380652280">"Жаңы терезе"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Терезелерди тескөө"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Тараптардын катнашын өзгөртүү"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Менюну ачуу"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Экранды сүрөткө тартып алуу"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Сүңгүтүүчү"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Калыбына келтирүү"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index b48b07067521..9710e69a0418 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ເລືອກ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ຮູບໜ້າຈໍ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ເປີດໃນໂປຣແກຣມທ່ອງເວັບ"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ເປີດຢູ່ໃນແອັບ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ໜ້າຈໍໃໝ່"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ຈັດການໜ້າຈໍ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ເປີດເມນູ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ສະແນັບໜ້າຈໍ"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ສົມຈິງ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ກູ້ຄືນ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index d7a907cdc105..5bfb8e34fd53 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Pasirinkti"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekrano kopija"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Atidaryti naršyklėje"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Atidaryti programoje"</string>
<string name="new_window_text" msgid="6318648868380652280">"Naujas langas"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Tvarkyti langus"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Keisti kraštinių santykį"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atidaryti meniu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Sutraukti ekraną"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Įtraukiantis"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Atkurti"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 4ba7c2346a33..07342000ca66 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Atlasīt"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekrānuzņēmums"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Atvērt pārlūkā"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Atvērt lietotnē"</string>
<string name="new_window_text" msgid="6318648868380652280">"Jauns logs"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pārvaldīt logus"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mainīt malu attiecību"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Atvērt izvēlni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fiksēt ekrānu"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Iekļaujoši"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Atjaunot"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index d20eba55eac9..2c4503c23e80 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Изберете"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Слика од екранот"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Отвори во прелистувач"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Отвори во апликацијата"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управувајте со прозорци"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени го соодносот"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отвори го менито"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Подели го екранот на половина"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалистично"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 81c5094526c1..7e20ee1fc36b 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"തിരഞ്ഞെടുക്കുക"</string>
<string name="screenshot_text" msgid="1477704010087786671">"സ്ക്രീൻഷോട്ട്"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ബ്രൗസറിൽ തുറക്കുക"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ആപ്പിൽ തുറക്കുക"</string>
<string name="new_window_text" msgid="6318648868380652280">"പുതിയ വിന്‍ഡോ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"വിൻഡോകൾ മാനേജ് ചെയ്യുക"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"മെനു തുറക്കുക"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്‌ക്രീൻ വലുതാക്കുക"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"സ്‌ക്രീൻ സ്‌നാപ്പ് ചെയ്യുക"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ഇമേഴ്‌സീവ്"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"പുനഃസ്ഥാപിക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 35da93e774b5..ef24222cdef1 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Сонгох"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Дэлгэцийн агшин"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Хөтчид нээх"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Аппад нээх"</string>
<string name="new_window_text" msgid="6318648868380652280">"Шинэ цонх"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Windows-г удирдах"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Харьцааг өөрчлөх"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Цэсийг нээх"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Дэлгэцийг таллах"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Бодит мэт"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Сэргээх"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index c6b874a6780b..e665639ca217 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"निवडा"</string>
<string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउझरमध्ये उघडा"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"अ‍ॅपमध्ये उघडा"</string>
<string name="new_window_text" msgid="6318648868380652280">"नवीन विंडो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विंडो व्यवस्थापित करा"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आस्पेक्ट रेशो बदला"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनू उघडा"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रीन स्नॅप करा"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अ‍ॅप इथे हलवू शकत नाही"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव्ह"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"रिस्टोअर करा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 0fce0e9da45f..5de79c2c9afc 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Pilih"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Tangkapan skrin"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Buka dalam penyemak imbas"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Buka pada Apl"</string>
<string name="new_window_text" msgid="6318648868380652280">"Tetingkap Baharu"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Urus Tetingkap"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tukar nisbah bidang"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buka Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tangkap Skrin"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Mengasyikkan"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Pulihkan"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index abc2a19ba989..e6d355379f9a 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ရွေးရန်"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ဘရောင်ဇာတွင် ဖွင့်ရန်"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"အက်ပ်တွင် ဖွင့်ရန်"</string>
<string name="new_window_text" msgid="6318648868380652280">"ဝင်းဒိုးအသစ်"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ဝင်းဒိုးများ စီမံရန်"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"အချိုးအစား ပြောင်းရန်"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"မီနူး ဖွင့်ရန်"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"စခရင်ကို ချုံ့မည်"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"သုံးဘက်မြင်"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ပြန်ပြောင်းရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index ed6fb900564f..bde7ec67d0cb 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Velg"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skjermbilde"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Åpne i nettleseren"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Åpne i appen"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nytt vindu"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduene"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Endre høyde/bredde-forholdet"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Åpne menyen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fest skjermen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Oppslukende"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Gjenopprett"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index aff712901ff6..a40e3adede16 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"चयन गर्नुहोस्"</string>
<string name="screenshot_text" msgid="1477704010087786671">"स्क्रिनसट"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ब्राउजरमा खोल्नुहोस्"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"एपमा खोल्नुहोस्"</string>
<string name="new_window_text" msgid="6318648868380652280">"नयाँ विन्डो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विन्डोहरू व्यवस्थापन गर्नुहोस्"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"मेनु खोल्नुहोस्"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रिन स्न्याप गर्नुहोस्"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिभ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"रिस्टोर गर्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 8db3a0ecfc2f..b28b69080051 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Selecteren"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Openen in browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Openen in app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nieuw venster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Vensters beheren"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menu openen"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Scherm halveren"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersief"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Herstellen"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 69540898161c..842e3def41f1 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ଚୟନ କରନ୍ତୁ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ସ୍କ୍ରିନସଟ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ବ୍ରାଉଜରରେ ଖୋଲନ୍ତୁ"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ଆପରେ ଖୋଲନ୍ତୁ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ନୂଆ ୱିଣ୍ଡୋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ମେନୁ ଖୋଲନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ସ୍କ୍ରିନକୁ ସ୍ନାପ କରନ୍ତୁ"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ଇମର୍ସିଭ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index c627d7fcc2c5..e1c804a56289 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ਚੁਣੋ"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"ਬ੍ਰਾਊਜ਼ਰ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ਐਪ ਵਿੱਚ ਖੋਲ੍ਹੋ"</string>
<string name="new_window_text" msgid="6318648868380652280">"ਨਵੀਂ ਵਿੰਡੋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ਵਿੰਡੋਆਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"ਮੀਨੂ ਖੋਲ੍ਹੋ"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ਸਕ੍ਰੀਨ ਨੂੰ ਸਨੈਪ ਕਰੋ"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ਇਮਰਸਿਵ"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index a138c08d319a..e82916b89033 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Wybierz"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Zrzut ekranu"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Otwórz w przeglądarce"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Otwórz w aplikacji"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nowe okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Zarządzaj oknami"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmień format obrazu"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otwórz menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Przyciągnij ekran"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Tryb immersyjny"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Przywróć"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 9942f6980306..6d8c9ce2a72f 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Abrir no app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 559eea2d3cab..e0e91e715ed0 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de ecrã"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Abrir na app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Faça a gestão das janelas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar ecrã"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover a app para aqui"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 9942f6980306..6d8c9ce2a72f 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Abrir no navegador"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Abrir no app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Abrir o menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ajustar tela"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Imersivo"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index df0ee45695b2..5a381556207e 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Selectează"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Captură de ecran"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Deschide în browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Deschide în aplicație"</string>
<string name="new_window_text" msgid="6318648868380652280">"Fereastră nouă"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestionează ferestrele"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Schimbă raportul de dimensiuni"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Deschide meniul"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Micșorează fereastra și fixeaz-o"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Captivant"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restabilește"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 430f1b1448da..d26eb532be28 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Выбрать"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Открыть в браузере"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Открыть в приложении"</string>
<string name="new_window_text" msgid="6318648868380652280">"Новое окно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управление окнами"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Изменить соотношение сторон"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Открыть меню"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Свернуть"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Погружение"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Восстановить"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 3e3766768a7f..5bfa4c91bc6c 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"තෝරන්න"</string>
<string name="screenshot_text" msgid="1477704010087786671">"තිර රුව"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"බ්‍රව්සරයේ විවෘත කරන්න"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"යෙදුම තුළ විවෘත කරන්න"</string>
<string name="new_window_text" msgid="6318648868380652280">"නව කවුළුව"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"කවුළු කළමනාකරණය කරන්න"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"මෙනුව විවෘත කරන්න"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ස්නැප් තිරය"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ගිලෙන සුළු"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ප්‍රතිසාධනය කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 56a7edd08b23..cd20df5e1a1c 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Vybrať"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Snímka obrazovky"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Otvoriť v prehliadači"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Otvoriť v aplikácii"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Správa okien"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmeniť pomer strán"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Otvoriť ponuku"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Zobraziť polovicu obrazovky"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pútavé"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnoviť"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index b6344c981fc9..063e47c80d5f 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Izberi"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Posnetek zaslona"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Odpri v brskalniku"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Odpiranje v aplikaciji"</string>
<string name="new_window_text" msgid="6318648868380652280">"Novo okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje oken"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Sprememba razmerja stranic"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Odpri meni"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Pripni zaslon"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Poglobljeno"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovi"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index ab7499d505f8..f2fb7da44807 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Zgjidh"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Pamja e ekranit"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Hape në shfletues"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Hap në aplikacion"</string>
<string name="new_window_text" msgid="6318648868380652280">"Dritare e re"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Menaxho dritaret"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Hap menynë"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Regjistro ekranin"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Përfshirës"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restauro"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 773ed16dc4b9..f74e460226b6 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Изаберите"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Снимак екрана"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Отворите у прегледачу"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Отворите у апликацији"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нови прозор"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управљајте прозорима"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промените размеру"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Отворите мени"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Уклопи екран"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Имерзивне"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Врати"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 6f6a97b4495f..7a5549eb5f59 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Välj"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skärmbild"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Öppna i webbläsaren"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Öppna i appen"</string>
<string name="new_window_text" msgid="6318648868380652280">"Nytt fönster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Hantera fönster"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ändra bildformat"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Öppna menyn"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Fäst skärmen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Det går inte att flytta appen hit"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Uppslukande"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Återställ"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 72b7384fa83a..128ba74fd80c 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Chagua"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Picha ya skrini"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Fungua katika kivinjari"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Fungua kwenye Programu"</string>
<string name="new_window_text" msgid="6318648868380652280">"Dirisha Jipya"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Dhibiti Windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Badilisha uwiano"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Fungua Menyu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Panga Madirisha kwenye Skrini"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Shirikishi"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Rejesha"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 9d902912b377..668efd5ebf82 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"தேர்ந்தெடுக்கும்"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ஸ்கிரீன்ஷாட்"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"உலாவியில் திறக்கும்"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ஆப்ஸில் திறக்கும்"</string>
<string name="new_window_text" msgid="6318648868380652280">"புதிய சாளரம்"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"சாளரங்களை நிர்வகிக்கலாம்"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"தோற்ற விகிதத்தை மாற்று"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"மெனுவைத் திறக்கும்"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"திரையை ஸ்னாப் செய்"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ஈடுபட வைக்கும்"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"மீட்டெடுக்கும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 3c7c06a4fc1a..a3827bb3703a 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -102,7 +102,7 @@
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"యాప్ మెనూ నుండి ఏ సమయంలోనైనా ఫుల్ స్క్రీన్‌కు తిరిగి రండి"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"చూసి, మరిన్ని చేయండి"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"స్ప్లిట్ స్క్రీన్ కోసం మరొక యాప్‌లోకి లాగండి"</string>
- <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ స్థానాన్ని మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string>
+ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ లొకేషన్‌ను మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string>
<string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string>
<string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"మరింత సమాచారం కోసం విస్తరించండి."</string>
<string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"మెరుగైన వీక్షణ కోసం రీస్టార్ట్ చేయాలా?"</string>
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"ఎంచుకోండి"</string>
<string name="screenshot_text" msgid="1477704010087786671">"స్క్రీన్‌షాట్"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"బ్రౌజర్‌లో తెరవండి"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"యాప్‌లో తెరవండి"</string>
<string name="new_window_text" msgid="6318648868380652280">"కొత్త విండో"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"విండోలను మేనేజ్ చేయండి"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ఆకార నిష్పత్తిని మార్చండి"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"మెనూను తెరవండి"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్‌ను పెంచండి"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"స్క్రీన్‌ను స్నాప్ చేయండి"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"లీనమయ్యే"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"రీస్టోర్ చేయండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 9071bfb66e92..fe7556156e78 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"เลือก"</string>
<string name="screenshot_text" msgid="1477704010087786671">"ภาพหน้าจอ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"เปิดในเบราว์เซอร์"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"เปิดในแอป"</string>
<string name="new_window_text" msgid="6318648868380652280">"หน้าต่างใหม่"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"จัดการหน้าต่าง"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"เปลี่ยนสัดส่วนการแสดงผล"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"เปิดเมนู"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"สแนปหน้าจอ"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"สมจริง"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"คืนค่า"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index a00f7839186b..d9fb13bb0b6f 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Piliin"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Buksan sa browser"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Buksan sa App"</string>
<string name="new_window_text" msgid="6318648868380652280">"Bagong Window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pamahalaan ang Mga Window"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Baguhin ang aspect ratio"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Buksan ang Menu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"I-snap ang Screen"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"I-restore"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 8310a66e9d33..e6d900af0cf8 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Seç"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ekran görüntüsü"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Tarayıcıda aç"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Uygulamada Aç"</string>
<string name="new_window_text" msgid="6318648868380652280">"Yeni Pencere"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pencereleri yönet"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"En boy oranını değiştir"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menüyü aç"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranın Yarısına Tuttur"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Etkileyici"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Geri yükle"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 624a19e67724..ea599952a0e7 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Вибрати"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Знімок екрана"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Відкрити у вебпереглядачі"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Відкрити в додатку"</string>
<string name="new_window_text" msgid="6318648868380652280">"Нове вікно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Керувати вікнами"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змінити формат"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Відкрити меню"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Розгорнути екран"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Зафіксувати екран"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Сюди не можна перемістити додаток"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Реалістичність"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Відновити"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 2ccaf50fee21..6749629f2c3e 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"منتخب کریں"</string>
<string name="screenshot_text" msgid="1477704010087786671">"اسکرین شاٹ"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"براؤزر میں کھولیں"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"ایپ میں کھولیں"</string>
<string name="new_window_text" msgid="6318648868380652280">"نئی ونڈو"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"‏‫Windows کا نظم کریں"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تناسبی شرح کو تبدیل کریں"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"مینو کھولیں"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"اسکرین کا اسناپ شاٹ لیں"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"عمیق"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"بحال کریں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 88edc929528b..3417fef84de5 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Tanlash"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Skrinshot"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Brauzerda ochish"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Ilovada ochish"</string>
<string name="new_window_text" msgid="6318648868380652280">"Yangi oyna"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Oynalarni boshqarish"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tomonlar nisbatini oʻzgartirish"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Menyuni ochish"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Ekranni biriktirish"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersiv"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Tiklash"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index c1c7653ce90c..559bff8711bf 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Chọn"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Ảnh chụp màn hình"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Mở trong trình duyệt"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Mở trong Ứng dụng"</string>
<string name="new_window_text" msgid="6318648868380652280">"Cửa sổ mới"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Quản lý cửa sổ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Thay đổi tỷ lệ khung hình"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Mở Trình đơn"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Điều chỉnh kích thước màn hình"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Không di chuyển được ứng dụng đến đây"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Hiển thị tối đa"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Khôi phục"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 83e15d8cbdf6..f327653bd5d9 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"选择"</string>
<string name="screenshot_text" msgid="1477704010087786671">"屏幕截图"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"在浏览器中打开"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"在应用内打开"</string>
<string name="new_window_text" msgid="6318648868380652280">"新窗口"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理窗口"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"更改宽高比"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打开菜单"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"最大化屏幕"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"屏幕快照"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"无法将应用移至此处"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"沉浸式"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"恢复"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index f60b3efc6f38..e1ecd44eb69f 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"選取"</string>
<string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"在應用程式中開啟"</string>
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"打開選單"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"身歷其境"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"還原"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index b2227deeccc3..1b8f704cef29 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"選取"</string>
<string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"在瀏覽器中開啟"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"在應用程式中開啟"</string>
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更顯示比例"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"開啟選單"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"貼齊畫面"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"沉浸"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"還原"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 10d904fa17d2..604031733ed2 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -125,6 +125,7 @@
<string name="select_text" msgid="5139083974039906583">"Khetha"</string>
<string name="screenshot_text" msgid="1477704010087786671">"Isithombe-skrini"</string>
<string name="open_in_browser_text" msgid="9181692926376072904">"Vula kubhrawuza"</string>
+ <string name="open_in_app_text" msgid="2874590745116268525">"Vula Ku-app"</string>
<string name="new_window_text" msgid="6318648868380652280">"Iwindi Elisha"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Phatha Amawindi"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Shintsha ukubukeka kwesilinganiselo"</string>
@@ -132,7 +133,8 @@
<string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="6366422614991687237">"Vula Imenyu"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string>
- <string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Thwebula Isikrini"</string>
+ <!-- no translation found for desktop_mode_maximize_menu_snap_text (5673738963174074006) -->
+ <skip />
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
<string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Okugxilile"</string>
<string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Buyisela"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 7078d66d265c..21ec84d9bc0a 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -504,17 +504,15 @@
<dimen name="desktop_mode_maximize_menu_buttons_fill_radius">4dp</dimen>
<!-- The padding between the outline and fill of the maximize menu snap and maximize buttons. -->
<dimen name="desktop_mode_maximize_menu_snap_and_maximize_buttons_fill_padding">4dp</dimen>
- <!-- The padding between the outline and fill of the maximize menu snap and maximize buttons. -->
- <dimen name="desktop_mode_maximize_menu_snap_and_maximize_buttons_fill_padding_bottom">8dp</dimen>
<!-- The vertical padding between the outline and fill of the maximize menu restore button. -->
<dimen name="desktop_mode_maximize_menu_restore_button_fill_vertical_padding">13dp</dimen>
<!-- The horizontal padding between the outline and fill of the maximize menu restore button. -->
- <dimen name="desktop_mode_maximize_menu_restore_button_fill_horizontal_padding">21dp</dimen>
+ <dimen name="desktop_mode_maximize_menu_restore_button_fill_horizontal_padding">15dp</dimen>
<!-- The padding between the outline and fill of the maximize menu immersive button. -->
- <dimen name="desktop_mode_maximize_menu_immersive_button_fill_padding">4dp</dimen>
+ <dimen name="desktop_mode_maximize_menu_immersive_button_fill_padding">0dp</dimen>
<!-- The corner radius of the maximize menu. -->
- <dimen name="desktop_mode_maximize_menu_corner_radius">8dp</dimen>
+ <dimen name="desktop_mode_maximize_menu_corner_radius">16dp</dimen>
<!-- The radius of the Maximize menu shadow. -->
<dimen name="desktop_mode_maximize_menu_shadow_radius">8dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 012579a6d40c..468c345259d0 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -318,7 +318,7 @@
<!-- Maximize menu maximize button string. -->
<string name="desktop_mode_maximize_menu_maximize_text">Maximize Screen</string>
<!-- Maximize menu snap buttons string. -->
- <string name="desktop_mode_maximize_menu_snap_text">Snap Screen</string>
+ <string name="desktop_mode_maximize_menu_snap_text">Resize</string>
<!-- Snap resizing non-resizable string. -->
<string name="desktop_mode_non_resizable_snap_text">App can\'t be moved here</string>
<!-- Accessibility text for the Maximize Menu's immersive button [CHAR LIMIT=NONE] -->
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 55cda783005f..597a921302b7 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -29,6 +29,7 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowAnimationStyle">@null</item>
+ <item name="android:windowIsTranslucent">true</item>
</style>
<style name="Animation.ForcedResizable" parent="@android:style/Animation">
diff --git a/libs/WindowManager/Shell/shared/Android.bp b/libs/WindowManager/Shell/shared/Android.bp
new file mode 100644
index 000000000000..5113d980fb7d
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/Android.bp
@@ -0,0 +1,78 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+ default_team: "trendy_team_multitasking_windowing",
+}
+
+filegroup {
+ name: "wm_shell-shared-utils",
+ srcs: [
+ "src/com/android/wm/shell/shared/TransitionUtil.java",
+ ],
+}
+
+filegroup {
+ name: "wm_shell-shared-aidls",
+
+ srcs: [
+ "**/*.aidl",
+ ],
+
+ path: "src",
+}
+
+// NOTE: This shared lib is built with various apps and should not
+// contain resources that can be overlaid, as they would need
+// to be overlaid in each app individually.
+android_library {
+ name: "WindowManager-Shell-shared",
+
+ resource_dirs: [
+ "res",
+ ],
+ srcs: [
+ "**/*.java",
+ "**/*.kt",
+ ":wm_shell-shared-aidls",
+ ],
+ static_libs: [
+ "androidx.core_core-animation",
+ "androidx.dynamicanimation_dynamicanimation",
+ "jsr330",
+ ],
+ kotlincflags: ["-Xjvm-default=all"],
+ use_resource_processor: true,
+}
+
+// NOTE: This shared lib is built with various apps and should not
+// contain resources that can be overlaid, as they would need
+// to be overlaid in each app individually.
+java_library {
+ name: "WindowManager-Shell-shared-desktopMode",
+
+ srcs: [
+ "**/desktopmode/*.java",
+ "**/desktopmode/*.kt",
+ ],
+ static_libs: [
+ "com.android.window.flags.window-aconfig-java",
+ ],
+}
diff --git a/packages/BackupRestoreConfirmation/res/values/styles.xml b/libs/WindowManager/Shell/shared/AndroidManifest.xml
index ce54568ed6d6..5a4af5163fbe 100644
--- a/packages/BackupRestoreConfirmation/res/values/styles.xml
+++ b/libs/WindowManager/Shell/shared/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2024 The Android Open Source Project
+<!--
+ Copyright (C) 2024 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,12 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <!--
- TODO(b/309578419): Make activities handle insets properly and then remove this.
- -->
- <style name="OptOutEdgeToEdgeEnforcement">
- <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
- </style>
-</resources>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wm.shell.shared">
+</manifest>
diff --git a/libs/WindowManager/Shell/shared/res/values/config.xml b/libs/WindowManager/Shell/shared/res/values/config.xml
new file mode 100644
index 000000000000..a1d81cea093a
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/res/values/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+</resources> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
index 6bc995f14d44..04c17e54d11f 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -191,6 +191,23 @@ public class DesktopModeStatus {
}
/**
+ * @return {@code true} if this device is requesting to show the app handle despite non
+ * necessarily enabling desktop mode
+ */
+ public static boolean overridesShowAppHandle(@NonNull Context context) {
+ return Flags.showAppHandleLargeScreens()
+ && context.getResources().getBoolean(R.bool.config_enableAppHandle);
+ }
+
+ /**
+ * @return {@code true} if the app handle should be shown because desktop mode is enabled or
+ * the device is overriding {@code R.bool.config_enableAppHandle}
+ */
+ public static boolean canEnterDesktopModeOrShowAppHandle(@NonNull Context context) {
+ return canEnterDesktopMode(context) || overridesShowAppHandle(context);
+ }
+
+ /**
* Return {@code true} if the override desktop density is enabled and valid.
*/
public static boolean useDesktopOverrideDensity() {
@@ -264,5 +281,8 @@ public class DesktopModeStatus {
SystemProperties.Handle maxTaskLimitHandle = SystemProperties.find(MAX_TASK_LIMIT_SYS_PROP);
pw.print(innerPrefix); pw.print("maxTaskLimit sysprop=");
pw.println(maxTaskLimitHandle == null ? "null" : maxTaskLimitHandle.getInt(/* def= */ -1));
+
+ pw.print(innerPrefix); pw.print("showAppHandle config override=");
+ pw.print(context.getResources().getBoolean(R.bool.config_enableAppHandle));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index ce7a97703f44..e9cfd9bc2209 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -37,6 +37,7 @@ import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_B
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
+import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.app.TaskInfo;
@@ -73,10 +74,12 @@ import android.window.BackMotionEvent;
import android.window.BackNavigationInfo;
import android.window.BackTouchTracker;
import android.window.IBackAnimationFinishedCallback;
+import android.window.IBackAnimationHandoffHandler;
import android.window.IBackAnimationRunner;
import android.window.IOnBackInvokedCallback;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -84,6 +87,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.animation.TransitionAnimator;
+import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
@@ -227,6 +232,15 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private Runnable mPilferPointerCallback;
private BackAnimation.TopUiRequest mRequestTopUiCallback;
+ private final IBackAnimationHandoffHandler mHandoffHandler =
+ new IBackAnimationHandoffHandler.Stub() {
+ @Override
+ public void handOffAnimation(
+ RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+ mBackTransitionHandler.handOffAnimation(targets, states);
+ }
+ };
+
public BackAnimationController(
@NonNull ShellInit shellInit,
@NonNull ShellController shellController,
@@ -282,7 +296,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mShellCommandHandler = shellCommandHandler;
mWindowManager = context.getSystemService(WindowManager.class);
mTransitions = transitions;
- mBackTransitionHandler = new BackTransitionHandler();
+ mBackTransitionHandler = new BackTransitionHandler(mTransitions);
mTransitions.addHandler(mBackTransitionHandler);
mHandler = handler;
mTransitions.registerObserver(mBackTransitionObserver);
@@ -715,6 +729,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
try {
callback.onBackStarted(backEvent);
+ if (mBackTransitionHandler.canHandOffAnimation()) {
+ callback.setHandoffHandler(mHandoffHandler);
+ }
mOnBackStartDispatched = true;
} catch (RemoteException e) {
Log.e(TAG, "dispatchOnBackStarted error: ", e);
@@ -1192,6 +1209,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
class BackTransitionHandler implements Transitions.TransitionHandler {
+ private final Transitions mTransitions;
Runnable mOnAnimationFinishCallback;
boolean mCloseTransitionRequested;
@@ -1203,6 +1221,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
// animation is canceled, start a close prepare transition to finish the whole transition.
IBinder mClosePrepareTransition;
TransitionInfo mOpenTransitionInfo;
+ Transitions.TransitionHandler mTakeoverHandler;
+
+ BackTransitionHandler(Transitions transitions) {
+ mTransitions = transitions;
+ }
+
void onAnimationFinished() {
if (!mCloseTransitionRequested && mPrepareOpenTransition != null) {
createClosePrepareTransition();
@@ -1214,18 +1238,23 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
private void applyFinishOpenTransition() {
- mOpenTransitionInfo = null;
- mPrepareOpenTransition = null;
if (mFinishOpenTransaction != null) {
final SurfaceControl.Transaction t = mFinishOpenTransaction;
- mFinishOpenTransaction = null;
t.apply();
}
if (mFinishOpenTransitionCallback != null) {
final Transitions.TransitionFinishCallback callback = mFinishOpenTransitionCallback;
- mFinishOpenTransitionCallback = null;
callback.onTransitionFinished(null);
}
+ cleanUpInternalState();
+ }
+
+ private void cleanUpInternalState() {
+ mOpenTransitionInfo = null;
+ mPrepareOpenTransition = null;
+ mFinishOpenTransaction = null;
+ mFinishOpenTransitionCallback = null;
+ mTakeoverHandler = null;
}
private void applyAndFinish(@NonNull SurfaceControl.Transaction st,
@@ -1237,6 +1266,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
finishCallback.onTransitionFinished(null);
mCloseTransitionRequested = false;
}
+
@Override
public boolean startAnimation(@NonNull IBinder transition,
@NonNull TransitionInfo info,
@@ -1246,6 +1276,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
final boolean isPrepareTransition =
info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
if (isPrepareTransition) {
+ if (checkTakeoverFlags()) {
+ mTakeoverHandler = mTransitions.getHandlerForTakeover(transition, info);
+ }
kickStartAnimation();
}
// Both mShellExecutor and Transitions#mMainExecutor are ShellMainThread, so we don't
@@ -1288,6 +1321,57 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
return handleCloseTransition(info, st, ft, finishCallback);
}
+ private boolean canHandOffAnimation() {
+ if (!checkTakeoverFlags()) {
+ return false;
+ }
+
+ return mTakeoverHandler != null;
+ }
+
+ private void handOffAnimation(
+ RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+ if (!checkTakeoverFlags()) {
+ ProtoLog.e(WM_SHELL_BACK_PREVIEW,
+ "Trying to hand off the animation, but the required flags are disabled.");
+ return;
+ } else if (mTakeoverHandler == null) {
+ ProtoLog.e(WM_SHELL_BACK_PREVIEW,
+ "Missing takeover handler when trying to hand off animation.");
+ return;
+ } else if (targets.length != states.length) {
+ ProtoLog.e(WM_SHELL_BACK_PREVIEW,
+ "Targets passed for takeover don't match the window states.");
+ return;
+ }
+
+ // The states passed to this method are paired with the targets, but they need to be
+ // paired with the changes inside the TransitionInfo. So for each change we find its
+ // matching target, and leave the state for any change missing a matching target blank.
+ WindowAnimationState[] updatedStates =
+ new WindowAnimationState[mOpenTransitionInfo.getChanges().size()];
+ for (int i = 0; i < mOpenTransitionInfo.getChanges().size(); i++) {
+ ActivityManager.RunningTaskInfo taskInfo =
+ mOpenTransitionInfo.getChanges().get(i).getTaskInfo();
+ if (taskInfo == null) {
+ continue;
+ }
+
+ for (int j = 0; j < targets.length; j++) {
+ if (taskInfo.taskId == targets[j].taskId) {
+ updatedStates[i] = states[j];
+ break;
+ }
+ }
+ }
+
+ mTakeoverHandler.takeOverAnimation(
+ mPrepareOpenTransition, mOpenTransitionInfo, new SurfaceControl.Transaction(),
+ mFinishOpenTransitionCallback, updatedStates);
+
+ cleanUpInternalState();
+ }
+
@Override
public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
@Nullable SurfaceControl.Transaction finishTransaction) {
@@ -1673,6 +1757,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
return null;
}
+
+ private static boolean checkTakeoverFlags() {
+ return TransitionAnimator.Companion.longLivedReturnAnimationsEnabled()
+ && Flags.unifyBackNavigationTransition();
+ }
}
private static boolean isNotGestureBackTransition(@NonNull TransitionInfo info) {
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 603a9ec6bedb..b82496e45415 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
@@ -1327,7 +1327,11 @@ public class BubbleController implements ConfigurationChangeListener,
/** Promote the provided bubble from the overflow view. */
public void promoteBubbleFromOverflow(Bubble bubble) {
- mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_BACK_TO_STACK);
+ if (isShowingAsBubbleBar()) {
+ mLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_OVERFLOW_REMOVE_BACK_TO_BAR);
+ } else {
+ mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_BACK_TO_STACK);
+ }
ProtoLog.d(WM_SHELL_BUBBLES, "promoteBubbleFromOverflow=%s", bubble.getKey());
bubble.setInflateSynchronously(mInflateSynchronously);
bubble.setShouldAutoExpand(true);
@@ -1350,11 +1354,7 @@ public class BubbleController implements ConfigurationChangeListener,
if (BubbleOverflow.KEY.equals(key)) {
mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
mLayerView.showExpandedView(mBubbleData.getOverflow());
- if (wasExpanded) {
- mLogger.log(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED);
- } else {
- mLogger.log(BubbleLogger.Event.BUBBLE_BAR_EXPANDED);
- }
+ mLogger.log(BubbleLogger.Event.BUBBLE_BAR_OVERFLOW_SELECTED);
return;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 4de9dfa54c5d..294569190f68 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -759,7 +759,9 @@ public class BubbleData {
if (b != null) {
b.stopInflation();
}
- mLogger.logOverflowRemove(b, reason);
+ if (!mPositioner.isShowingInBubbleBar()) {
+ mLogger.logStackOverflowRemove(b, reason);
+ }
mOverflowBubbles.remove(b);
mStateChange.bubbleRemoved(b, reason);
mStateChange.removedOverflowBubble = b;
@@ -802,6 +804,27 @@ public class BubbleData {
setNewSelectedIndex(indexToRemove);
}
maybeSendDeleteIntent(reason, bubbleToRemove);
+
+ if (mPositioner.isShowingInBubbleBar()) {
+ logBubbleBarBubbleRemoved(bubbleToRemove, reason);
+ }
+ }
+
+ private void logBubbleBarBubbleRemoved(Bubble bubble, @DismissReason int reason) {
+ switch (reason) {
+ case Bubbles.DISMISS_NOTIF_CANCEL:
+ mLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_REMOVED_CANCELED);
+ break;
+ case Bubbles.DISMISS_TASK_FINISHED:
+ mLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_ACTIVITY_FINISH);
+ break;
+ case Bubbles.DISMISS_BLOCKED:
+ case Bubbles.DISMISS_NO_LONGER_BUBBLE:
+ mLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_REMOVED_BLOCKED);
+ break;
+ default:
+ // skip logging other events
+ }
}
private void setNewSelectedIndex(int indexOfSelected) {
@@ -862,7 +885,7 @@ public class BubbleData {
return;
}
ProtoLog.d(WM_SHELL_BUBBLES, "overflowBubble=%s", bubble.getKey());
- mLogger.logOverflowAdd(bubble, reason);
+ mLogger.logOverflowAdd(bubble, mPositioner.isShowingInBubbleBar(), reason);
if (mOverflowBubbles.isEmpty()) {
mStateChange.showOverflowChanged = true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java
index 36630733e1da..347df330c4b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleLogger.java
@@ -182,10 +182,12 @@ public class BubbleLogger {
}
/**
+ * Log when a bubble is removed from overflow in stack view
+ *
* @param b Bubble removed from overflow
* @param r Reason that bubble was removed
*/
- public void logOverflowRemove(Bubble b, @Bubbles.DismissReason int r) {
+ public void logStackOverflowRemove(Bubble b, @Bubbles.DismissReason int r) {
if (r == Bubbles.DISMISS_NOTIF_CANCEL) {
log(b, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_CANCEL);
} else if (r == Bubbles.DISMISS_GROUP_CANCELLED) {
@@ -201,13 +203,19 @@ public class BubbleLogger {
* @param b Bubble added to overflow
* @param r Reason that bubble was added to overflow
*/
- public void logOverflowAdd(Bubble b, @Bubbles.DismissReason int r) {
- if (r == Bubbles.DISMISS_AGED) {
- log(b, Event.BUBBLE_OVERFLOW_ADD_AGED);
- } else if (r == Bubbles.DISMISS_USER_GESTURE) {
- log(b, Event.BUBBLE_OVERFLOW_ADD_USER_GESTURE);
- } else if (r == Bubbles.DISMISS_RELOAD_FROM_DISK) {
- log(b, Event.BUBBLE_OVERFLOW_RECOVER);
+ public void logOverflowAdd(Bubble b, boolean bubbleBar, @Bubbles.DismissReason int r) {
+ if (bubbleBar) {
+ if (r == Bubbles.DISMISS_AGED) {
+ log(b, Event.BUBBLE_BAR_OVERFLOW_ADD_AGED);
+ }
+ } else {
+ if (r == Bubbles.DISMISS_AGED) {
+ log(b, Event.BUBBLE_OVERFLOW_ADD_AGED);
+ } else if (r == Bubbles.DISMISS_USER_GESTURE) {
+ log(b, Event.BUBBLE_OVERFLOW_ADD_USER_GESTURE);
+ } else if (r == Bubbles.DISMISS_RELOAD_FROM_DISK) {
+ log(b, Event.BUBBLE_OVERFLOW_RECOVER);
+ }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index c386c9398624..068b2d246500 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -830,6 +830,13 @@ public class BubblePositioner {
mShowingInBubbleBar = showingInBubbleBar;
}
+ /**
+ * Whether bubbles ar showing in the bubble bar from launcher.
+ */
+ boolean isShowingInBubbleBar() {
+ return mShowingInBubbleBar;
+ }
+
public void setBubbleBarLocation(BubbleBarLocation location) {
mBubbleBarLocation = location;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index cf858deb0327..2c418d34f09a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -90,8 +90,8 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
private int mHandleRegionHeight;
/**
- * Tracks divider bar visible bounds in screen-based coordination. Used to calculate with
- * insets.
+ * This is not the visible bounds you see on screen, but the actual behind-the-scenes window
+ * bounds, which is larger.
*/
private final Rect mDividerBounds = new Rect();
private final Rect mTempRect = new Rect();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
new file mode 100644
index 000000000000..381f0b037023
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/OffscreenTouchZone.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.common.split;
+
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+
+import static com.android.wm.shell.common.split.SplitLayout.RESTING_TOUCH_LAYER;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.PixelFormat;
+import android.os.Binder;
+import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowlessWindowManager;
+
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+/**
+ * Holds and manages a single touchable surface. These are used in offscreen split layouts, where
+ * we use them as a signal that the user wants to bring an offscreen app back onscreen.
+ * <br>
+ * Split root
+ * / | \
+ * Stage root Divider Stage root
+ * / \
+ * Task *this class*
+ *
+ */
+public class OffscreenTouchZone {
+ private static final String TAG = "OffscreenTouchZone";
+
+ /**
+ * Whether this touch zone is on the top/left or the bottom/right screen edge.
+ */
+ private final boolean mIsTopLeft;
+ /** The function that will be run when this zone is tapped. */
+ private final Runnable mOnClickRunnable;
+ private SurfaceControlViewHost mViewHost;
+
+ /**
+ * @param isTopLeft Whether the desired touch zone will be on the top/left or the bottom/right
+ * screen edge.
+ * @param runnable The function to run when the touch zone is tapped.
+ */
+ OffscreenTouchZone(boolean isTopLeft, Runnable runnable) {
+ mIsTopLeft = isTopLeft;
+ mOnClickRunnable = runnable;
+ }
+
+ /** Sets up a touch zone. */
+ public void inflate(Context context, Configuration config, SyncTransactionQueue syncQueue,
+ SurfaceControl stageRoot) {
+ View touchableView = new View(context);
+ touchableView.setOnTouchListener(new OffscreenTouchListener());
+
+ // Set WM flags, tokens, and sizing on the touchable view. It will be the same size as its
+ // parent, the stage root.
+ // TODO (b/349828130): It's a bit wasteful to have the touch zone cover the whole app
+ // surface, even extending offscreen (keeps buffer active in memory), so can trim it down
+ // to the visible onscreen area in a future patch.
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_INPUT_CONSUMER,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.TRANSLUCENT);
+ lp.token = new Binder();
+ lp.setTitle(TAG);
+ lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
+ touchableView.setLayoutParams(lp);
+
+ // Create a new leash under our stage leash.
+ final SurfaceControl.Builder builder = new SurfaceControl.Builder()
+ .setContainerLayer()
+ .setName(TAG + (mIsTopLeft ? "TopLeft" : "BottomRight"))
+ .setCallsite("OffscreenTouchZone::init");
+ builder.setParent(stageRoot);
+ SurfaceControl leash = builder.build();
+
+ // Create a ViewHost that will hold our view.
+ WindowlessWindowManager wwm = new WindowlessWindowManager(config, leash, null);
+ mViewHost = new SurfaceControlViewHost(context, context.getDisplay(), wwm,
+ "SplitTouchZones");
+ mViewHost.setView(touchableView, lp);
+
+ // Create a transaction so that we can activate and reposition our surface.
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ // Set layer to maximum. We want this surface to be above the app layer, or else touches
+ // will be blocked.
+ t.setLayer(leash, RESTING_TOUCH_LAYER);
+ // Leash starts off hidden, show it.
+ t.show(leash);
+ syncQueue.runInSync(transaction -> {
+ transaction.merge(t);
+ t.close();
+ });
+ }
+
+ /** Releases the touch zone when it's no longer needed. */
+ void release() {
+ if (mViewHost != null) {
+ mViewHost.release();
+ }
+ }
+
+ /**
+ * Listens for touch events.
+ * TODO (b/349828130): Update for mouse click events as well, and possibly keyboard?
+ */
+ private class OffscreenTouchListener implements View.OnTouchListener {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
+ mOnClickRunnable.run();
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Returns {@code true} if this touch zone represents an offscreen app on the top/left edge of
+ * the display, {@code false} for bottom/right.
+ */
+ public boolean isTopLeft() {
+ return mIsTopLeft;
+ }
+}
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 de3152ad7687..d20ad5d1b908 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
@@ -23,8 +23,8 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-import static com.android.wm.shell.common.split.SplitLayout.BEHIND_APP_VEIL_LAYER;
-import static com.android.wm.shell.common.split.SplitLayout.FRONT_APP_VEIL_LAYER;
+import static com.android.wm.shell.common.split.SplitLayout.ANIMATING_BACK_APP_VEIL_LAYER;
+import static com.android.wm.shell.common.split.SplitLayout.ANIMATING_FRONT_APP_VEIL_LAYER;
import static com.android.wm.shell.shared.split.SplitScreenConstants.FADE_DURATION;
import static com.android.wm.shell.shared.split.SplitScreenConstants.VEIL_DELAY_DURATION;
@@ -66,6 +66,13 @@ import java.util.function.Consumer;
* Currently, we show a veil when:
* a) Task is resizing down from a fullscreen window.
* b) Task is being stretched past its original bounds.
+ * <br>
+ * Split root
+ * / | \
+ * Stage root Divider Stage root
+ * / \
+ * Task *this class*
+ *
*/
public class SplitDecorManager extends WindowlessWindowManager {
private static final String TAG = SplitDecorManager.class.getSimpleName();
@@ -77,6 +84,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
private Drawable mIcon;
private ImageView mVeilIconView;
private SurfaceControlViewHost mViewHost;
+ /** The parent surface that this is attached to. Should be the stage root. */
private SurfaceControl mHostLeash;
private SurfaceControl mIconLeash;
private SurfaceControl mBackgroundLeash;
@@ -389,7 +397,9 @@ public class SplitDecorManager extends WindowlessWindowManager {
mOffsetX = (int) iconOffsetX;
mOffsetY = (int) iconOffsetY;
- t.setLayer(leash, isGoingBehind ? BEHIND_APP_VEIL_LAYER : FRONT_APP_VEIL_LAYER);
+ t.setLayer(leash, isGoingBehind
+ ? ANIMATING_BACK_APP_VEIL_LAYER
+ : ANIMATING_FRONT_APP_VEIL_LAYER);
if (!mShown) {
if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
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 dab30b0f0b96..6beff1979e6d 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
@@ -33,6 +33,8 @@ import static com.android.wm.shell.shared.animation.Interpolators.LINEAR;
import static com.android.wm.shell.shared.animation.Interpolators.SLOWDOWN_INTERPOLATOR;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_90_10;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_10_45_45;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_3_45_45_10;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -72,6 +74,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.protolog.ProtoLog;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -80,6 +83,7 @@ import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget;
+import com.android.wm.shell.common.split.SplitWindowManager.ParentContainerCallbacks;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition;
@@ -88,6 +92,8 @@ import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.StageTaskListener;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
/**
@@ -111,15 +117,19 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
public static final float OFFSCREEN_ASYMMETRIC_RATIO = 0.1f;
// Here are some (arbitrarily decided) layer definitions used during animations to make sure the
- // layers stay in order. Note: This does not affect any other layer numbering systems because
- // the layer system in WindowManager is local within sibling groups. So, for example, each
- // "veil layer" defined here actually has two sub-layers; and *their* layer values, which we set
- // in SplitDecorManager, are only important relative to each other.
- public static final int DIVIDER_LAYER = 0;
- public static final int FRONT_APP_VEIL_LAYER = DIVIDER_LAYER + 20;
- public static final int FRONT_APP_LAYER = DIVIDER_LAYER + 10;
- public static final int BEHIND_APP_VEIL_LAYER = DIVIDER_LAYER - 10;
- public static final int BEHIND_APP_LAYER = DIVIDER_LAYER - 20;
+ // layers stay in order. (During transitions, everything is reparented onto a transition root
+ // and can be freely relayered.)
+ public static final int ANIMATING_DIVIDER_LAYER = 0;
+ public static final int ANIMATING_FRONT_APP_VEIL_LAYER = ANIMATING_DIVIDER_LAYER + 20;
+ public static final int ANIMATING_FRONT_APP_LAYER = ANIMATING_DIVIDER_LAYER + 10;
+ public static final int ANIMATING_BACK_APP_VEIL_LAYER = ANIMATING_DIVIDER_LAYER - 10;
+ public static final int ANIMATING_BACK_APP_LAYER = ANIMATING_DIVIDER_LAYER - 20;
+ // The divider is on the split root, and is sibling with the stage roots. We want to keep it
+ // above the app stages.
+ public static final int RESTING_DIVIDER_LAYER = Integer.MAX_VALUE;
+ // The touch layer is on a stage root, and is sibling with things like the app activity itself
+ // and the app veil. We want it to be above all those.
+ public static final int RESTING_TOUCH_LAYER = Integer.MAX_VALUE;
// Animation specs for the swap animation
private static final int SWAP_ANIMATION_TOTAL_DURATION = 500;
@@ -139,19 +149,31 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
private final Rect mTempRect = new Rect();
private final Rect mRootBounds = new Rect();
private final Rect mDividerBounds = new Rect();
- // Bounds1 final position should be always at top or left
- private final Rect mBounds1 = new Rect();
- // Bounds2 final position should be always at bottom or right
- private final Rect mBounds2 = new Rect();
+ /**
+ * A list of stage bounds, kept in order from top/left to bottom/right. These are the sizes of
+ * the app surfaces, not necessarily the same as the size of the rendered content.
+ * See {@link #mContentBounds}.
+ */
+ private final List<Rect> mStageBounds = List.of(new Rect(), new Rect());
+ /**
+ * A list of app content bounds, kept in order from top/left to bottom/right. These are the
+ * sizes of the rendered app contents, not necessarily the same as the size of the drawn app
+ * surfaces. See {@link #mStageBounds}.
+ */
+ private final List<Rect> mContentBounds = List.of(new Rect(), new Rect());
// The temp bounds outside of display bounds for side stage when split screen inactive to avoid
// flicker next time active split screen.
private final Rect mInvisibleBounds = new Rect();
- private final Rect mWinBounds1 = new Rect();
- private final Rect mWinBounds2 = new Rect();
+ /**
+ * Areas on the screen that the user can touch to shift the layout, bringing offscreen apps
+ * onscreen. If n apps are offscreen, there should be n such areas. Empty otherwise.
+ */
+ private final List<OffscreenTouchZone> mOffscreenTouchZones = new ArrayList<>();
private final SplitLayoutHandler mSplitLayoutHandler;
private final SplitWindowManager mSplitWindowManager;
private final DisplayController mDisplayController;
private final DisplayImeController mDisplayImeController;
+ private final ParentContainerCallbacks mParentContainerCallbacks;
private final ImePositionProcessor mImePositionProcessor;
private final ResizingEffectPolicy mSurfaceEffectPolicy;
private final ShellTaskOrganizer mTaskOrganizer;
@@ -192,6 +214,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mSplitLayoutHandler = splitLayoutHandler;
mDisplayController = displayController;
mDisplayImeController = displayImeController;
+ mParentContainerCallbacks = parentContainerCallbacks;
mSplitWindowManager = new SplitWindowManager(windowName, mContext, configuration,
parentContainerCallbacks);
mTaskOrganizer = taskOrganizer;
@@ -233,26 +256,26 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mDividerWindowWidth = mDividerSize + 2 * mDividerInsets;
}
- /** Gets bounds of the primary split with screen based coordinate. */
- public Rect getBounds1() {
- return new Rect(mBounds1);
+ /** Gets the bounds of the top/left app in screen-based coordinates. */
+ public Rect getTopLeftBounds() {
+ return mStageBounds.getFirst();
}
- /** Gets bounds of the primary split with parent based coordinate. */
- public Rect getRefBounds1() {
- Rect outBounds = getBounds1();
- outBounds.offset(-mRootBounds.left, -mRootBounds.top);
- return outBounds;
+ /** Gets the bounds of the bottom/right app in screen-based coordinates. */
+ public Rect getBottomRightBounds() {
+ return mStageBounds.getLast();
}
- /** Gets bounds of the secondary split with screen based coordinate. */
- public Rect getBounds2() {
- return new Rect(mBounds2);
+ /** Gets the bounds of the top/left app in parent-based coordinates. */
+ public Rect getTopLeftRefBounds() {
+ Rect outBounds = getTopLeftBounds();
+ outBounds.offset(-mRootBounds.left, -mRootBounds.top);
+ return outBounds;
}
- /** Gets bounds of the secondary split with parent based coordinate. */
- public Rect getRefBounds2() {
- final Rect outBounds = getBounds2();
+ /** Gets the bounds of the bottom/right app in parent-based coordinates. */
+ public Rect getBottomRightRefBounds() {
+ Rect outBounds = getBottomRightBounds();
outBounds.offset(-mRootBounds.left, -mRootBounds.top);
return outBounds;
}
@@ -262,51 +285,74 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
return new Rect(mRootBounds);
}
- /** Gets bounds of divider window with screen based coordinate. */
- public Rect getDividerBounds() {
- return new Rect(mDividerBounds);
+ /** Copies the top/left bounds to the provided Rect (screen-based coordinates). */
+ public void copyTopLeftBounds(Rect rect) {
+ rect.set(getTopLeftBounds());
}
- /** Gets bounds of divider window with parent based coordinate. */
- public Rect getRefDividerBounds() {
- final Rect outBounds = getDividerBounds();
- outBounds.offset(-mRootBounds.left, -mRootBounds.top);
- return outBounds;
+ /** Copies the top/left bounds to the provided Rect (parent-based coordinates). */
+ public void copyTopLeftRefBounds(Rect rect) {
+ copyTopLeftBounds(rect);
+ rect.offset(-mRootBounds.left, -mRootBounds.top);
}
- /** Gets bounds of the primary split with screen based coordinate on the param Rect. */
- public void getBounds1(Rect rect) {
- rect.set(mBounds1);
+ /** Copies the bottom/right bounds to the provided Rect (screen-based coordinates). */
+ public void copyBottomRightBounds(Rect rect) {
+ rect.set(getBottomRightBounds());
}
- /** Gets bounds of the primary split with parent based coordinate on the param Rect. */
- public void getRefBounds1(Rect rect) {
- getBounds1(rect);
+ /** Copies the bottom/right bounds to the provided Rect (parent-based coordinates). */
+ public void copyBottomRightRefBounds(Rect rect) {
+ copyBottomRightBounds(rect);
rect.offset(-mRootBounds.left, -mRootBounds.top);
}
- /** Gets bounds of the secondary split with screen based coordinate on the param Rect. */
- public void getBounds2(Rect rect) {
- rect.set(mBounds2);
+ /**
+ * Gets the content bounds of the top/left app (the bounds of where the app contents would be
+ * drawn). Might be larger than the available surface space.
+ */
+ public Rect getTopLeftContentBounds() {
+ return mContentBounds.getFirst();
}
- /** Gets bounds of the secondary split with parent based coordinate on the param Rect. */
- public void getRefBounds2(Rect rect) {
- getBounds2(rect);
- rect.offset(-mRootBounds.left, -mRootBounds.top);
+ /**
+ * Gets the content bounds of the bottom/right app (the bounds of where the app contents would
+ * be drawn). Might be larger than the available surface space.
+ */
+ public Rect getBottomRightContentBounds() {
+ return mContentBounds.getLast();
}
- /** Gets root bounds of the whole split layout on the param Rect. */
- public void getRootBounds(Rect rect) {
- rect.set(mRootBounds);
+ /**
+ * Gets the bounds of divider window, in screen-based coordinates. This is not the visible
+ * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+ */
+ public Rect getDividerBounds() {
+ return new Rect(mDividerBounds);
+ }
+
+ /**
+ * Gets the bounds of divider window, in parent-based coordinates. This is not the visible
+ * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+ */
+ public Rect getRefDividerBounds() {
+ final Rect outBounds = getDividerBounds();
+ outBounds.offset(-mRootBounds.left, -mRootBounds.top);
+ return outBounds;
}
- /** Gets bounds of divider window with screen based coordinate on the param Rect. */
+ /**
+ * Gets the bounds of divider window, in screen-based coordinates. This is not the visible
+ * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+ */
public void getDividerBounds(Rect rect) {
rect.set(mDividerBounds);
}
- /** Gets bounds of divider window with parent based coordinate on the param Rect. */
+ /**
+ * Gets the bounds of divider window, in parent-based coordinates. This is not the visible
+ * bounds you see on screen, but the actual behind-the-scenes window bounds, which is larger.
+ */
public void getRefDividerBounds(Rect rect) {
getDividerBounds(rect);
rect.offset(-mRootBounds.left, -mRootBounds.top);
@@ -340,8 +386,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
*/
public float getDividerPositionAsFraction() {
return Math.min(1f, Math.max(0f, mIsLeftRightSplit
- ? (float) ((mBounds1.right + mBounds2.left) / 2f) / mBounds2.right
- : (float) ((mBounds1.bottom + mBounds2.top) / 2f) / mBounds2.bottom));
+ ? (float) ((getTopLeftBounds().right + getBottomRightBounds().left) / 2f)
+ / getBottomRightBounds().right
+ : (float) ((getTopLeftBounds().bottom + getBottomRightBounds().top) / 2f)
+ / getBottomRightBounds().bottom));
}
private void updateInvisibleRect() {
@@ -352,6 +400,46 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mIsLeftRightSplit ? 0 : mRootBounds.bottom);
}
+ /**
+ * (Re)calculates and activates any needed touch zones, so the user can tap them and retrieve
+ * offscreen apps.
+ */
+ public void populateTouchZones() {
+ if (!Flags.enableFlexibleTwoAppSplit()) {
+ return;
+ }
+
+ if (!mOffscreenTouchZones.isEmpty()) {
+ removeTouchZones();
+ }
+
+ int currentPosition = calculateCurrentSnapPosition();
+ switch (currentPosition) {
+ case SNAP_TO_2_10_90:
+ case SNAP_TO_3_10_45_45:
+ mOffscreenTouchZones.add(new OffscreenTouchZone(true /* isTopLeft */,
+ () -> flingDividerToOtherSide(currentPosition)));
+ break;
+ case SNAP_TO_2_90_10:
+ case SNAP_TO_3_45_45_10:
+ mOffscreenTouchZones.add(new OffscreenTouchZone(false /* isTopLeft */,
+ () -> flingDividerToOtherSide(currentPosition)));
+ break;
+ }
+
+ mOffscreenTouchZones.forEach(mParentContainerCallbacks::inflateOnStageRoot);
+ }
+
+ /** Removes all touch zones. */
+ public void removeTouchZones() {
+ if (!Flags.enableFlexibleTwoAppSplit()) {
+ return;
+ }
+
+ mOffscreenTouchZones.forEach(OffscreenTouchZone::release);
+ mOffscreenTouchZones.clear();
+ }
+
/** Applies new configuration, returns {@code false} if there's no effect to the layout. */
public boolean updateConfiguration(Configuration configuration) {
// Update the split bounds when necessary. Besides root bounds changed, split bounds need to
@@ -435,7 +523,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
}
private void updateBounds(int position) {
- updateBounds(position, mBounds1, mBounds2, mDividerBounds, true /* setEffectBounds */);
+ updateBounds(position, getTopLeftBounds(), getBottomRightBounds(), mDividerBounds,
+ true /* setEffectBounds */);
}
/** Updates recording bounds of divider window and both of the splits. */
@@ -488,6 +577,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
if (mInitialized) return;
mInitialized = true;
mSplitWindowManager.init(this, mInsetsState, false /* isRestoring */);
+ populateTouchZones();
mDisplayImeController.addPositionProcessor(mImePositionProcessor);
}
@@ -496,6 +586,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
if (!mInitialized) return;
mInitialized = false;
mSplitWindowManager.release(t);
+ removeTouchZones();
mDisplayImeController.removePositionProcessor(mImePositionProcessor);
mImePositionProcessor.reset();
if (mDividerFlingAnimator != null) {
@@ -519,6 +610,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mImePositionProcessor.reset();
}
mSplitWindowManager.init(this, mInsetsState, true /* isRestoring */);
+ populateTouchZones();
// Update the surface positions again after recreating the divider in case nothing else
// triggers it
mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this);
@@ -638,8 +730,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
updateBounds(mDividerPosition);
mWinToken1 = null;
mWinToken2 = null;
- mWinBounds1.setEmpty();
- mWinBounds2.setEmpty();
+ getTopLeftContentBounds().setEmpty();
+ getBottomRightContentBounds().setEmpty();
}
/**
@@ -761,6 +853,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
* DividerSnapAlgorithm will need to be refactored, and this function will change as well.
*/
public void flingDividerToOtherSide(@PersistentSnapPosition int currentSnapPosition) {
+ // If a fling animation is already running, just return.
+ if (mDividerFlingAnimator != null) return;
+
switch (currentSnapPosition) {
case SNAP_TO_2_10_90 ->
snapToTarget(mDividerPosition, mDividerSnapAlgorithm.getLastSplitTarget(),
@@ -835,7 +930,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
insets.left != 0 || insets.top != 0 || insets.right != 0 || insets.bottom != 0;
final int dividerPos = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
- mIsLeftRightSplit ? mBounds2.width() : mBounds2.height()).position;
+ mIsLeftRightSplit ? getBottomRightBounds().width() : getBottomRightBounds().height()
+ ).position;
final Rect endBounds1 = new Rect();
final Rect endBounds2 = new Rect();
final Rect endDividerBounds = new Rect();
@@ -847,12 +943,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
endBounds2.offset(-mRootBounds.left, -mRootBounds.top);
endDividerBounds.offset(-mRootBounds.left, -mRootBounds.top);
- ValueAnimator animator1 = moveSurface(t, topLeftStage, getRefBounds1(), endBounds1,
+ ValueAnimator animator1 = moveSurface(t, topLeftStage, getTopLeftRefBounds(), endBounds1,
-insets.left, -insets.top, true /* roundCorners */, true /* isGoingBehind */,
shouldVeil);
- ValueAnimator animator2 = moveSurface(t, bottomRightStage, getRefBounds2(), endBounds2,
- insets.left, insets.top, true /* roundCorners */, false /* isGoingBehind */,
- shouldVeil);
+ ValueAnimator animator2 = moveSurface(t, bottomRightStage, getBottomRightRefBounds(),
+ endBounds2, insets.left, insets.top, true /* roundCorners */,
+ false /* isGoingBehind */, shouldVeil);
ValueAnimator animator3 = moveSurface(t, null /* stage */, getRefDividerBounds(),
endDividerBounds, 0 /* offsetX */, 0 /* offsetY */, false /* roundCorners */,
false /* isGoingBehind */, false /* addVeil */);
@@ -996,9 +1092,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
// Set layers
if (taskInfo != null) {
- t.setLayer(leash, isGoingBehind ? BEHIND_APP_LAYER : FRONT_APP_LAYER);
+ t.setLayer(leash, isGoingBehind
+ ? ANIMATING_BACK_APP_LAYER
+ : ANIMATING_FRONT_APP_LAYER);
} else {
- t.setLayer(leash, DIVIDER_LAYER);
+ t.setLayer(leash, ANIMATING_DIVIDER_LAYER);
}
if (offsetX == 0 && offsetY == 0) {
@@ -1057,12 +1155,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
getRefDividerBounds(mTempRect);
t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
// Resets layer of divider bar to make sure it is always on top.
- t.setLayer(dividerLeash, Integer.MAX_VALUE);
+ t.setLayer(dividerLeash, RESTING_DIVIDER_LAYER);
}
- getRefBounds1(mTempRect);
+ copyTopLeftRefBounds(mTempRect);
t.setPosition(leash1, mTempRect.left, mTempRect.top)
.setWindowCrop(leash1, mTempRect.width(), mTempRect.height());
- getRefBounds2(mTempRect);
+ copyBottomRightRefBounds(mTempRect);
t.setPosition(leash2, mTempRect.left, mTempRect.top)
.setWindowCrop(leash2, mTempRect.width(), mTempRect.height());
@@ -1084,15 +1182,17 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
public boolean applyTaskChanges(WindowContainerTransaction wct,
ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) {
boolean boundsChanged = false;
- if (!mBounds1.equals(mWinBounds1) || !task1.token.equals(mWinToken1)) {
- setTaskBounds(wct, task1, mBounds1);
- mWinBounds1.set(mBounds1);
+ if (!getTopLeftBounds().equals(getTopLeftContentBounds())
+ || !task1.token.equals(mWinToken1)) {
+ setTaskBounds(wct, task1, getTopLeftBounds());
+ getTopLeftContentBounds().set(getTopLeftBounds());
mWinToken1 = task1.token;
boundsChanged = true;
}
- if (!mBounds2.equals(mWinBounds2) || !task2.token.equals(mWinToken2)) {
- setTaskBounds(wct, task2, mBounds2);
- mWinBounds2.set(mBounds2);
+ if (!getBottomRightBounds().equals(getBottomRightContentBounds())
+ || !task2.token.equals(mWinToken2)) {
+ setTaskBounds(wct, task2, getBottomRightBounds());
+ getBottomRightContentBounds().set(getBottomRightBounds());
mWinToken2 = task2.token;
boundsChanged = true;
}
@@ -1129,22 +1229,22 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
public void applyLayoutOffsetTarget(WindowContainerTransaction wct, int offsetX, int offsetY,
ActivityManager.RunningTaskInfo taskInfo1, ActivityManager.RunningTaskInfo taskInfo2) {
if (offsetX == 0 && offsetY == 0) {
- wct.setBounds(taskInfo1.token, mBounds1);
+ wct.setBounds(taskInfo1.token, getTopLeftBounds());
wct.setScreenSizeDp(taskInfo1.token,
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
- wct.setBounds(taskInfo2.token, mBounds2);
+ wct.setBounds(taskInfo2.token, getBottomRightBounds());
wct.setScreenSizeDp(taskInfo2.token,
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
} else {
- getBounds1(mTempRect);
+ copyTopLeftBounds(mTempRect);
mTempRect.offset(offsetX, offsetY);
wct.setBounds(taskInfo1.token, mTempRect);
wct.setScreenSizeDp(taskInfo1.token,
taskInfo1.configuration.screenWidthDp,
taskInfo1.configuration.screenHeightDp);
- getBounds2(mTempRect);
+ copyBottomRightBounds(mTempRect);
mTempRect.offset(offsetX, offsetY);
wct.setBounds(taskInfo2.token, mTempRect);
wct.setScreenSizeDp(taskInfo2.token,
@@ -1162,9 +1262,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
pw.println(innerPrefix + "mFreezeDividerWindow=" + mFreezeDividerWindow);
pw.println(innerPrefix + "mDimNonImeSide=" + mDimNonImeSide);
pw.println(innerPrefix + "mDividerPosition=" + mDividerPosition);
- pw.println(innerPrefix + "bounds1=" + mBounds1.toShortString());
+ pw.println(innerPrefix + "bounds1=" + getTopLeftBounds().toShortString());
pw.println(innerPrefix + "dividerBounds=" + mDividerBounds.toShortString());
- pw.println(innerPrefix + "bounds2=" + mBounds2.toShortString());
+ pw.println(innerPrefix + "bounds2=" + getBottomRightBounds().toShortString());
}
/** Handles layout change event. */
@@ -1274,15 +1374,16 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
}
final boolean topLeftShrink = isLeftRightSplit
- ? position < mWinBounds1.right : position < mWinBounds1.bottom;
+ ? position < getTopLeftContentBounds().right
+ : position < getTopLeftContentBounds().bottom;
if (topLeftShrink) {
mShrinkSide = isLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP;
- mContentBounds.set(mWinBounds1);
- mSurfaceBounds.set(mBounds1);
+ mContentBounds.set(getTopLeftContentBounds());
+ mSurfaceBounds.set(getTopLeftBounds());
} else {
mShrinkSide = isLeftRightSplit ? DOCKED_RIGHT : DOCKED_BOTTOM;
- mContentBounds.set(mWinBounds2);
- mSurfaceBounds.set(mBounds2);
+ mContentBounds.set(getBottomRightContentBounds());
+ mSurfaceBounds.set(getBottomRightBounds());
}
if (mDismissingSide != DOCKED_INVALID) {
@@ -1334,12 +1435,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
case DOCKED_TOP:
case DOCKED_LEFT:
targetLeash = leash1;
- mTempRect.set(mBounds1);
+ mTempRect.set(getTopLeftBounds());
break;
case DOCKED_BOTTOM:
case DOCKED_RIGHT:
targetLeash = leash2;
- mTempRect.set(mBounds2);
+ mTempRect.set(getBottomRightBounds());
break;
}
} else if (mParallaxType == PARALLAX_ALIGN_CENTER) {
@@ -1347,12 +1448,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
case DOCKED_TOP:
case DOCKED_LEFT:
targetLeash = leash1;
- mTempRect.set(mBounds1);
+ mTempRect.set(getTopLeftBounds());
break;
case DOCKED_BOTTOM:
case DOCKED_RIGHT:
targetLeash = leash2;
- mTempRect.set(mBounds2);
+ mTempRect.set(getBottomRightBounds());
break;
}
}
@@ -1530,7 +1631,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
private int getTargetYOffset() {
final int desireOffset = Math.abs(mEndImeTop - mStartImeTop);
// Make sure to keep at least 30% visible for the top split.
- final int maxOffset = (int) (mBounds1.height() * ADJUSTED_SPLIT_FRACTION_MAX);
+ final int maxOffset = (int) (getTopLeftBounds().height() * ADJUSTED_SPLIT_FRACTION_MAX);
return -Math.min(desireOffset, maxOffset);
}
@@ -1580,11 +1681,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
t.setPosition(dividerLeash, mTempRect.left, mTempRect.top);
}
- getRefBounds1(mTempRect);
+ copyTopLeftRefBounds(mTempRect);
mTempRect.offset(0, mYOffsetForIme);
t.setPosition(leash1, mTempRect.left, mTempRect.top);
- getRefBounds2(mTempRect);
+ copyBottomRightRefBounds(mTempRect);
mTempRect.offset(0, mYOffsetForIme);
t.setPosition(leash2, mTempRect.left, mTempRect.top);
adjusted = true;
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 c5f19742c803..89573ccef24b 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
@@ -67,6 +67,8 @@ public final class SplitWindowManager extends WindowlessWindowManager {
public interface ParentContainerCallbacks {
void attachToParentSurface(SurfaceControl.Builder b);
void onLeashReady(SurfaceControl leash);
+ /** Inflates the given touch zone on the appropriate stage root. */
+ void inflateOnStageRoot(OffscreenTouchZone touchZone);
}
public SplitWindowManager(String windowName, Context context, Configuration config,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 02df38e03d7c..60237502007d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -636,7 +636,7 @@ public abstract class WMShellBaseModule {
static Optional<FreeformComponents> provideFreeformComponents(
@DynamicOverride Optional<FreeformComponents> freeformComponents,
Context context) {
- if (FreeformComponents.isFreeformEnabled(context)) {
+ if (FreeformComponents.requiresFreeformComponents(context)) {
return freeformComponents;
}
return Optional.empty();
@@ -992,7 +992,7 @@ public abstract class WMShellBaseModule {
// Lazy ensures that this provider will not be the cause the dependency is created
// when it will not be returned due to the condition below.
return desktopTasksController.flatMap((lazy) -> {
- if (DesktopModeStatus.canEnterDesktopMode(context)) {
+ if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
return Optional.of(lazy.get());
}
return Optional.empty();
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 96f80245c76c..9ec80ec48654 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
@@ -17,6 +17,7 @@
package com.android.wm.shell.dagger;
import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS;
+import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY;
import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_TASK_LIMIT;
import static android.window.DesktopModeFlags.ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS;
@@ -94,6 +95,7 @@ import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator;
import com.android.wm.shell.desktopmode.SpringDragToDesktopTransitionHandler;
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
+import com.android.wm.shell.desktopmode.compatui.SystemModalsTransitionHandler;
import com.android.wm.shell.desktopmode.education.AppHandleEducationController;
import com.android.wm.shell.desktopmode.education.AppHandleEducationFilter;
import com.android.wm.shell.desktopmode.education.AppToWebEducationController;
@@ -286,57 +288,15 @@ public abstract class WMShellModule {
@ShellBackgroundThread ShellExecutor bgExecutor,
ShellInit shellInit,
IWindowManager windowManager,
- ShellCommandHandler shellCommandHandler,
ShellTaskOrganizer taskOrganizer,
- @DynamicOverride DesktopRepository desktopRepository,
DisplayController displayController,
- ShellController shellController,
- DisplayInsetsController displayInsetsController,
SyncTransactionQueue syncQueue,
Transitions transitions,
- Optional<DesktopTasksController> desktopTasksController,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- InteractionJankMonitor interactionJankMonitor,
- AppToWebGenericLinksParser genericLinksParser,
- AssistContentRequester assistContentRequester,
- MultiInstanceHelper multiInstanceHelper,
- Optional<DesktopTasksLimiter> desktopTasksLimiter,
- AppHandleEducationController appHandleEducationController,
- AppToWebEducationController appToWebEducationController,
- WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
- Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger) {
- if (DesktopModeStatus.canEnterDesktopMode(context)) {
- return new DesktopModeWindowDecorViewModel(
- context,
- mainExecutor,
- mainHandler,
- mainChoreographer,
- bgExecutor,
- shellInit,
- shellCommandHandler,
- windowManager,
- taskOrganizer,
- desktopRepository,
- displayController,
- shellController,
- displayInsetsController,
- syncQueue,
- transitions,
- desktopTasksController,
- rootTaskDisplayAreaOrganizer,
- interactionJankMonitor,
- genericLinksParser,
- assistContentRequester,
- multiInstanceHelper,
- desktopTasksLimiter,
- appHandleEducationController,
- appToWebEducationController,
- windowDecorCaptionHandleRepository,
- desktopActivityOrientationHandler,
- focusTransitionObserver,
- desktopModeEventLogger);
+ Optional<DesktopModeWindowDecorViewModel> desktopModeWindowDecorViewModel) {
+ if (desktopModeWindowDecorViewModel.isPresent()) {
+ return desktopModeWindowDecorViewModel.get();
}
return new CaptionWindowDecorViewModel(
context,
@@ -406,7 +366,7 @@ public abstract class WMShellModule {
Optional<TaskChangeListener> taskChangeListener) {
// TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
// override for this controller from the base module
- ShellInit init = FreeformComponents.isFreeformEnabled(context) ? shellInit : null;
+ ShellInit init = FreeformComponents.requiresFreeformComponents(context) ? shellInit : null;
return new FreeformTaskListener(
context,
init,
@@ -847,7 +807,7 @@ public abstract class WMShellModule {
DisplayController displayController,
ShellTaskOrganizer shellTaskOrganizer,
ShellCommandHandler shellCommandHandler) {
- if (DesktopModeStatus.canEnterDesktopMode(context)) {
+ if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
return Optional.of(
new DesktopImmersiveController(
shellInit,
@@ -908,7 +868,7 @@ public abstract class WMShellModule {
Context context,
@ShellMainThread ShellExecutor shellExecutor,
@ShellMainThread Handler mainHandler,
- Choreographer mainChoreographer,
+ @ShellMainThread Choreographer mainChoreographer,
@ShellBackgroundThread ShellExecutor bgExecutor,
ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
@@ -934,7 +894,7 @@ public abstract class WMShellModule {
FocusTransitionObserver focusTransitionObserver,
DesktopModeEventLogger desktopModeEventLogger
) {
- if (!DesktopModeStatus.canEnterDesktopMode(context)) {
+ if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
return Optional.empty();
}
return Optional.of(new DesktopModeWindowDecorViewModel(context, shellExecutor, mainHandler,
@@ -950,6 +910,26 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
+ static Optional<SystemModalsTransitionHandler> provideSystemModalsTransitionHandler(
+ Context context,
+ @ShellMainThread ShellExecutor mainExecutor,
+ @ShellAnimationThread ShellExecutor animExecutor,
+ ShellInit shellInit,
+ Transitions transitions,
+ @DynamicOverride DesktopRepository desktopRepository) {
+ if (!DesktopModeStatus.canEnterDesktopMode(context)
+ || !ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue()
+ || !Flags.enableDesktopSystemDialogsTransitions()) {
+ return Optional.empty();
+ }
+ return Optional.of(
+ new SystemModalsTransitionHandler(
+ context, mainExecutor, animExecutor, shellInit, transitions,
+ desktopRepository));
+ }
+
+ @WMSingleton
+ @Provides
static EnterDesktopTaskTransitionHandler provideEnterDesktopModeTaskTransitionHandler(
Transitions transitions,
Optional<DesktopTasksLimiter> desktopTasksLimiter,
@@ -1074,7 +1054,8 @@ public abstract class WMShellModule {
ShellInit shellInit,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
) {
- if (!DesktopModeStatus.canEnterDesktopMode(context)) {
+ if (!DesktopModeStatus.canEnterDesktopMode(context)
+ && !DesktopModeStatus.overridesShowAppHandle(context)) {
return Optional.empty();
}
return Optional.of(
@@ -1303,7 +1284,8 @@ public abstract class WMShellModule {
@NonNull LetterboxCommandHandler letterboxCommandHandler,
Optional<DesktopTasksTransitionObserver> desktopTasksTransitionObserverOptional,
Optional<DesktopDisplayEventHandler> desktopDisplayEventHandler,
- Optional<DesktopModeKeyGestureHandler> desktopModeKeyGestureHandler) {
+ Optional<DesktopModeKeyGestureHandler> desktopModeKeyGestureHandler,
+ Optional<SystemModalsTransitionHandler> systemModalsTransitionHandler) {
return new Object();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index 1acde73e68dc..4723eb273988 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -119,7 +119,8 @@ class DesktopImmersiveController(
)
}
- fun moveTaskToNonImmersive(taskInfo: RunningTaskInfo) {
+ /** Starts a transition to move an immersive task out of immersive. */
+ fun moveTaskToNonImmersive(taskInfo: RunningTaskInfo, reason: ExitReason) {
if (inProgress) {
logV(
"Cannot start exit because transition(s) already in progress: %s",
@@ -131,7 +132,7 @@ class DesktopImmersiveController(
val wct = WindowContainerTransaction().apply {
setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
}
- logV("Moving task ${taskInfo.taskId} out of immersive mode")
+ logV("Moving task %d out of immersive mode, reason: %s", taskInfo.taskId, reason)
val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ this)
state = TransitionState(
transition = transition,
@@ -151,10 +152,11 @@ class DesktopImmersiveController(
fun exitImmersiveIfApplicable(
transition: IBinder,
wct: WindowContainerTransaction,
- displayId: Int
+ displayId: Int,
+ reason: ExitReason,
) {
if (!Flags.enableFullyImmersiveInDesktop()) return
- val result = exitImmersiveIfApplicable(wct, displayId)
+ val result = exitImmersiveIfApplicable(wct, displayId, excludeTaskId = null, reason)
result.asExit()?.runOnTransitionStart?.invoke(transition)
}
@@ -170,6 +172,7 @@ class DesktopImmersiveController(
wct: WindowContainerTransaction,
displayId: Int,
excludeTaskId: Int? = null,
+ reason: ExitReason,
): ExitResult {
if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId)
@@ -179,7 +182,10 @@ class DesktopImmersiveController(
}
val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask)
?: return ExitResult.NoExit
- logV("Appending immersive exit for task: $immersiveTask in display: $displayId")
+ logV(
+ "Appending immersive exit for task: %d in display: %d for reason: %s",
+ immersiveTask, displayId, reason
+ )
wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
return ExitResult.Exit(
exitingTask = immersiveTask,
@@ -198,14 +204,15 @@ class DesktopImmersiveController(
*/
fun exitImmersiveIfApplicable(
wct: WindowContainerTransaction,
- taskInfo: RunningTaskInfo
+ taskInfo: RunningTaskInfo,
+ reason: ExitReason,
): ExitResult {
if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
if (desktopRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
// A full immersive task is being minimized, make sure the immersive state is broken
// (i.e. resize back to max bounds).
wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
- logV("Appending immersive exit for task: ${taskInfo.taskId}")
+ logV("Appending immersive exit for task: %d for reason: %s", taskInfo.taskId, reason)
return ExitResult.Exit(
exitingTask = taskInfo.taskId,
runOnTransitionStart = { transition ->
@@ -550,6 +557,15 @@ class DesktopImmersiveController(
ENTER, EXIT
}
+ /** The reason for moving the task out of desktop immersive mode. */
+ enum class ExitReason {
+ APP_NOT_IMMERSIVE, // The app stopped requesting immersive treatment.
+ USER_INTERACTION, // Explicit user intent request, e.g. a button click.
+ TASK_LAUNCH, // A task launched/moved on top of the immersive task.
+ MINIMIZED, // The immersive task was minimized.
+ CLOSED, // The immersive task was closed.
+ }
+
private fun logV(msg: String, vararg arguments: Any?) {
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index 39586e39fdd4..b4eac7a7b2d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -187,8 +187,10 @@ class DesktopModeEventLogger {
*/
fun logTaskResizingStarted(
resizeTrigger: ResizeTrigger,
- motionEvent: MotionEvent?,
+ inputMethod: InputMethod,
taskInfo: RunningTaskInfo,
+ taskWidth: Int? = null,
+ taskHeight: Int? = null,
displayController: DisplayController? = null,
displayLayoutSize: Size? = null,
) {
@@ -205,8 +207,10 @@ class DesktopModeEventLogger {
val taskSizeUpdate = createTaskSizeUpdate(
resizeTrigger,
- motionEvent,
+ inputMethod,
taskInfo,
+ taskWidth,
+ taskHeight,
displayController = displayController,
displayLayoutSize = displayLayoutSize,
)
@@ -228,10 +232,10 @@ class DesktopModeEventLogger {
*/
fun logTaskResizingEnded(
resizeTrigger: ResizeTrigger,
- motionEvent: MotionEvent?,
+ inputMethod: InputMethod,
taskInfo: RunningTaskInfo,
- taskHeight: Int? = null,
taskWidth: Int? = null,
+ taskHeight: Int? = null,
displayController: DisplayController? = null,
displayLayoutSize: Size? = null,
) {
@@ -248,10 +252,10 @@ class DesktopModeEventLogger {
val taskSizeUpdate = createTaskSizeUpdate(
resizeTrigger,
- motionEvent,
+ inputMethod,
taskInfo,
- taskHeight,
taskWidth,
+ taskHeight,
displayController,
displayLayoutSize,
)
@@ -271,10 +275,10 @@ class DesktopModeEventLogger {
private fun createTaskSizeUpdate(
resizeTrigger: ResizeTrigger,
- motionEvent: MotionEvent?,
+ inputMethod: InputMethod,
taskInfo: RunningTaskInfo,
- taskHeight: Int? = null,
taskWidth: Int? = null,
+ taskHeight: Int? = null,
displayController: DisplayController? = null,
displayLayoutSize: Size? = null,
): TaskSizeUpdate {
@@ -292,7 +296,7 @@ class DesktopModeEventLogger {
return TaskSizeUpdate(
resizeTrigger,
- getInputMethodFromMotionEvent(motionEvent),
+ inputMethod,
taskInfo.taskId,
taskInfo.effectiveUid,
height,
@@ -442,7 +446,7 @@ class DesktopModeEventLogger {
val displayArea: Int?,
)
- private fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
+ fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
if (e == null) return InputMethod.UNKNOWN_INPUT_METHOD
val toolType = e.getToolType(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
index ac07eaa695c1..114563aa18bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
@@ -66,15 +66,13 @@ class DesktopModeKeyGestureHandler(
}
return true
}
- // TODO(b/375356876): Modify function to pass in keyboard shortcut as the input
- // method for logging task resize
KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW -> {
logV("Key gesture SNAP_LEFT_FREEFORM_WINDOW is handled")
getGloballyFocusedFreeformTask()?.let {
desktopModeWindowDecorViewModel.get().onSnapResize(
it.taskId,
true,
- null
+ DesktopModeEventLogger.Companion.InputMethod.KEYBOARD
)
}
return true
@@ -85,7 +83,7 @@ class DesktopModeKeyGestureHandler(
desktopModeWindowDecorViewModel.get().onSnapResize(
it.taskId,
false,
- null
+ DesktopModeEventLogger.Companion.InputMethod.KEYBOARD
)
}
return true
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 0a39076a8768..ccbc9204ad9d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -70,6 +70,7 @@ import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags
+import com.android.wm.shell.Flags.enableFlexibleSplit
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
@@ -102,6 +103,7 @@ import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.useDesktopOverrideDensity
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
import com.android.wm.shell.splitscreen.SplitScreenController
@@ -126,10 +128,13 @@ import java.io.PrintWriter
import java.util.Optional
import java.util.concurrent.Executor
import java.util.function.Consumer
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.Companion.DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS
import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION
import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler.FULLSCREEN_ANIMATION_DURATION
+import com.android.wm.shell.recents.RecentsTransitionStateListener.RecentsTransitionState
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING
/** Handles moving tasks in and out of desktop */
class DesktopTasksController(
@@ -206,7 +211,9 @@ class DesktopTasksController(
val draggingTaskId
get() = dragToDesktopTransitionHandler.draggingTaskId
- private var recentsAnimationRunning = false
+ @RecentsTransitionState
+ private var recentsTransitionState = TRANSITION_STATE_NOT_RUNNING
+
private lateinit var splitScreenController: SplitScreenController
lateinit var freeformTaskTransitionStarter: FreeformTaskTransitionStarter
// Launch cookie used to identify a drag and drop transition to fullscreen after it has begun.
@@ -235,10 +242,15 @@ class DesktopTasksController(
dragToDesktopTransitionHandler.dragToDesktopStateListener = dragToDesktopStateListener
recentsTransitionHandler.addTransitionStateListener(
object : RecentsTransitionStateListener {
- override fun onAnimationStateChanged(running: Boolean) {
- logV("Recents animation state changed running=%b", running)
- recentsAnimationRunning = running
- desktopTilingDecorViewModel.onOverviewAnimationStateChange(running)
+ override fun onTransitionStateChanged(@RecentsTransitionState state: Int) {
+ logV(
+ "Recents transition state changed: %s",
+ RecentsTransitionStateListener.stateToString(state)
+ )
+ recentsTransitionState = state
+ desktopTilingDecorViewModel.onOverviewAnimationStateChange(
+ RecentsTransitionStateListener.isAnimating(state)
+ )
}
}
)
@@ -378,6 +390,7 @@ class DesktopTasksController(
wct = wct,
displayId = DEFAULT_DISPLAY,
excludeTaskId = taskId,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
wct.startTask(
taskId,
@@ -410,6 +423,7 @@ class DesktopTasksController(
wct = wct,
displayId = task.displayId,
excludeTaskId = task.taskId,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
// Bring other apps to front first
val taskIdToMinimize =
@@ -457,7 +471,11 @@ class DesktopTasksController(
bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
addMoveToDesktopChanges(wct, taskInfo)
val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
- wct, taskInfo.displayId)
+ wct = wct,
+ displayId = taskInfo.displayId,
+ excludeTaskId = null,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH
+ )
val transition = dragToDesktopTransitionHandler.finishDragToDesktopTransition(wct)
desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS.toInt()
@@ -505,8 +523,11 @@ class DesktopTasksController(
taskId
)
)
- return desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo).asExit()
- ?.runOnTransitionStart
+ return desktopImmersiveController.exitImmersiveIfApplicable(
+ wct = wct,
+ taskInfo = taskInfo,
+ reason = DesktopImmersiveController.ExitReason.CLOSED
+ ).asExit()?.runOnTransitionStart
}
fun minimizeTask(taskInfo: RunningTaskInfo) {
@@ -515,7 +536,11 @@ class DesktopTasksController(
val wct = WindowContainerTransaction()
performDesktopExitCleanupIfNeeded(taskId, wct)
// Notify immersive handler as it might need to exit immersive state.
- val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)
+ val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
+ wct = wct,
+ taskInfo = taskInfo,
+ reason = DesktopImmersiveController.ExitReason.MINIMIZED
+ )
wct.reorder(taskInfo.token, false)
val transition = freeformTaskTransitionStarter.startMinimizedModeTransition(wct)
@@ -672,6 +697,7 @@ class DesktopTasksController(
wct = wct,
displayId = displayId,
excludeTaskId = launchingTaskId,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
if (remoteTransition == null) {
val t = desktopMixedTransitionHandler.startLaunchTransition(
@@ -763,7 +789,10 @@ class DesktopTasksController(
/** Moves a task in/out of full immersive state within the desktop. */
fun toggleDesktopTaskFullImmersiveState(taskInfo: RunningTaskInfo) {
if (taskRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
- exitDesktopTaskFromFullImmersive(taskInfo)
+ exitDesktopTaskFromFullImmersive(
+ taskInfo,
+ DesktopImmersiveController.ExitReason.USER_INTERACTION,
+ )
} else {
moveDesktopTaskToFullImmersive(taskInfo)
}
@@ -774,9 +803,12 @@ class DesktopTasksController(
desktopImmersiveController.moveTaskToImmersive(taskInfo)
}
- private fun exitDesktopTaskFromFullImmersive(taskInfo: RunningTaskInfo) {
+ private fun exitDesktopTaskFromFullImmersive(
+ taskInfo: RunningTaskInfo,
+ reason: DesktopImmersiveController.ExitReason,
+ ) {
check(taskInfo.isFreeform) { "Task must already be in freeform" }
- desktopImmersiveController.moveTaskToNonImmersive(taskInfo)
+ desktopImmersiveController.moveTaskToNonImmersive(taskInfo, reason)
}
/**
@@ -789,14 +821,19 @@ class DesktopTasksController(
resizeTrigger: ResizeTrigger,
motionEvent: MotionEvent?,
) {
+ val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
desktopModeEventLogger.logTaskResizingStarted(
- resizeTrigger, motionEvent, taskInfo, displayController
+ resizeTrigger,
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ taskInfo,
+ currentTaskBounds.width(),
+ currentTaskBounds.height(),
+ displayController
)
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
- val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
val destinationBounds = Rect()
val isMaximized = isTaskMaximized(taskInfo, stableBounds)
@@ -840,8 +877,9 @@ class DesktopTasksController(
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding)
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
desktopModeEventLogger.logTaskResizingEnded(
- resizeTrigger, motionEvent, taskInfo, destinationBounds.height(),
- destinationBounds.width(), displayController
+ resizeTrigger, DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ taskInfo, destinationBounds.width(),
+ destinationBounds.height(), displayController
)
toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
}
@@ -962,11 +1000,26 @@ class DesktopTasksController(
currentDragBounds: Rect,
position: SnapPosition,
resizeTrigger: ResizeTrigger,
- motionEvent: MotionEvent?,
+ inputMethod: InputMethod,
desktopWindowDecoration: DesktopModeWindowDecoration,
) {
desktopModeEventLogger.logTaskResizingStarted(
- resizeTrigger, motionEvent, taskInfo, displayController
+ resizeTrigger,
+ inputMethod,
+ taskInfo,
+ currentDragBounds.width(),
+ currentDragBounds.height(),
+ displayController
+ )
+
+ val destinationBounds = getSnapBounds(taskInfo, position)
+ desktopModeEventLogger.logTaskResizingEnded(
+ resizeTrigger,
+ inputMethod,
+ taskInfo,
+ destinationBounds.width(),
+ destinationBounds.height(),
+ displayController,
)
if (DesktopModeFlags.ENABLE_TILE_RESIZING.isTrue()) {
@@ -981,15 +1034,7 @@ class DesktopTasksController(
}
return
}
- val destinationBounds = getSnapBounds(taskInfo, position)
- desktopModeEventLogger.logTaskResizingEnded(
- resizeTrigger,
- motionEvent,
- taskInfo,
- destinationBounds.height(),
- destinationBounds.width(),
- displayController,
- )
+
if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) {
// Handle the case where we attempt to snap resize when already snap resized: the task
// position won't need to change but we want to animate the surface going back to the
@@ -1019,7 +1064,7 @@ class DesktopTasksController(
taskInfo: RunningTaskInfo,
position: SnapPosition,
resizeTrigger: ResizeTrigger,
- motionEvent: MotionEvent? = null,
+ inputMethod: InputMethod,
desktopModeWindowDecoration: DesktopModeWindowDecoration,
) {
if (!isSnapResizingAllowed(taskInfo)) {
@@ -1037,7 +1082,7 @@ class DesktopTasksController(
taskInfo.configuration.windowConfiguration.bounds,
position,
resizeTrigger,
- motionEvent,
+ inputMethod,
desktopModeWindowDecoration
)
}
@@ -1088,7 +1133,7 @@ class DesktopTasksController(
currentDragBounds,
position,
resizeTrigger,
- motionEvent,
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
desktopModeWindowDecoration,
)
}
@@ -1289,6 +1334,8 @@ class DesktopTasksController(
// Check if we should skip handling this transition
var reason = ""
val triggerTask = request.triggerTask
+ val recentsAnimationRunning =
+ RecentsTransitionStateListener.isAnimating(recentsTransitionState)
var shouldHandleMidRecentsFreeformLaunch =
recentsAnimationRunning && isFreeformRelaunch(triggerTask, request)
val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask)
@@ -1476,6 +1523,7 @@ class DesktopTasksController(
wct = wct,
displayId = callingTask.displayId,
excludeTaskId = requestedTaskId,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
val transition = transitions.startTransition(TRANSIT_OPEN, wct, null)
taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
@@ -1512,11 +1560,15 @@ class DesktopTasksController(
WINDOWING_MODE_MULTI_WINDOW -> {
val splitPosition = splitScreenController
.determineNewInstancePosition(callingTaskInfo)
+ // TODO(b/349828130) currently pass in index_undefined until we can revisit these
+ // specific cases in the future.
+ val splitIndex = if (enableFlexibleSplit())
+ splitScreenController.determineNewInstanceIndex(callingTaskInfo) else
+ SPLIT_INDEX_UNDEFINED
splitScreenController.startIntent(
launchIntent, context.userId, fillIn, splitPosition,
options.toBundle(), null /* hideTaskToken */,
- true /* forceLaunchNewTask */
- )
+ true /* forceLaunchNewTask */, splitIndex)
}
WINDOWING_MODE_FREEFORM -> {
val wct = WindowContainerTransaction()
@@ -1621,7 +1673,12 @@ class DesktopTasksController(
}
// Desktop Mode is showing and we're launching a new Task:
// 1) Exit immersive if needed.
- desktopImmersiveController.exitImmersiveIfApplicable(transition, wct, task.displayId)
+ desktopImmersiveController.exitImmersiveIfApplicable(
+ transition = transition,
+ wct = wct,
+ displayId = task.displayId,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
+ )
// 2) minimize a Task if needed.
val taskIdToMinimize = addAndGetMinimizeChanges(task.displayId, wct, task.taskId)
addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
@@ -1646,8 +1703,11 @@ class DesktopTasksController(
return WindowContainerTransaction().also { wct ->
addMoveToDesktopChanges(wct, task)
// In some launches home task is moved behind new task being launched. Make sure
- // that's not the case for launches in desktop.
- if (task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0) {
+ // that's not the case for launches in desktop. Also, if this launch is the first
+ // one to trigger the desktop mode (e.g., when [forceEnterDesktop()]), activate the
+ // desktop mode here.
+ if (task.baseIntent.flags.and(Intent.FLAG_ACTIVITY_TASK_ON_HOME) != 0
+ || !isDesktopModeShowing(task.displayId)) {
bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
wct.reorder(task.token, true)
}
@@ -1658,9 +1718,19 @@ class DesktopTasksController(
taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize)
desktopImmersiveController.exitImmersiveIfApplicable(
- transition, wct, task.displayId
+ transition,
+ wct,
+ task.displayId,
+ reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH
)
}
+ } else if (taskRepository.isActiveTask(task.taskId)) {
+ // If a freeform task receives a request for a fullscreen launch, apply the same
+ // changes we do for similar transitions. The task not having WINDOWING_MODE_UNDEFINED
+ // set when needed can interfere with future split / multi-instance transitions.
+ return WindowContainerTransaction().also { wct ->
+ addMoveToFullscreenChanges(wct, task)
+ }
}
return null
}
@@ -2268,9 +2338,13 @@ class DesktopTasksController(
if (!Flags.enableFullyImmersiveInDesktop()) return
val inImmersive = taskRepository.isTaskInFullImmersiveState(taskInfo.taskId)
val requestingImmersive = taskInfo.requestingImmersive
- if (inImmersive && !requestingImmersive) {
+ if (inImmersive && !requestingImmersive
+ && !RecentsTransitionStateListener.isRunning(recentsTransitionState)) {
// Exit immersive if the app is no longer requesting it.
- exitDesktopTaskFromFullImmersive(taskInfo)
+ exitDesktopTaskFromFullImmersive(
+ taskInfo,
+ DesktopImmersiveController.ExitReason.APP_NOT_IMMERSIVE
+ )
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
new file mode 100644
index 000000000000..826de08557bd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandler.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode.compatui
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.os.IBinder
+import android.view.Display.DEFAULT_DISPLAY
+import android.view.SurfaceControl
+import android.window.TransitionInfo
+import android.window.TransitionRequestInfo
+import android.window.WindowContainerTransaction
+import androidx.core.animation.addListener
+import com.android.app.animation.Interpolators
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
+import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.shared.TransitionUtil.isClosingMode
+import com.android.wm.shell.shared.TransitionUtil.isClosingType
+import com.android.wm.shell.shared.TransitionUtil.isOpeningMode
+import com.android.wm.shell.shared.TransitionUtil.isOpeningType
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TransitionHandler
+
+/** Handles transitions related to system modals, e.g. launch and close transitions. */
+class SystemModalsTransitionHandler(
+ private val context: Context,
+ private val mainExecutor: ShellExecutor,
+ private val animExecutor: ShellExecutor,
+ private val shellInit: ShellInit,
+ private val transitions: Transitions,
+ private val desktopRepository: DesktopRepository,
+) : TransitionHandler {
+
+ private val showingSystemModalsIds = mutableSetOf<Int>()
+
+ init {
+ shellInit.addInitCallback({ transitions.addHandler(this) }, this)
+ }
+
+ override fun startAnimation(
+ transition: IBinder,
+ info: TransitionInfo,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction,
+ finishCallback: Transitions.TransitionFinishCallback,
+ ): Boolean {
+ if (!isDesktopModeShowing(DEFAULT_DISPLAY)) return false
+ if (isOpeningType(info.type)) {
+ val launchChange = getLaunchingSystemModal(info) ?: return false
+ val taskInfo = launchChange.taskInfo
+ requireNotNull(taskInfo)
+ logV("Animating system modal launch: taskId=%d", taskInfo.taskId)
+ showingSystemModalsIds.add(taskInfo.taskId)
+ animateSystemModal(
+ launchChange.leash,
+ startTransaction,
+ finishTransaction,
+ finishCallback,
+ /* toShow= */ true,
+ )
+ return true
+ }
+ if (isClosingType(info.type)) {
+ val closeChange = getClosingSystemModal(info) ?: return false
+ val taskInfo = closeChange.taskInfo
+ requireNotNull(taskInfo)
+ logV("Animating system modal close: taskId=%d", taskInfo.taskId)
+ showingSystemModalsIds.remove(taskInfo.taskId)
+ animateSystemModal(
+ closeChange.leash,
+ startTransaction,
+ finishTransaction,
+ finishCallback,
+ /* toShow= */ false,
+ )
+ return true
+ }
+ return false
+ }
+
+ private fun animateSystemModal(
+ leash: SurfaceControl,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction,
+ finishCallback: Transitions.TransitionFinishCallback,
+ toShow: Boolean, // Whether to show or to hide the system modal
+ ) {
+ val startAlpha = if (toShow) 0f else 1f
+ val endAlpha = if (toShow) 1f else 0f
+ val animator =
+ createAlphaAnimator(SurfaceControl.Transaction(), leash, startAlpha, endAlpha)
+ animator.addListener(
+ onEnd = { _ ->
+ mainExecutor.execute { finishCallback.onTransitionFinished(/* wct= */ null) }
+ }
+ )
+ if (toShow) {
+ finishTransaction.show(leash)
+ } else {
+ finishTransaction.hide(leash)
+ }
+ startTransaction.setAlpha(leash, startAlpha)
+ startTransaction.apply()
+ animExecutor.execute { animator.start() }
+ }
+
+ private fun getLaunchingSystemModal(info: TransitionInfo): TransitionInfo.Change? =
+ info.changes.find { change ->
+ if (!isOpeningMode(change.mode)) {
+ return@find false
+ }
+ val taskInfo = change.taskInfo ?: return@find false
+ return@find isTopActivityExemptFromDesktopWindowing(context, taskInfo)
+ }
+
+ private fun getClosingSystemModal(info: TransitionInfo): TransitionInfo.Change? =
+ info.changes.find { change ->
+ if (!isClosingMode(change.mode)) {
+ return@find false
+ }
+ val taskInfo = change.taskInfo ?: return@find false
+ return@find isTopActivityExemptFromDesktopWindowing(context, taskInfo) ||
+ showingSystemModalsIds.contains(taskInfo.taskId)
+ }
+
+ private fun createAlphaAnimator(
+ transaction: SurfaceControl.Transaction,
+ leash: SurfaceControl,
+ startVal: Float,
+ endVal: Float,
+ ): ValueAnimator =
+ ValueAnimator.ofFloat(startVal, endVal).apply {
+ duration = LAUNCH_ANIM_ALPHA_DURATION_MS
+ interpolator = Interpolators.LINEAR
+ addUpdateListener { animation ->
+ transaction.setAlpha(leash, animation.animatedValue as Float).apply()
+ }
+ }
+
+ private fun isDesktopModeShowing(displayId: Int): Boolean =
+ desktopRepository.getVisibleTaskCount(displayId) > 0
+
+ override fun handleRequest(
+ transition: IBinder,
+ request: TransitionRequestInfo,
+ ): WindowContainerTransaction? = null
+
+ private fun logV(msg: String, vararg arguments: Any?) {
+ ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ companion object {
+ private const val TAG = "SystemModalsTransitionHandler"
+ private const val LAUNCH_ANIM_ALPHA_DURATION_MS = 150L
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java
index 5d22c1edf8fe..ae9d21f621de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java
@@ -41,6 +41,9 @@ import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT
import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_TOP;
import static com.android.wm.shell.shared.draganddrop.DragAndDropConstants.EXTRA_DISALLOW_HIT_REGION;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_0;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_1;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -81,6 +84,7 @@ import com.android.wm.shell.draganddrop.anim.HoverAnimProps;
import com.android.wm.shell.draganddrop.anim.TwoFiftyFiftyTargetAnimator;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.split.SplitScreenConstants;
+import com.android.wm.shell.shared.split.SplitScreenConstants.SplitIndex;
import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -219,8 +223,10 @@ public class SplitDragPolicy implements DropTarget {
displayRegion.splitHorizontally(startHitRegion, endHitRegion);
}
- mTargets.add(new Target(TYPE_SPLIT_LEFT, startHitRegion, startBounds, -1));
- mTargets.add(new Target(TYPE_SPLIT_RIGHT, endHitRegion, endBounds, -1));
+ mTargets.add(new Target(TYPE_SPLIT_LEFT, startHitRegion, startBounds,
+ SPLIT_INDEX_0));
+ mTargets.add(new Target(TYPE_SPLIT_RIGHT, endHitRegion, endBounds,
+ SPLIT_INDEX_1));
} else {
// TODO(b/349828130), move this into init function and/or the insets updating
// callback
@@ -287,9 +293,10 @@ public class SplitDragPolicy implements DropTarget {
displayRegion.splitVertically(leftHitRegion, rightHitRegion);
}
- mTargets.add(new Target(TYPE_SPLIT_LEFT, leftHitRegion, topOrLeftBounds, -1));
+ mTargets.add(new Target(TYPE_SPLIT_LEFT, leftHitRegion, topOrLeftBounds,
+ SPLIT_INDEX_UNDEFINED));
mTargets.add(new Target(TYPE_SPLIT_RIGHT, rightHitRegion, bottomOrRightBounds,
- -1));
+ SPLIT_INDEX_UNDEFINED));
} else {
final Rect topHitRegion = new Rect();
final Rect bottomHitRegion = new Rect();
@@ -308,9 +315,10 @@ public class SplitDragPolicy implements DropTarget {
displayRegion.splitHorizontally(topHitRegion, bottomHitRegion);
}
- mTargets.add(new Target(TYPE_SPLIT_TOP, topHitRegion, topOrLeftBounds, -1));
+ mTargets.add(new Target(TYPE_SPLIT_TOP, topHitRegion, topOrLeftBounds,
+ SPLIT_INDEX_UNDEFINED));
mTargets.add(new Target(TYPE_SPLIT_BOTTOM, bottomHitRegion, bottomOrRightBounds,
- -1));
+ SPLIT_INDEX_UNDEFINED));
}
}
} else {
@@ -378,9 +386,9 @@ public class SplitDragPolicy implements DropTarget {
? mFullscreenStarter
: mSplitscreenStarter;
if (mSession.appData != null) {
- launchApp(mSession, starter, position, hideTaskToken);
+ launchApp(mSession, starter, position, hideTaskToken, target.index);
} else {
- launchIntent(mSession, starter, position, hideTaskToken);
+ launchIntent(mSession, starter, position, hideTaskToken, target.index);
}
if (enableFlexibleSplit()) {
@@ -392,9 +400,10 @@ public class SplitDragPolicy implements DropTarget {
* Launches an app provided by SysUI.
*/
private void launchApp(DragSession session, Starter starter, @SplitPosition int position,
- @Nullable WindowContainerToken hideTaskToken) {
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching app data at position=%d",
- position);
+ @Nullable WindowContainerToken hideTaskToken, @SplitIndex int splitIndex) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+ "Launching app data at position=%d index=%d",
+ position, splitIndex);
final ClipDescription description = session.getClipDescription();
final boolean isTask = description.hasMimeType(MIMETYPE_APPLICATION_TASK);
final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
@@ -429,7 +438,7 @@ public class SplitDragPolicy implements DropTarget {
}
}
starter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
- position, opts, hideTaskToken);
+ position, opts, hideTaskToken, splitIndex);
}
}
@@ -437,7 +446,7 @@ public class SplitDragPolicy implements DropTarget {
* Launches an intent sender provided by an application.
*/
private void launchIntent(DragSession session, Starter starter, @SplitPosition int position,
- @Nullable WindowContainerToken hideTaskToken) {
+ @Nullable WindowContainerToken hideTaskToken, @SplitIndex int index) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching intent at position=%d",
position);
final ActivityOptions baseActivityOpts = ActivityOptions.makeBasic();
@@ -452,7 +461,7 @@ public class SplitDragPolicy implements DropTarget {
final Bundle opts = baseActivityOpts.toBundle();
starter.startIntent(session.launchableIntent,
session.launchableIntent.getCreatorUserHandle().getIdentifier(),
- null /* fillIntent */, position, opts, hideTaskToken);
+ null /* fillIntent */, position, opts, hideTaskToken, index);
}
@Override
@@ -541,7 +550,7 @@ public class SplitDragPolicy implements DropTarget {
@Nullable Bundle options, UserHandle user);
void startIntent(PendingIntent intent, int userId, Intent fillInIntent,
@SplitPosition int position, @Nullable Bundle options,
- @Nullable WindowContainerToken hideTaskToken);
+ @Nullable WindowContainerToken hideTaskToken, @SplitIndex int index);
void enterSplitScreen(int taskId, boolean leftOrTop);
/**
@@ -592,7 +601,7 @@ public class SplitDragPolicy implements DropTarget {
@Override
public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
int position, @Nullable Bundle options,
- @Nullable WindowContainerToken hideTaskToken) {
+ @Nullable WindowContainerToken hideTaskToken, @SplitIndex int index) {
if (hideTaskToken != null) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
"Default starter does not support hide task token");
@@ -641,13 +650,13 @@ public class SplitDragPolicy implements DropTarget {
final Rect hitRegion;
// The approximate visual region for where the task will start
final Rect drawRegion;
- int index;
+ @SplitIndex int index;
/**
* @param index 0-indexed, represents which position of drop target this object represents,
* 0 to N for left to right, top to bottom
*/
- public Target(@Type int t, Rect hit, Rect draw, int index) {
+ public Target(@Type int t, Rect hit, Rect draw, @SplitIndex int index) {
type = t;
hitRegion = hit;
drawRegion = draw;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/anim/TwoFiftyFiftyTargetAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/anim/TwoFiftyFiftyTargetAnimator.kt
index 9f532f57961d..54619528f2bd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/anim/TwoFiftyFiftyTargetAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/anim/TwoFiftyFiftyTargetAnimator.kt
@@ -22,6 +22,10 @@ import android.graphics.Rect
import com.android.wm.shell.R
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.draganddrop.SplitDragPolicy.Target
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_0
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_1
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_2
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_3
/**
* Represents Drop Zone targets and animations for when the system is currently in a 2 app 50/50
@@ -98,7 +102,7 @@ class TwoFiftyFiftyTargetAnimator : DropTargetAnimSupplier {
farStartBounds.right + halfDividerWidth,
farStartBounds.bottom
),
- farStartBounds, 0
+ farStartBounds, SPLIT_INDEX_0
)
)
targets.add(
@@ -110,7 +114,7 @@ class TwoFiftyFiftyTargetAnimator : DropTargetAnimSupplier {
startBounds.right + halfDividerWidth,
startBounds.bottom
),
- startBounds, 1
+ startBounds, SPLIT_INDEX_1
)
)
targets.add(
@@ -120,7 +124,7 @@ class TwoFiftyFiftyTargetAnimator : DropTargetAnimSupplier {
endBounds.left - halfDividerWidth,
endBounds.top, endBounds.right, endBounds.bottom
),
- endBounds, 2
+ endBounds, SPLIT_INDEX_2
)
)
targets.add(
@@ -130,7 +134,7 @@ class TwoFiftyFiftyTargetAnimator : DropTargetAnimSupplier {
farEndBounds.left - halfDividerWidth,
farEndBounds.top, farEndBounds.right, farEndBounds.bottom
),
- farEndBounds, 3
+ farEndBounds, SPLIT_INDEX_3
)
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformComponents.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformComponents.java
index 3379ff2a8c30..24b74c636630 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformComponents.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformComponents.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.provider.Settings;
import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.transition.Transitions;
import java.util.Optional;
@@ -59,4 +60,12 @@ public class FreeformComponents {
|| Settings.Global.getInt(context.getContentResolver(),
DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
}
+
+ /**
+ * Freeform is enabled or we need the components to enable the app handle when desktop mode is
+ * not enabled
+ */
+ public static boolean requiresFreeformComponents(Context context) {
+ return isFreeformEnabled(context) || DesktopModeStatus.overridesShowAppHandle(context);
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index 18f9cc758e38..b6d19b657705 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -69,7 +69,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
mWindowDecorViewModel = windowDecorViewModel;
mTaskChangeListener = taskChangeListener;
mFocusTransitionObserver = focusTransitionObserver;
- if (FreeformComponents.isFreeformEnabled(context)) {
+ if (FreeformComponents.requiresFreeformComponents(context)) {
shellInit.addInitCallback(this::onInit, this);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index 319bfac734ba..e4f83333edbf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -173,6 +173,10 @@ public class KeyguardTransitionHandler
return mKeyguardShowing;
}
+ public boolean isKeyguardAnimating() {
+ return !mStartedTransitions.isEmpty();
+ }
+
@Override
public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
mDreamToken = taskInfo.getActivityType() == ACTIVITY_TYPE_DREAM ? taskInfo.token : null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 08e672790da6..2bcbe3013397 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -31,6 +31,7 @@ import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_RESIZE_PIP;
+import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PictureInPictureParams;
@@ -120,6 +121,8 @@ public class PipTransition extends PipTransitionController implements
@Nullable
private Transitions.TransitionFinishCallback mFinishCallback;
+ private ValueAnimator mTransitionAnimator;
+
public PipTransition(
Context context,
@NonNull ShellInit shellInit,
@@ -209,7 +212,12 @@ public class PipTransition extends PipTransitionController implements
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
- @NonNull Transitions.TransitionFinishCallback finishCallback) {}
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ // Just jump-cut the current animation if any, but do not merge.
+ if (info.getType() == TRANSIT_EXIT_PIP) {
+ end();
+ }
+ }
@Override
public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
@@ -271,6 +279,14 @@ public class PipTransition extends PipTransitionController implements
return false;
}
+ @Override
+ public void end() {
+ if (mTransitionAnimator != null && mTransitionAnimator.isRunning()) {
+ mTransitionAnimator.end();
+ mTransitionAnimator = null;
+ }
+ }
+
//
// Animation schedulers and entry points
//
@@ -400,7 +416,9 @@ public class PipTransition extends PipTransitionController implements
final SurfaceControl pipLeash = getLeash(pipChange);
final Rect startBounds = pipChange.getStartAbsBounds();
final Rect endBounds = pipChange.getEndAbsBounds();
- final PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams;
+ final PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams != null
+ ? pipChange.getTaskInfo().pictureInPictureParams
+ : new PictureInPictureParams.Builder().build();
final Rect adjustedSourceRectHint = getAdjustedSourceRectHint(info, pipChange,
pipActivityChange);
@@ -436,7 +454,7 @@ public class PipTransition extends PipTransitionController implements
}
finishTransition();
});
- animator.start();
+ cacheAndStartTransitionAnimator(animator);
return true;
}
@@ -536,7 +554,7 @@ public class PipTransition extends PipTransitionController implements
PipAlphaAnimator.FADE_IN);
// This should update the pip transition state accordingly after we stop playing.
animator.setAnimationEndCallback(this::finishTransition);
- animator.start();
+ cacheAndStartTransitionAnimator(animator);
return true;
}
@@ -606,7 +624,7 @@ public class PipTransition extends PipTransitionController implements
}
finishTransition();
});
- animator.start();
+ cacheAndStartTransitionAnimator(animator);
return true;
}
@@ -832,17 +850,17 @@ public class PipTransition extends PipTransitionController implements
return leash;
}
+ void cacheAndStartTransitionAnimator(@NonNull ValueAnimator animator) {
+ mTransitionAnimator = animator;
+ mTransitionAnimator.start();
+ }
+
//
// Miscellaneous callbacks and listeners
//
@Override
public void finishTransition() {
- if (mFinishCallback != null) {
- mFinishCallback.onTransitionFinished(null /* finishWct */);
- mFinishCallback = null;
- }
-
final int currentState = mPipTransitionState.getState();
int nextState = PipTransitionState.UNDEFINED;
switch (currentState) {
@@ -857,6 +875,14 @@ public class PipTransition extends PipTransitionController implements
break;
}
mPipTransitionState.setState(nextState);
+
+ if (mFinishCallback != null) {
+ // Need to unset mFinishCallback first because onTransitionFinished can re-enter this
+ // handler if there is a pending PiP animation.
+ final Transitions.TransitionFinishCallback finishCallback = mFinishCallback;
+ mFinishCallback = null;
+ finishCallback.onTransitionFinished(null /* finishWct */);
+ }
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 6da4f510ab77..d917f937b16c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -665,8 +665,10 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
mTransitionHandler.addTransitionStateListener(new RecentsTransitionStateListener() {
@Override
- public void onAnimationStateChanged(boolean running) {
- executor.execute(() -> listener.accept(running));
+ public void onTransitionStateChanged(@RecentsTransitionState int state) {
+ executor.execute(() -> {
+ listener.accept(RecentsTransitionStateListener.isAnimating(state));
+ });
}
});
});
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 1c58dbbf71fd..032dac9ff3a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -32,6 +32,9 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED;
import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION;
import static com.android.wm.shell.shared.split.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
import static com.android.wm.shell.transition.Transitions.TRANSIT_END_RECENTS_TRANSITION;
@@ -166,13 +169,19 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
// only care about latest one.
mAnimApp = appThread;
+ for (int i = 0; i < mStateListeners.size(); i++) {
+ mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_REQUESTED);
+ }
// TODO(b/366021931): Formalize this later
- final boolean isSyntheticRequest = options.containsKey("is_synthetic_recents_transition");
+ final boolean isSyntheticRequest = options.getBoolean(
+ "is_synthetic_recents_transition", /* defaultValue= */ false);
+ final IBinder transition;
if (isSyntheticRequest) {
- return startSyntheticRecentsTransition(listener);
+ transition = startSyntheticRecentsTransition(listener);
} else {
- return startRealRecentsTransition(intent, fillIn, options, listener);
+ transition = startRealRecentsTransition(intent, fillIn, options, listener);
}
+ return transition;
}
/**
@@ -542,7 +551,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
mPendingFinishTransition = null;
mControllers.remove(this);
for (int i = 0; i < mStateListeners.size(); i++) {
- mStateListeners.get(i).onAnimationStateChanged(false);
+ mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_NOT_RUNNING);
}
}
@@ -578,7 +587,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
new RemoteAnimationTarget[0],
new Rect(0, 0, 0, 0), new Rect(), new Bundle());
for (int i = 0; i < mStateListeners.size(); i++) {
- mStateListeners.get(i).onAnimationStateChanged(true);
+ mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING);
}
} catch (RemoteException e) {
Slog.e(TAG, "Error starting recents animation", e);
@@ -809,7 +818,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
new Rect(0, 0, 0, 0), new Rect(), b);
for (int i = 0; i < mStateListeners.size(); i++) {
- mStateListeners.get(i).onAnimationStateChanged(true);
+ mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING);
}
} catch (RemoteException e) {
Slog.e(TAG, "Error starting recents animation", e);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java
index 95874c8193c9..ea7cfd374f71 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionStateListener.java
@@ -16,12 +16,47 @@
package com.android.wm.shell.recents;
-import android.os.IBinder;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/** The listener for the events from {@link RecentsTransitionHandler}. */
public interface RecentsTransitionStateListener {
- /** Notifies whether the recents animation is running. */
- default void onAnimationStateChanged(boolean running) {
+ @IntDef(prefix = { "TRANSITION_STATE_" }, value = {
+ TRANSITION_STATE_NOT_RUNNING,
+ TRANSITION_STATE_REQUESTED,
+ TRANSITION_STATE_ANIMATING,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface RecentsTransitionState {}
+
+ int TRANSITION_STATE_NOT_RUNNING = 1;
+ int TRANSITION_STATE_REQUESTED = 2;
+ int TRANSITION_STATE_ANIMATING = 3;
+
+ /** Notifies whether the recents transition state changes. */
+ default void onTransitionStateChanged(@RecentsTransitionState int state) {
+ }
+
+ /** Returns whether the recents transition is running. */
+ static boolean isRunning(@RecentsTransitionState int state) {
+ return state >= TRANSITION_STATE_REQUESTED;
+ }
+
+ /** Returns whether the recents transition is animating. */
+ static boolean isAnimating(@RecentsTransitionState int state) {
+ return state >= TRANSITION_STATE_ANIMATING;
+ }
+
+ /** Returns a string representation of the given state. */
+ static String stateToString(@RecentsTransitionState int state) {
+ return switch (state) {
+ case TRANSITION_STATE_NOT_RUNNING -> "TRANSITION_STATE_NOT_RUNNING";
+ case TRANSITION_STATE_REQUESTED -> "TRANSITION_STATE_REQUESTED";
+ case TRANSITION_STATE_ANIMATING -> "TRANSITION_STATE_ANIMATING";
+ default -> "UNKNOWN";
+ };
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 3e6d36ce0ca3..39ed9abcfd26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -54,10 +54,27 @@ public interface SplitScreen {
*/
int STAGE_TYPE_SIDE = 1;
+ /**
+ * Position independent stage identifier for a given Stage
+ */
+ int STAGE_TYPE_A = 2;
+ /**
+ * Position independent stage identifier for a given Stage
+ */
+ int STAGE_TYPE_B = 3;
+ /**
+ * Position independent stage identifier for a given Stage
+ */
+ int STAGE_TYPE_C = 4;
+
@IntDef(prefix = { "STAGE_TYPE_" }, value = {
STAGE_TYPE_UNDEFINED,
STAGE_TYPE_MAIN,
- STAGE_TYPE_SIDE
+ STAGE_TYPE_SIDE,
+ // Used for flexible split
+ STAGE_TYPE_A,
+ STAGE_TYPE_B,
+ STAGE_TYPE_C
})
@interface StageType {}
@@ -128,6 +145,9 @@ public interface SplitScreen {
case STAGE_TYPE_UNDEFINED: return "UNDEFINED";
case STAGE_TYPE_MAIN: return "MAIN";
case STAGE_TYPE_SIDE: return "SIDE";
+ case STAGE_TYPE_A: return "STAGE_A";
+ case STAGE_TYPE_B: return "STAGE_B";
+ case STAGE_TYPE_C: return "STAGE_C";
default: return "UNKNOWN(" + stage + ")";
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 6398d31b4f82..4f0f6760a951 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
@@ -24,6 +24,7 @@ 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 com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.common.MultiInstanceHelper.getComponent;
import static com.android.wm.shell.common.MultiInstanceHelper.getShortcutComponent;
import static com.android.wm.shell.common.MultiInstanceHelper.samePackage;
@@ -33,6 +34,9 @@ import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMes
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.split.SplitScreenConstants.KEY_EXTRA_WIDGET_INTENT;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_0;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_1;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -98,6 +102,7 @@ import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.annotations.ExternalThread;
import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition;
+import com.android.wm.shell.shared.split.SplitScreenConstants.SplitIndex;
import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.sysui.KeyguardChangeListener;
@@ -325,7 +330,6 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
/**
* @return an Array of RunningTaskInfo's ordered by leftToRight or topTopBottom
*/
- @Nullable
public ActivityManager.RunningTaskInfo[] getAllTaskInfos() {
// TODO(b/349828130) Add the third stage task info and not rely on positions
ActivityManager.RunningTaskInfo topLeftTask = getTaskInfo(SPLIT_POSITION_TOP_OR_LEFT);
@@ -335,7 +339,7 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
return new ActivityManager.RunningTaskInfo[]{topLeftTask, bottomRightTask};
}
- return null;
+ return new ActivityManager.RunningTaskInfo[0];
}
/** Check task is under split or not by taskId. */
@@ -405,7 +409,7 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
public void prepareEnterSplitScreen(WindowContainerTransaction wct,
ActivityManager.RunningTaskInfo taskInfo, int startPosition) {
mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition,
- false /* resizeAnim */);
+ false /* resizeAnim */, SPLIT_INDEX_UNDEFINED);
}
/**
@@ -451,6 +455,24 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
}
}
+ /**
+ * Determines which split index a new instance of a task should take.
+ * @param callingTask The task requesting a new instance.
+ * @return the split index of the new instance
+ */
+ @SplitIndex
+ public int determineNewInstanceIndex(@NonNull ActivityManager.RunningTaskInfo callingTask) {
+ if (!enableFlexibleSplit()) {
+ throw new IllegalStateException("Use determineNewInstancePosition");
+ }
+ if (callingTask.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ || getSplitPosition(callingTask.taskId) == SPLIT_POSITION_TOP_OR_LEFT) {
+ return SPLIT_INDEX_1;
+ } else {
+ return SPLIT_INDEX_0;
+ }
+ }
+
public void enterSplitScreen(int taskId, boolean leftOrTop) {
enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction());
}
@@ -685,7 +707,10 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startIntentWithInstanceId: reason=%d",
ENTER_REASON_LAUNCHER);
mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
- startIntent(intent, userId, fillInIntent, position, options, null /* hideTaskToken */);
+ // TODO(b/349828130) currently pass in index_undefined until we can revisit these
+ // specific cases in the future. Only focusing on parity with starting intent/task
+ startIntent(intent, userId, fillInIntent, position, options, null /* hideTaskToken */,
+ SPLIT_INDEX_UNDEFINED);
}
private void startIntentAndTask(PendingIntent pendingIntent, int userId1,
@@ -775,9 +800,9 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
@Override
public void startIntent(PendingIntent intent, int userId1, @Nullable Intent fillInIntent,
@SplitPosition int position, @Nullable Bundle options,
- @Nullable WindowContainerToken hideTaskToken) {
+ @Nullable WindowContainerToken hideTaskToken, @SplitIndex int index) {
startIntent(intent, userId1, fillInIntent, position, options, hideTaskToken,
- false /* forceLaunchNewTask */);
+ false /* forceLaunchNewTask */, index);
}
/**
@@ -790,7 +815,8 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
*/
public void startIntent(PendingIntent intent, int userId1, @Nullable Intent fillInIntent,
@SplitPosition int position, @Nullable Bundle options,
- @Nullable WindowContainerToken hideTaskToken, boolean forceLaunchNewTask) {
+ @Nullable WindowContainerToken hideTaskToken, boolean forceLaunchNewTask,
+ @SplitIndex int index) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"startIntent(): intent=%s user=%d fillInIntent=%s position=%d", intent, userId1,
fillInIntent, position);
@@ -816,7 +842,7 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
if (taskInfo != null) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"Found suitable background task=%s", taskInfo);
- mStageCoordinator.startTask(taskInfo.taskId, position, options, hideTaskToken);
+ mStageCoordinator.startTask(taskInfo.taskId, position, options, hideTaskToken, index);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background");
return;
@@ -841,7 +867,8 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
}
}
- mStageCoordinator.startIntent(intent, fillInIntent, position, options, hideTaskToken);
+ mStageCoordinator.startIntent(intent, fillInIntent, position, options, hideTaskToken,
+ index);
}
/**
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 840049412db4..3091be574a53 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
@@ -21,6 +21,7 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;
import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_IN;
@@ -55,6 +56,9 @@ import com.android.wm.shell.transition.OneShotRemoteHandler;
import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
/** Manages transition animations for split-screen. */
@@ -268,22 +272,21 @@ class SplitScreenTransitions {
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback,
- @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
- @NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) {
+ @NonNull Map<WindowContainerToken, SplitDecorManager> rootDecorMap) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "playResizeAnimation: transition=%d", info.getDebugId());
initTransition(transition, finishTransaction, finishCallback);
+ Set<WindowContainerToken> rootDecorKeys = rootDecorMap.keySet();
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
- if (mainRoot.equals(change.getContainer()) || sideRoot.equals(change.getContainer())) {
+ if (rootDecorKeys.contains(change.getContainer())) {
final SurfaceControl leash = change.getLeash();
startTransaction.setPosition(leash, change.getEndAbsBounds().left,
change.getEndAbsBounds().top);
startTransaction.setWindowCrop(leash, change.getEndAbsBounds().width(),
change.getEndAbsBounds().height());
- SplitDecorManager decor = mainRoot.equals(change.getContainer())
- ? mainDecor : sideDecor;
+ SplitDecorManager decor = rootDecorMap.get(change.getContainer());
// This is to ensure onFinished be called after all animations ended.
ValueAnimator va = new ValueAnimator();
@@ -433,15 +436,22 @@ class SplitScreenTransitions {
Transitions.TransitionHandler handler,
@Nullable TransitionConsumedCallback consumedCallback,
@Nullable TransitionFinishedCallback finishCallback,
- @NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) {
+ @Nullable SplitDecorManager mainDecor, @Nullable SplitDecorManager sideDecor,
+ @Nullable List<SplitDecorManager> decorManagers) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
" splitTransition deduced Resize split screen.");
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition: hasPendingResize=%b",
mPendingResize != null);
if (mPendingResize != null) {
mPendingResize.cancel(null);
- mainDecor.cancelRunningAnimations();
- sideDecor.cancelRunningAnimations();
+ if (enableFlexibleSplit()) {
+ for (SplitDecorManager stage : decorManagers) {
+ stage.cancelRunningAnimations();
+ }
+ } else {
+ mainDecor.cancelRunningAnimations();
+ sideDecor.cancelRunningAnimations();
+ }
mAnimations.clear();
onFinish(null /* wct */);
}
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 e692c61cd493..86d689831bdc 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
@@ -33,16 +33,16 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
+import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
-import static com.android.wm.shell.common.split.SplitScreenUtils.isPartiallyOffscreen;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
-import static com.android.wm.shell.shared.TransitionUtil.isOrderOnly;
import static com.android.wm.shell.shared.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_90_10;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_0;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_1;
@@ -51,9 +51,12 @@ import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.shared.split.SplitScreenConstants.splitPositionToString;
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_A;
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_B;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_LAUNCHER;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED;
@@ -132,6 +135,7 @@ import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.split.OffscreenTouchZone;
import com.android.wm.shell.common.split.SplitDecorManager;
import com.android.wm.shell.common.split.SplitLayout;
import com.android.wm.shell.common.split.SplitScreenUtils;
@@ -142,6 +146,7 @@ import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.shared.split.SplitBounds;
import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition;
+import com.android.wm.shell.shared.split.SplitScreenConstants.SplitIndex;
import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.splitscreen.SplitScreenController.ExitReason;
@@ -153,11 +158,15 @@ import dalvik.annotation.optimization.NeverCompile;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
/**
* Coordinates the staging (visibility, sizing, ...) of the split-screen stages.
@@ -178,10 +187,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// entered
private static final int DISABLE_LAUNCH_ADJACENT_AFTER_ENTER_TIMEOUT_MS = 1000;
- private final StageTaskListener mMainStage;
- private final StageTaskListener mSideStage;
+ private StageTaskListener mMainStage;
+ private StageTaskListener mSideStage;
@SplitPosition
private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
+ private StageOrderOperator mStageOrderOperator;
private final int mDisplayId;
private SplitLayout mSplitLayout;
@@ -311,6 +321,20 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSyncQueue.runInSync(t -> applyDividerVisibility(t));
}
}
+
+ @Override
+ public void inflateOnStageRoot(OffscreenTouchZone touchZone) {
+ SurfaceControl topLeftLeash =
+ mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+ ? mMainStage.mRootLeash : mSideStage.mRootLeash;
+ SurfaceControl bottomRightLeash =
+ mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+ ? mSideStage.mRootLeash : mMainStage.mRootLeash;
+ touchZone.inflate(
+ mContext.createConfigurationContext(mRootTaskInfo.configuration),
+ mRootTaskInfo.configuration, mSyncQueue,
+ touchZone.isTopLeft() ? topLeftLeash : bottomRightLeash);
+ }
};
protected StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
@@ -335,22 +359,32 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */);
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Creating main/side root task");
- mMainStage = new StageTaskListener(
- mContext,
- mTaskOrganizer,
- mDisplayId,
- this /*stageListenerCallbacks*/,
- mSyncQueue,
- iconProvider,
- mWindowDecorViewModel);
- mSideStage = new StageTaskListener(
- mContext,
- mTaskOrganizer,
- mDisplayId,
- this /*stageListenerCallbacks*/,
- mSyncQueue,
- iconProvider,
- mWindowDecorViewModel);
+ if (enableFlexibleSplit()) {
+ mStageOrderOperator = new StageOrderOperator(mContext,
+ mTaskOrganizer,
+ mDisplayId,
+ this /*stageListenerCallbacks*/,
+ mSyncQueue,
+ iconProvider,
+ mWindowDecorViewModel);
+ } else {
+ mMainStage = new StageTaskListener(
+ mContext,
+ mTaskOrganizer,
+ mDisplayId,
+ this /*stageListenerCallbacks*/,
+ mSyncQueue,
+ iconProvider,
+ mWindowDecorViewModel, STAGE_TYPE_MAIN);
+ mSideStage = new StageTaskListener(
+ mContext,
+ mTaskOrganizer,
+ mDisplayId,
+ this /*stageListenerCallbacks*/,
+ mSyncQueue,
+ iconProvider,
+ mWindowDecorViewModel, STAGE_TYPE_SIDE);
+ }
mDisplayController = displayController;
mDisplayImeController = displayImeController;
mDisplayInsetsController = displayInsetsController;
@@ -422,24 +456,63 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
public boolean isSplitScreenVisible() {
- return mSideStage.mVisible && mMainStage.mVisible;
+ if (enableFlexibleSplit()) {
+ return runForActiveStagesAllMatch((stage) -> stage.mVisible);
+ } else {
+ return mSideStage.mVisible && mMainStage.mVisible;
+ }
}
- private void activateSplit(WindowContainerTransaction wct, boolean includingTopTask) {
- mMainStage.activate(wct, includingTopTask);
+ /**
+ * @param includingTopTask reparents the current top task into the stage defined by index
+ * (or mainStage in legacy split)
+ * @param index the index to move the current visible task into, if undefined will arbitrarily
+ * choose a stage to launch into
+ */
+ private void activateSplit(WindowContainerTransaction wct, boolean includingTopTask,
+ int index) {
+ if (enableFlexibleSplit()) {
+ mStageOrderOperator.onEnteringSplit(SNAP_TO_2_50_50);
+ if (index == SPLIT_INDEX_UNDEFINED || !includingTopTask) {
+ // If we aren't includingTopTask, then the call to activate on the stage is
+ // effectively a no-op. Previously the stage kept track of the "isActive" state,
+ // but now that gets set in the "onEnteringSplit" call above.
+ //
+ // index == UNDEFINED case might change, but as of now no use case where we activate
+ // without an index specified.
+ return;
+ }
+ @SplitIndex int oppositeIndex = index == SPLIT_INDEX_0 ? SPLIT_INDEX_1 : SPLIT_INDEX_0;
+ StageTaskListener activatingStage = mStageOrderOperator.getStageForIndex(oppositeIndex);
+ activatingStage.activate(wct, includingTopTask);
+ } else {
+ mMainStage.activate(wct, includingTopTask);
+ }
}
public boolean isSplitActive() {
- return mMainStage.isActive();
+ if (enableFlexibleSplit()) {
+ return mStageOrderOperator.isActive();
+ } else {
+ return mMainStage.isActive();
+ }
}
/**
* Deactivates main stage by removing the stage from the top level split root (usually when a
* task underneath gets removed from the stage root).
- * @param reparentToTop whether we want to put the stage root back on top
+ * @param stageToTop stage which we want to put on top
*/
- private void deactivateSplit(WindowContainerTransaction wct, boolean reparentToTop) {
- mMainStage.deactivate(wct, reparentToTop);
+ private void deactivateSplit(WindowContainerTransaction wct, @StageType int stageToTop) {
+ if (enableFlexibleSplit()) {
+ StageTaskListener stageToDeactivate = mStageOrderOperator.getAllStages().stream()
+ .filter(stage -> stage.getId() == stageToTop)
+ .findFirst().orElseThrow();
+ stageToDeactivate.deactivate(wct, true /*toTop*/);
+ mStageOrderOperator.onExitingSplit();
+ } else {
+ mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
+ }
}
/** @return whether this transition-request has the launch-adjacent flag. */
@@ -463,11 +536,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// If one of the splitting tasks support auto-pip, wm-core might reparent the task to TDA
// and file a TRANSIT_PIP transition when finishing transitions.
// @see com.android.server.wm.RootWindowContainer#moveActivityToPinnedRootTask
- if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
- return true;
+ if (enableFlexibleSplit()) {
+ return mStageOrderOperator.getActiveStages().stream()
+ .anyMatch(stage -> stage.getChildCount() == 0);
+ } else {
+ return mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0;
}
-
- return false;
}
/** Checks if `transition` is a pending enter-split transition. */
@@ -477,10 +551,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@StageType
int getStageOfTask(int taskId) {
- if (mMainStage.containsTask(taskId)) {
- return STAGE_TYPE_MAIN;
- } else if (mSideStage.containsTask(taskId)) {
- return STAGE_TYPE_SIDE;
+ if (enableFlexibleSplit()) {
+ StageTaskListener stageTaskListener = mStageOrderOperator.getActiveStages().stream()
+ .filter(stage -> stage.containsTask(taskId))
+ .findFirst().orElse(null);
+ if (stageTaskListener != null) {
+ return stageTaskListener.getId();
+ }
+ } else {
+ if (mMainStage.containsTask(taskId)) {
+ return STAGE_TYPE_MAIN;
+ } else if (mSideStage.containsTask(taskId)) {
+ return STAGE_TYPE_SIDE;
+ }
}
return STAGE_TYPE_UNDEFINED;
@@ -490,14 +573,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (mRootTaskInfo != null && mRootTaskInfo.taskId == taskId) {
return true;
}
- return mMainStage.isRootTaskId(taskId) || mSideStage.isRootTaskId(taskId);
+ if (enableFlexibleSplit()) {
+ return mStageOrderOperator.getActiveStages().stream()
+ .anyMatch((stage) -> stage.isRootTaskId(taskId));
+ } else {
+ return mMainStage.isRootTaskId(taskId) || mSideStage.isRootTaskId(taskId);
+ }
}
boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
WindowContainerTransaction wct) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "moveToStage: task=%d position=%d", task.taskId,
stagePosition);
- prepareEnterSplitScreen(wct, task, stagePosition, false /* resizeAnim */);
+ // TODO(b/349828130) currently pass in index_undefined until we can revisit these
+ // specific cases in the future. Only focusing on parity with starting intent/task
+ prepareEnterSplitScreen(wct, task, stagePosition, false /* resizeAnim */,
+ SPLIT_INDEX_UNDEFINED);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
null, this,
isSplitScreenVisible()
@@ -595,11 +686,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
* same window container transaction as the starting of the intent.
*/
void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
- @Nullable WindowContainerToken hideTaskToken) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startTask: task=%d position=%d", taskId, position);
+ @Nullable WindowContainerToken hideTaskToken, @SplitIndex int index) {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startTask: task=%d position=%d index=%d",
+ taskId, position, index);
mSplitRequest = new SplitRequest(taskId, position);
final WindowContainerTransaction wct = new WindowContainerTransaction();
- options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+ options = enableFlexibleSplit()
+ ? resolveStartStageForIndex(options, null /*wct*/, index)
+ : resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
if (hideTaskToken != null) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
wct.reorder(hideTaskToken, false /* onTop */);
@@ -623,7 +717,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// If split screen is not activated, we're expecting to open a pair of apps to split.
final int extraTransitType = isSplitActive()
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
- prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering);
+ prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering, index);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
extraTransitType, !mIsDropEntering);
@@ -635,13 +729,16 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
* same window container transaction as the starting of the intent.
*/
void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
- @Nullable Bundle options, @Nullable WindowContainerToken hideTaskToken) {
+ @Nullable Bundle options, @Nullable WindowContainerToken hideTaskToken,
+ @SplitIndex int index) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startIntent: intent=%s position=%d", intent.getIntent(),
position);
mSplitRequest = new SplitRequest(intent.getIntent(), position);
final WindowContainerTransaction wct = new WindowContainerTransaction();
- options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+ options = enableFlexibleSplit()
+ ? resolveStartStageForIndex(options, null /*wct*/, index)
+ : resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
if (hideTaskToken != null) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
wct.reorder(hideTaskToken, false /* onTop */);
@@ -666,13 +763,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// If split screen is not activated, we're expecting to open a pair of apps to split.
final int extraTransitType = isSplitActive()
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
- prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering);
+ prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering, index);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
extraTransitType, !mIsDropEntering);
}
- /** Starts 2 tasks in one transition. */
+ /**
+ * Starts 2 tasks in one transition.
+ * @param taskId1 starts in the mSideStage
+ * @param taskId2 starts in the mainStage #startWithTask()
+ */
void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2,
@SplitPosition int splitPosition, @PersistentSnapPosition int snapPosition,
@Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
@@ -687,11 +788,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
setSideStagePosition(splitPosition, wct);
options1 = options1 != null ? options1 : new Bundle();
- addActivityOptions(options1, mSideStage);
+ StageTaskListener stageForTask1;
+ if (enableFlexibleSplit()) {
+ stageForTask1 = mStageOrderOperator.getStageForLegacyPosition(splitPosition,
+ true /*checkAllStagesIfNotActive*/);
+ } else {
+ stageForTask1 = mSideStage;
+ }
+ addActivityOptions(options1, stageForTask1);
prepareTasksForSplitScreen(new int[] {taskId1, taskId2}, wct);
wct.startTask(taskId1, options1);
- startWithTask(wct, taskId2, options2, snapPosition, remoteTransition, instanceId);
+ startWithTask(wct, taskId2, options2, snapPosition, remoteTransition, instanceId,
+ splitPosition);
}
/** Start an intent and a task to a split pair in one transition. */
@@ -721,7 +830,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
prepareTasksForSplitScreen(new int[] {taskId}, wct);
- startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId);
+ startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId,
+ splitPosition);
}
/**
@@ -765,7 +875,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
prepareTasksForSplitScreen(new int[] {taskId}, wct);
- startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId);
+ startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId,
+ splitPosition);
}
/**
@@ -795,11 +906,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
*/
private void startWithTask(WindowContainerTransaction wct, int mainTaskId,
@Nullable Bundle mainOptions, @PersistentSnapPosition int snapPosition,
- @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+ @Nullable RemoteTransition remoteTransition, InstanceId instanceId,
+ @SplitPosition int splitPosition) {
if (!isSplitActive()) {
// Build a request WCT that will launch both apps such that task 0 is on the main stage
// while task 1 is on the side stage.
- activateSplit(wct, false /* reparentToTop */);
+ // TODO(b/349828130) currently pass in index_undefined until we can revisit these
+ // specific cases in the future. Only focusing on parity with starting intent/task
+ activateSplit(wct, false /* reparentToTop */, SPLIT_INDEX_UNDEFINED);
}
mSplitLayout.setDivideRatio(snapPosition);
updateWindowBounds(mSplitLayout, wct);
@@ -807,10 +921,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
false /* reparentLeafTaskIfRelaunch */);
setRootForceTranslucent(false, wct);
-
+ // All callers of this method set the correct activity options on mSideStage,
+ // so we choose the opposite stage for this method
+ StageTaskListener stage;
+ if (enableFlexibleSplit()) {
+ stage = mStageOrderOperator
+ .getStageForLegacyPosition(reverseSplitPosition(splitPosition),
+ false /*checkAllStagesIfNotActive*/);
+ } else {
+ stage = mMainStage;
+ }
// Make sure the launch options will put tasks in the corresponding split roots
mainOptions = mainOptions != null ? mainOptions : new Bundle();
- addActivityOptions(mainOptions, mMainStage);
+ addActivityOptions(mainOptions, stage);
// Add task launch requests
wct.startTask(mainTaskId, mainOptions);
@@ -866,7 +989,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!isSplitActive()) {
// Build a request WCT that will launch both apps such that task 0 is on the main stage
// while task 1 is on the side stage.
- activateSplit(wct, false /* reparentToTop */);
+ // TODO(b/349828130) currently pass in index_undefined until we can revisit these
+ // specific cases in the future. Only focusing on parity with starting intent/task
+ activateSplit(wct, false /* reparentToTop */, SPLIT_INDEX_UNDEFINED);
}
setSideStagePosition(splitPosition, wct);
@@ -974,6 +1099,31 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSideStage.evictInvisibleChildren(wct);
}
+ /**
+ * @param index for the new stage that will be opening. Ex. if app is dragged to
+ * index=1, then this will tell the stage at index=1 to launch the task
+ * in the wct in that stage. This doesn't verify that the non-specified
+ * indices' stages have their tasks correctly set/re-parented.
+ */
+ Bundle resolveStartStageForIndex(@Nullable Bundle options,
+ @Nullable WindowContainerTransaction wct,
+ @SplitIndex int index) {
+ StageTaskListener oppositeStage;
+ if (index == SPLIT_INDEX_UNDEFINED) {
+ // Arbitrarily choose a stage
+ oppositeStage = mStageOrderOperator.getStageForIndex(SPLIT_INDEX_1);
+ } else {
+ oppositeStage = mStageOrderOperator.getStageForIndex(index);
+ }
+ if (options == null) {
+ options = new Bundle();
+ }
+ updateStageWindowBoundsForIndex(wct, index);
+ addActivityOptions(options, oppositeStage);
+
+ return options;
+ }
+
Bundle resolveStartStage(@StageType int stage, @SplitPosition int position,
@Nullable Bundle options, @Nullable WindowContainerTransaction wct) {
switch (stage) {
@@ -1041,20 +1191,35 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return INVALID_TASK_ID;
}
- return mSideStagePosition == splitPosition
- ? mSideStage.getTopVisibleChildTaskId()
- : mMainStage.getTopVisibleChildTaskId();
+ if (enableFlexibleSplit()) {
+ StageTaskListener stage = mStageOrderOperator.getStageForLegacyPosition(splitPosition,
+ true /*checkAllStagesIfNotActive*/);
+ return stage != null ? stage.getTopVisibleChildTaskId() : INVALID_TASK_ID;
+ } else {
+ return mSideStagePosition == splitPosition
+ ? mSideStage.getTopVisibleChildTaskId()
+ : mMainStage.getTopVisibleChildTaskId();
+ }
}
void switchSplitPosition(String reason) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "switchSplitPosition");
final SurfaceControl.Transaction t = mTransactionPool.acquire();
mTempRect1.setEmpty();
- final StageTaskListener topLeftStage =
- mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
- final StageTaskListener bottomRightStage =
- mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
-
+ final StageTaskListener topLeftStage;
+ final StageTaskListener bottomRightStage;
+ if (enableFlexibleSplit()) {
+ topLeftStage = mStageOrderOperator.getStageForLegacyPosition(SPLIT_POSITION_TOP_OR_LEFT,
+ false /*checkAllStagesIfNotActive*/);
+ bottomRightStage = mStageOrderOperator
+ .getStageForLegacyPosition(SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ false /*checkAllStagesIfNotActive*/);
+ } else {
+ topLeftStage =
+ mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
+ bottomRightStage =
+ mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
+ }
// Don't allow windows or divider to be focused during animation (mRootTaskInfo is the
// parent of all 3 leaves). We don't want the user to be able to tap and focus a window
// while it is moving across the screen, because granting focus also recalculates the
@@ -1091,9 +1256,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
});
ProtoLog.v(WM_SHELL_SPLIT_SCREEN, "Switch split position: %s", reason);
- mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
- getSideStagePosition(), mSideStage.getTopChildTaskUid(),
- mSplitLayout.isLeftRightSplit());
+ if (enableFlexibleSplit()) {
+ // TODO(b/374825718) update logging for 2+ apps
+ } else {
+ mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
+ getSideStagePosition(), mSideStage.getTopChildTaskUid(),
+ mSplitLayout.isLeftRightSplit());
+ }
}
void setSideStagePosition(@SplitPosition int sideStagePosition,
@@ -1101,8 +1270,26 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (mSideStagePosition == sideStagePosition) return;
mSideStagePosition = sideStagePosition;
sendOnStagePositionChanged();
+ StageTaskListener stage = enableFlexibleSplit()
+ ? mStageOrderOperator.getStageForLegacyPosition(mSideStagePosition,
+ true /*checkAllStagesIfNotActive*/)
+ : mSideStage;
+
+ if (stage.mVisible) {
+ if (wct == null) {
+ // onLayoutChanged builds/applies a wct with the contents of updateWindowBounds.
+ onLayoutSizeChanged(mSplitLayout);
+ } else {
+ updateWindowBounds(mSplitLayout, wct);
+ sendOnBoundsChanged();
+ }
+ }
+ }
- if (mSideStage.mVisible) {
+ private void updateStageWindowBoundsForIndex(@Nullable WindowContainerTransaction wct,
+ @SplitIndex int index) {
+ StageTaskListener stage = mStageOrderOperator.getStageForIndex(index);
+ if (stage.mVisible) {
if (wct == null) {
// onLayoutChanged builds/applies a wct with the contents of updateWindowBounds.
onLayoutSizeChanged(mSplitLayout);
@@ -1152,10 +1339,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
void recordLastActiveStage() {
if (!isSplitActive() || !isSplitScreenVisible()) {
mLastActiveStage = STAGE_TYPE_UNDEFINED;
- } else if (mMainStage.isFocused()) {
- mLastActiveStage = STAGE_TYPE_MAIN;
- } else if (mSideStage.isFocused()) {
- mLastActiveStage = STAGE_TYPE_SIDE;
+ } else if (enableFlexibleSplit()) {
+ mStageOrderOperator.getActiveStages().stream()
+ .filter(StageTaskListener::isFocused)
+ .findFirst()
+ .ifPresent(stage -> mLastActiveStage = stage.getId());
+ } else {
+ if (mMainStage.isFocused()) {
+ mLastActiveStage = STAGE_TYPE_MAIN;
+ } else if (mSideStage.isFocused()) {
+ mLastActiveStage = STAGE_TYPE_SIDE;
+ }
}
}
@@ -1212,7 +1406,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.getInvisibleBounds(mTempRect1);
if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
mSideStage.removeAllTasks(wct, false /* toTop */);
- deactivateSplit(wct, false /* reparentToTop */);
+ deactivateSplit(wct, STAGE_TYPE_UNDEFINED);
wct.reorder(mRootTaskInfo.token, false /* onTop */);
setRootForceTranslucent(true, wct);
wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
@@ -1241,7 +1435,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
childrenToTop.fadeOutDecor(() -> {
WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
mIsExiting = false;
- deactivateSplit(finishedWCT, childrenToTop == mMainStage /* reparentToTop */);
+ deactivateSplit(finishedWCT, childrenToTop.getId());
mSideStage.removeAllTasks(finishedWCT, childrenToTop == mSideStage /* toTop */);
finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
setRootForceTranslucent(true, finishedWCT);
@@ -1369,8 +1563,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mRecentTasks.ifPresent(recentTasks -> {
// Notify recents if we are exiting in a way that breaks the pair, and disable further
// updates to splits in the recents until we enter split again
- mMainStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
- mSideStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
+ if (enableFlexibleSplit()) {
+ runForActiveStages((stage) ->
+ stage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId)));
+ } else {
+ mMainStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
+ mSideStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
+ }
});
logExit(exitReason);
}
@@ -1383,15 +1582,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
void prepareExitSplitScreen(@StageType int stageToTop,
@NonNull WindowContainerTransaction wct) {
if (!isSplitActive()) return;
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareExitSplitScreen: stageToTop=%d", stageToTop);
- mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
- deactivateSplit(wct, stageToTop == STAGE_TYPE_MAIN);
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareExitSplitScreen: stageToTop=%s",
+ stageTypeToString(stageToTop));
+ if (enableFlexibleSplit()) {
+ mStageOrderOperator.getActiveStages().stream()
+ .filter(stage -> stage.getId() != stageToTop)
+ .forEach(stage -> stage.removeAllTasks(wct, false /*toTop*/));
+ } else {
+ mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
+ }
+ deactivateSplit(wct, stageToTop);
}
private void prepareEnterSplitScreen(WindowContainerTransaction wct) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareEnterSplitScreen");
prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED,
- !mIsDropEntering);
+ !mIsDropEntering, SPLIT_INDEX_UNDEFINED);
}
/**
@@ -1400,7 +1606,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
*/
void prepareEnterSplitScreen(WindowContainerTransaction wct,
@Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
- boolean resizeAnim) {
+ boolean resizeAnim, @SplitIndex int index) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareEnterSplitScreen: position=%d resize=%b",
startPosition, resizeAnim);
onSplitScreenEnter();
@@ -1412,7 +1618,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (isSplitActive()) {
prepareBringSplit(wct, taskInfo, startPosition, resizeAnim);
} else {
- prepareActiveSplit(wct, taskInfo, startPosition, resizeAnim);
+ prepareActiveSplit(wct, taskInfo, startPosition, resizeAnim, index);
}
}
@@ -1433,14 +1639,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!mSkipEvictingMainStageChildren) {
mMainStage.evictAllChildren(wct);
}
- mMainStage.reparentTopTask(wct);
+ // TODO(b/349828130) revisit bring split from BG to FG scenarios
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stage -> stage.reparentTopTask(wct));
+ } else {
+ mMainStage.reparentTopTask(wct);
+ }
prepareSplitLayout(wct, resizeAnim);
}
}
+ /**
+ * @param index The index that has already been assigned a stage
+ */
private void prepareActiveSplit(WindowContainerTransaction wct,
@Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
- boolean resizeAnim) {
+ boolean resizeAnim, @SplitIndex int index) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "prepareActiveSplit: task=%d isSplitVisible=%b",
taskInfo != null ? taskInfo.taskId : -1, isSplitScreenVisible());
// We handle split visibility itself on shell transition, but sometimes we didn't
@@ -1450,7 +1664,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
setSideStagePosition(startPosition, wct);
mSideStage.addTask(taskInfo, wct);
}
- activateSplit(wct, true /* reparentToTop */);
+ activateSplit(wct, true /* reparentToTop */, index);
prepareSplitLayout(wct, resizeAnim);
}
@@ -1477,8 +1691,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
void finishEnterSplitScreen(SurfaceControl.Transaction finishT) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "finishEnterSplitScreen");
mSplitLayout.update(null, true /* resetImePosition */);
- mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash);
- mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash);
+ if (enableFlexibleSplit()) {
+ runForActiveStages((stage) ->
+ stage.getSplitDecorManager().inflate(mContext, stage.mRootLeash));
+ } else {
+ mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash);
+ mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash);
+ }
setDividerVisibility(true, finishT);
// Ensure divider surface are re-parented back into the hierarchy at the end of the
// transition. See Transition#buildFinishTransaction for more detail.
@@ -1492,6 +1711,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitRequest = null;
updateRecentTasksSplitPair();
+ if (enableFlexibleSplit()) {
+ // TODO(b/374825718) log 2+ apps
+ return;
+ }
mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
getMainStagePosition(), mMainStage.getTopChildTaskUid(),
getSideStagePosition(), mSideStage.getTopChildTaskUid(),
@@ -1499,8 +1722,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
- outTopOrLeftBounds.set(mSplitLayout.getBounds1());
- outBottomOrRightBounds.set(mSplitLayout.getBounds2());
+ outTopOrLeftBounds.set(mSplitLayout.getTopLeftBounds());
+ outBottomOrRightBounds.set(mSplitLayout.getBottomRightBounds());
+ }
+
+ private void runForActiveStages(Consumer<StageTaskListener> consumer) {
+ mStageOrderOperator.getActiveStages().forEach(consumer);
+ }
+
+ private boolean runForActiveStagesAllMatch(Predicate<StageTaskListener> predicate) {
+ List<StageTaskListener> activeStages = mStageOrderOperator.getActiveStages();
+ return !activeStages.isEmpty() && activeStages.stream().allMatch(predicate);
}
@SplitPosition
@@ -1516,6 +1748,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void addActivityOptions(Bundle opts, @Nullable StageTaskListener launchTarget) {
ActivityOptions options = ActivityOptions.fromBundle(opts);
if (launchTarget != null) {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+ "addActivityOptions setting launch root for stage=%s",
+ stageTypeToString(launchTarget.getId()));
options.setLaunchRootTask(launchTarget.mRootTaskInfo.token);
}
// Put BAL flags to avoid activity start aborted. Otherwise, flows like shortcut to split
@@ -1559,8 +1794,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
listener.onSplitBoundsChanged(mSplitLayout.getRootBounds(), getMainStageBounds(),
getSideStageBounds());
}
- mSideStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_SIDE);
- mMainStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_MAIN);
+ if (enableFlexibleSplit()) {
+ // TODO(b/349828130) replace w/ stageID
+ mStageOrderOperator.getAllStages().forEach(
+ stage -> stage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_UNDEFINED)
+ );
+ } else {
+ mSideStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_SIDE);
+ mMainStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_MAIN);
+ }
}
private void sendOnStagePositionChanged() {
@@ -1584,17 +1826,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
boolean present, boolean visible) {
int stage;
if (present) {
- stage = stageListener == mSideStage ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
+ if (enableFlexibleSplit()) {
+ stage = stageListener.getId();
+ } else {
+ stage = stageListener == mSideStage ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
+ }
} else {
// No longer on any stage
stage = STAGE_TYPE_UNDEFINED;
}
- if (stage == STAGE_TYPE_MAIN) {
- mLogger.logMainStageAppChange(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
- mSplitLayout.isLeftRightSplit());
- } else if (stage == STAGE_TYPE_SIDE) {
- mLogger.logSideStageAppChange(getSideStagePosition(), mSideStage.getTopChildTaskUid(),
- mSplitLayout.isLeftRightSplit());
+ if (!enableFlexibleSplit()) {
+ if (stage == STAGE_TYPE_MAIN) {
+ mLogger.logMainStageAppChange(getMainStagePosition(),
+ mMainStage.getTopChildTaskUid(),
+ mSplitLayout.isLeftRightSplit());
+ } else if (stage == STAGE_TYPE_SIDE) {
+ mLogger.logSideStageAppChange(getSideStagePosition(),
+ mSideStage.getTopChildTaskUid(),
+ mSplitLayout.isLeftRightSplit());
+ }
}
if (present) {
updateRecentTasksSplitPair();
@@ -1620,19 +1870,40 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return;
}
mRecentTasks.ifPresent(recentTasks -> {
- Rect topLeftBounds = mSplitLayout.getBounds1();
- Rect bottomRightBounds = mSplitLayout.getBounds2();
- int mainStageTopTaskId = mMainStage.getTopVisibleChildTaskId();
- int sideStageTopTaskId = mSideStage.getTopVisibleChildTaskId();
+ Rect topLeftBounds = new Rect();
+ mSplitLayout.copyTopLeftBounds(topLeftBounds);
+ Rect bottomRightBounds = new Rect();
+ mSplitLayout.copyBottomRightBounds(bottomRightBounds);
+
+ int sideStageTopTaskId;
+ int mainStageTopTaskId;
+ if (enableFlexibleSplit()) {
+ List<StageTaskListener> activeStages = mStageOrderOperator.getActiveStages();
+ if (activeStages.size() != 2) {
+ sideStageTopTaskId = mainStageTopTaskId = INVALID_TASK_ID;
+ } else {
+ // doesn't matter which one we assign to? What matters is the order of 0 and 1?
+ mainStageTopTaskId = activeStages.get(0).getTopVisibleChildTaskId();
+ sideStageTopTaskId = activeStages.get(1).getTopVisibleChildTaskId();
+ }
+ } else {
+ mainStageTopTaskId = mMainStage.getTopVisibleChildTaskId();
+ sideStageTopTaskId= mSideStage.getTopVisibleChildTaskId();
+ }
boolean sideStageTopLeft = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
int leftTopTaskId;
int rightBottomTaskId;
- if (sideStageTopLeft) {
- leftTopTaskId = sideStageTopTaskId;
- rightBottomTaskId = mainStageTopTaskId;
- } else {
+ if (enableFlexibleSplit()) {
leftTopTaskId = mainStageTopTaskId;
rightBottomTaskId = sideStageTopTaskId;
+ } else {
+ if (sideStageTopLeft) {
+ leftTopTaskId = sideStageTopTaskId;
+ rightBottomTaskId = mainStageTopTaskId;
+ } else {
+ leftTopTaskId = mainStageTopTaskId;
+ rightBottomTaskId = sideStageTopTaskId;
+ }
}
if (Flags.enableFlexibleTwoAppSplit()) {
@@ -1741,29 +2012,59 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@VisibleForTesting
@Override
public void onRootTaskAppeared() {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRootTaskAppeared: rootTask=%s mainRoot=%b sideRoot=%b",
- mRootTaskInfo, mMainStage.mHasRootTask, mSideStage.mHasRootTask);
+ if (enableFlexibleSplit()) {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRootTaskAppeared: rootTask=%s",
+ mRootTaskInfo);
+ mStageOrderOperator.getAllStages().forEach(stage -> {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+ " onRootStageAppeared stageId=%s hasRoot=%b",
+ stageTypeToString(stage.getId()), stage.mHasRootTask);
+ });
+ } else {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+ "onRootTaskAppeared: rootTask=%s mainRoot=%b sideRoot=%b",
+ mRootTaskInfo, mMainStage.mHasRootTask, mSideStage.mHasRootTask);
+ }
+ boolean notAllStagesHaveRootTask;
+ if (enableFlexibleSplit()) {
+ notAllStagesHaveRootTask = mStageOrderOperator.getAllStages().stream()
+ .anyMatch((stage) -> !stage.mHasRootTask);
+ } else {
+ notAllStagesHaveRootTask = !mMainStage.mHasRootTask
+ || !mSideStage.mHasRootTask;
+ }
// Wait unit all root tasks appeared.
- if (mRootTaskInfo == null
- || !mMainStage.mHasRootTask
- || !mSideStage.mHasRootTask) {
+ if (mRootTaskInfo == null || notAllStagesHaveRootTask) {
return;
}
final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.reparent(mMainStage.mRootTaskInfo.token, mRootTaskInfo.token, true);
- wct.reparent(mSideStage.mRootTaskInfo.token, mRootTaskInfo.token, true);
+ if (enableFlexibleSplit()) {
+ mStageOrderOperator.getAllStages().forEach(stage ->
+ wct.reparent(stage.mRootTaskInfo.token, mRootTaskInfo.token, true));
+ } else {
+ wct.reparent(mMainStage.mRootTaskInfo.token, mRootTaskInfo.token, true);
+ wct.reparent(mSideStage.mRootTaskInfo.token, mRootTaskInfo.token, true);
+ }
- // Make the stages adjacent to each other so they occlude what's behind them.
- wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
setRootForceTranslucent(true, wct);
- mSplitLayout.getInvisibleBounds(mTempRect1);
- wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
+ if (!enableFlexibleSplit()) {
+ //TODO(b/373709676) Need to figure out how adjacentRoots work for flex split
+
+ // Make the stages adjacent to each other so they occlude what's behind them.
+ wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
+ mSplitLayout.getInvisibleBounds(mTempRect1);
+ wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
+ }
mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t -> {
- t.setPosition(mSideStage.mRootLeash, mTempRect1.left, mTempRect1.top);
- });
- mLaunchAdjacentController.setLaunchAdjacentRoot(mSideStage.mRootTaskInfo.token);
+ if (!enableFlexibleSplit()) {
+ mSyncQueue.runInSync(t -> {
+ t.setPosition(mSideStage.mRootLeash, mTempRect1.left, mTempRect1.top);
+ });
+ mLaunchAdjacentController.setLaunchAdjacentRoot(mSideStage.mRootTaskInfo.token);
+ } else {
+ // TODO(b/373709676) Need to figure out how adjacentRoots work for flex split
+ }
}
@Override
@@ -1876,11 +2177,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mDividerFadeInAnimator.cancel();
}
- mSplitLayout.getRefDividerBounds(mTempRect1);
if (t != null) {
+ updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
t.setVisibility(dividerLeash, mDividerVisible);
- t.setLayer(dividerLeash, Integer.MAX_VALUE);
- t.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
} else if (mDividerVisible) {
final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
mDividerFadeInAnimator = ValueAnimator.ofFloat(0f, 1f);
@@ -1900,11 +2199,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mDividerFadeInAnimator.cancel();
return;
}
- mSplitLayout.getRefDividerBounds(mTempRect1);
+ updateSurfaceBounds(mSplitLayout, transaction, false /* applyResizingOffset */);
transaction.show(dividerLeash);
transaction.setAlpha(dividerLeash, 0);
- transaction.setLayer(dividerLeash, Integer.MAX_VALUE);
- transaction.setPosition(dividerLeash, mTempRect1.left, mTempRect1.top);
transaction.apply();
}
@@ -1958,15 +2255,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
@Override
- public void onSnappedToDismiss(boolean bottomOrRight, @ExitReason int exitReason) {
+ public void onSnappedToDismiss(boolean closedBottomRightStage, @ExitReason int exitReason) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onSnappedToDismiss: bottomOrRight=%b reason=%s",
- bottomOrRight, exitReasonToString(exitReason));
- final boolean mainStageToTop =
- bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
+ closedBottomRightStage, exitReasonToString(exitReason));
+ boolean mainStageToTop =
+ closedBottomRightStage ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
: mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
- final StageTaskListener toTopStage = mainStageToTop ? mMainStage : mSideStage;
-
- final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
+ StageTaskListener toTopStage = mainStageToTop ? mMainStage : mSideStage;
+ int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
+ if (enableFlexibleSplit()) {
+ toTopStage = mStageOrderOperator.getStageForLegacyPosition(closedBottomRightStage
+ ? SPLIT_POSITION_TOP_OR_LEFT
+ : SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ false /*checkAllStagesIfNotActive*/);
+ dismissTop = toTopStage.getId();
+ }
final WindowContainerTransaction wct = new WindowContainerTransaction();
toTopStage.resetBounds(wct);
prepareExitSplitScreen(dismissTop, wct);
@@ -1998,8 +2301,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
updateSurfaceBounds(layout, t, shouldUseParallaxEffect);
getMainStageBounds(mTempRect1);
getSideStageBounds(mTempRect2);
- mMainStage.onResizing(mTempRect1, mTempRect2, t, offsetX, offsetY, mShowDecorImmediately);
- mSideStage.onResizing(mTempRect2, mTempRect1, t, offsetX, offsetY, mShowDecorImmediately);
+ if (enableFlexibleSplit()) {
+ StageTaskListener ltStage =
+ mStageOrderOperator.getStageForLegacyPosition(SPLIT_POSITION_TOP_OR_LEFT,
+ false /*checkAllStagesIfNotActive*/);
+ StageTaskListener brStage =
+ mStageOrderOperator.getStageForLegacyPosition(SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ false /*checkAllStagesIfNotActive*/);
+ ltStage.onResizing(mTempRect1, mTempRect2, t, offsetX, offsetY, mShowDecorImmediately);
+ brStage.onResizing(mTempRect2, mTempRect1, t, offsetX, offsetY, mShowDecorImmediately);
+ } else {
+ mMainStage.onResizing(mTempRect1, mTempRect2, t, offsetX, offsetY,
+ mShowDecorImmediately);
+ mSideStage.onResizing(mTempRect2, mTempRect1, t, offsetX, offsetY,
+ mShowDecorImmediately);
+ }
t.apply();
mTransactionPool.release(t);
}
@@ -2015,19 +2331,34 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!sizeChanged) {
// We still need to resize on decor for ensure all current status clear.
final SurfaceControl.Transaction t = mTransactionPool.acquire();
- mMainStage.onResized(t);
- mSideStage.onResized(t);
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stage -> stage.onResized(t));
+ } else {
+ mMainStage.onResized(t);
+ mSideStage.onResized(t);
+ }
mTransactionPool.release(t);
return;
}
-
+ List<SplitDecorManager> decorManagers = new ArrayList<>();
+ SplitDecorManager mainDecor = null;
+ SplitDecorManager sideDecor = null;
+ if (enableFlexibleSplit()) {
+ decorManagers = mStageOrderOperator.getActiveStages().stream()
+ .map(StageTaskListener::getSplitDecorManager)
+ .toList();
+ } else {
+ mainDecor = mMainStage.getSplitDecorManager();
+ sideDecor = mSideStage.getSplitDecorManager();
+ }
sendOnBoundsChanged();
mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart");
mSplitTransitions.startResizeTransition(wct, this, (aborted) -> {
mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed");
}, (finishWct, t) -> {
mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish");
- }, mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager());
+ mSplitLayout.populateTouchZones();
+ }, mainDecor, sideDecor, decorManagers);
if (Flags.enableFlexibleTwoAppSplit()) {
switch (layout.calculateCurrentSnapPosition()) {
@@ -2054,29 +2385,55 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
* @return true if stage bounds actually .
*/
private boolean updateWindowBounds(SplitLayout layout, WindowContainerTransaction wct) {
- final StageTaskListener topLeftStage =
- mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
- final StageTaskListener bottomRightStage =
- mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
+ final StageTaskListener topLeftStage;
+ final StageTaskListener bottomRightStage;
+ if (enableFlexibleSplit()) {
+ topLeftStage = mStageOrderOperator
+ .getStageForLegacyPosition(SPLIT_POSITION_TOP_OR_LEFT,
+ true /*checkAllStagesIfNotActive*/);
+ bottomRightStage = mStageOrderOperator
+ .getStageForLegacyPosition(SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ true /*checkAllStagesIfNotActive*/);
+ } else {
+ topLeftStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
+ ? mSideStage
+ : mMainStage;
+ bottomRightStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
+ ? mMainStage
+ : mSideStage;
+ }
boolean updated = layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo,
bottomRightStage.mRootTaskInfo);
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "updateWindowBounds: topLeftStage=%s bottomRightStage=%s",
- layout.getBounds1(), layout.getBounds2());
+ layout.getTopLeftBounds(), layout.getBottomRightBounds());
return updated;
}
void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t,
boolean applyResizingOffset) {
- final StageTaskListener topLeftStage =
- mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
- final StageTaskListener bottomRightStage =
- mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
+ final StageTaskListener topLeftStage;
+ final StageTaskListener bottomRightStage;
+ if (enableFlexibleSplit()) {
+ topLeftStage = mStageOrderOperator
+ .getStageForLegacyPosition(SPLIT_POSITION_TOP_OR_LEFT,
+ true /*checkAllStagesIfNotActive*/);
+ bottomRightStage = mStageOrderOperator
+ .getStageForLegacyPosition(SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ true /*checkAllStagesIfNotActive*/);
+ } else {
+ topLeftStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
+ ? mSideStage
+ : mMainStage;
+ bottomRightStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
+ ? mMainStage
+ : mSideStage;
+ }
(layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash,
bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer,
applyResizingOffset);
ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
"updateSurfaceBounds: topLeftStage=%s bottomRightStage=%s",
- layout.getBounds1(), layout.getBounds2());
+ layout.getTopLeftBounds(), layout.getBottomRightBounds());
}
@Override
@@ -2085,10 +2442,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return SPLIT_POSITION_UNDEFINED;
}
- if (mMainStage.containsToken(token)) {
- return getMainStagePosition();
- } else if (mSideStage.containsToken(token)) {
- return getSideStagePosition();
+ if (enableFlexibleSplit()) {
+ // We could migrate to/return the new INDEX enums here since most callers just care that
+ // this value isn't SPLIT_POSITION_UNDEFINED, but
+ // ImePositionProcessor#getImeTargetPosition actually uses the leftTop/bottomRight value
+ StageTaskListener stageForToken = mStageOrderOperator.getAllStages().stream()
+ .filter(stage -> stage.containsToken(token))
+ .findFirst().orElse(null);
+ return stageForToken == null
+ ? SPLIT_POSITION_UNDEFINED
+ : mStageOrderOperator.getLegacyPositionForStage(stageForToken);
+ } else {
+ if (mMainStage.containsToken(token)) {
+ return getMainStagePosition();
+ } else if (mSideStage.containsToken(token)) {
+ return getSideStagePosition();
+ }
}
return SPLIT_POSITION_UNDEFINED;
@@ -2185,27 +2554,49 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private Rect getSideStageBounds() {
return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
- ? mSplitLayout.getBounds1() : mSplitLayout.getBounds2();
+ ? mSplitLayout.getTopLeftBounds() : mSplitLayout.getBottomRightBounds();
}
private Rect getMainStageBounds() {
return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
- ? mSplitLayout.getBounds2() : mSplitLayout.getBounds1();
+ ? mSplitLayout.getBottomRightBounds() : mSplitLayout.getTopLeftBounds();
}
+ /**
+ * TODO(b/349828130) Currently the way this is being used is only to to get the bottomRight
+ * stage. Eventually we'll need to rename and for now we'll repurpose the method to return
+ * the bottomRight bounds under the flex split flag
+ */
private void getSideStageBounds(Rect rect) {
- if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
- mSplitLayout.getBounds1(rect);
+ if (enableFlexibleSplit()) {
+ // Split Layout doesn't actually keep track of the bounds based on the stage,
+ // it only knows that bounds1 is leftTop position and bounds2 is bottomRight position
+ // We'll then assume this method is to get bounds of bottomRight stage
+ mSplitLayout.copyBottomRightBounds(rect);
+ } else if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
+ mSplitLayout.copyTopLeftBounds(rect);
} else {
- mSplitLayout.getBounds2(rect);
+ mSplitLayout.copyBottomRightBounds(rect);
}
}
+ /**
+ * TODO(b/349828130) Currently the way this is being used is only to to get the leftTop
+ * stage. Eventually we'll need to rename and for now we'll repurpose the method to return
+ * the leftTop bounds under the flex split flag
+ */
private void getMainStageBounds(Rect rect) {
- if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
- mSplitLayout.getBounds2(rect);
+ if (enableFlexibleSplit()) {
+ // Split Layout doesn't actually keep track of the bounds based on the stage,
+ // it only knows that bounds1 is leftTop position and bounds2 is bottomRight position
+ // We'll then assume this method is to get bounds of topLeft stage
+ mSplitLayout.copyTopLeftBounds(rect);
} else {
- mSplitLayout.getBounds1(rect);
+ if (mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT) {
+ mSplitLayout.copyBottomRightBounds(rect);
+ } else {
+ mSplitLayout.copyTopLeftBounds(rect);
+ }
}
}
@@ -2214,14 +2605,23 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
* this task (yet) so this can also be used to identify which stage to put a task into.
*/
private StageTaskListener getStageOfTask(ActivityManager.RunningTaskInfo taskInfo) {
- // TODO(b/184679596): Find a way to either include task-org information in the transition,
- // or synchronize task-org callbacks so we can use stage.containsTask
- if (mMainStage.mRootTaskInfo != null
- && taskInfo.parentTaskId == mMainStage.mRootTaskInfo.taskId) {
- return mMainStage;
- } else if (mSideStage.mRootTaskInfo != null
- && taskInfo.parentTaskId == mSideStage.mRootTaskInfo.taskId) {
- return mSideStage;
+ if (enableFlexibleSplit()) {
+ return mStageOrderOperator.getActiveStages().stream()
+ .filter((stage) -> stage.mRootTaskInfo != null &&
+ taskInfo.parentTaskId == stage.mRootTaskInfo.taskId
+ )
+ .findFirst()
+ .orElse(null);
+ } else {
+ // TODO(b/184679596): Find a way to either include task-org information in the
+ // transition, or synchronize task-org callbacks so we can use stage.containsTask
+ if (mMainStage.mRootTaskInfo != null
+ && taskInfo.parentTaskId == mMainStage.mRootTaskInfo.taskId) {
+ return mMainStage;
+ } else if (mSideStage.mRootTaskInfo != null
+ && taskInfo.parentTaskId == mSideStage.mRootTaskInfo.taskId) {
+ return mSideStage;
+ }
}
return null;
}
@@ -2229,7 +2629,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@StageType
private int getStageType(StageTaskListener stage) {
if (stage == null) return STAGE_TYPE_UNDEFINED;
- return stage == mMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
+ if (enableFlexibleSplit()) {
+ return stage.getId();
+ } else {
+ return stage == mMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
+ }
}
@Override
@@ -2276,11 +2680,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (isSplitActive()) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "handleRequest: transition=%d split active",
request.getDebugId());
+ StageTaskListener primaryStage = enableFlexibleSplit()
+ ? mStageOrderOperator.getActiveStages().get(0)
+ : mMainStage;
+ StageTaskListener secondaryStage = enableFlexibleSplit()
+ ? mStageOrderOperator.getActiveStages().get(1)
+ : mSideStage;
// Try to handle everything while in split-screen, so return a WCT even if it's empty.
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " split is active so using split"
+ "Transition to handle request. triggerTask=%d type=%s mainChildren=%d"
+ " sideChildren=%d", triggerTask.taskId, transitTypeToString(type),
- mMainStage.getChildCount(), mSideStage.getChildCount());
+ primaryStage.getChildCount(), secondaryStage.getChildCount());
out = new WindowContainerTransaction();
if (stage != null) {
if (isClosingType(type) && stage.getChildCount() == 1) {
@@ -2320,11 +2730,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// the remote handler.
return null;
}
-
- if ((mMainStage.containsTask(triggerTask.taskId)
- && mMainStage.getChildCount() == 1)
- || (mSideStage.containsTask(triggerTask.taskId)
- && mSideStage.getChildCount() == 1)) {
+ boolean anyStageContainsSingleFullscreenTask;
+ if (enableFlexibleSplit()) {
+ anyStageContainsSingleFullscreenTask =
+ mStageOrderOperator.getActiveStages().stream()
+ .anyMatch(stageListener ->
+ stageListener.containsTask(triggerTask.taskId)
+ && stageListener.getChildCount() == 1);
+ } else {
+ anyStageContainsSingleFullscreenTask =
+ (mMainStage.containsTask(triggerTask.taskId)
+ && mMainStage.getChildCount() == 1)
+ || (mSideStage.containsTask(triggerTask.taskId)
+ && mSideStage.getChildCount() == 1);
+ }
+ if (anyStageContainsSingleFullscreenTask) {
// A splitting task is opening to fullscreen causes one side of the split empty,
// so appends operations to exit split.
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, out);
@@ -2344,11 +2764,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// One of the cases above handled it
return out;
} else if (isSplitScreenVisible()) {
+ boolean allStagesHaveChildren;
+ if (enableFlexibleSplit()) {
+ allStagesHaveChildren = runForActiveStagesAllMatch(stageTaskListener ->
+ stageTaskListener.getChildCount() != 0);
+ } else {
+ allStagesHaveChildren = mMainStage.getChildCount() != 0
+ && mSideStage.getChildCount() != 0;
+ }
// If split is visible, only defer handling this transition if it's launching
// adjacent while there is already a split pair -- this may trigger PIP and
// that should be handled by the mixed handler.
final boolean deferTransition = requestHasLaunchAdjacentFlag(request)
- && mMainStage.getChildCount() != 0 && mSideStage.getChildCount() != 0;
+ && allStagesHaveChildren;
return !deferTransition ? out : null;
}
// Don't intercept the transition if we are not handling it as a part of one of the
@@ -2493,26 +2921,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mTaskOrganizer.applyTransaction(wct);
}
continue;
- } else if (Flags.enableFlexibleTwoAppSplit() && isOrderOnly(change)) {
- int focusedStageIndex = SPLIT_INDEX_UNDEFINED;
- if (taskInfo.token.equals(mMainStage.mRootTaskInfo.token)) {
- focusedStageIndex = mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
- ? SPLIT_INDEX_0 : SPLIT_INDEX_1;
- } else if (taskInfo.token.equals(mSideStage.mRootTaskInfo.token)) {
- focusedStageIndex = mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
- ? SPLIT_INDEX_1 : SPLIT_INDEX_0;
- }
-
- if (focusedStageIndex != SPLIT_INDEX_UNDEFINED) {
- @PersistentSnapPosition int currentSnapPosition =
- mSplitLayout.calculateCurrentSnapPosition();
- boolean offscreenTaskFocused =
- isPartiallyOffscreen(focusedStageIndex, currentSnapPosition);
-
- if (offscreenTaskFocused) {
- mSplitLayout.flingDividerToOtherSide(currentSnapPosition);
- }
- }
}
final StageTaskListener stage = getStageOfTask(taskInfo);
if (stage == null) {
@@ -2588,8 +2996,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage();
- if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
- || dismissStages.size() == 1) {
+ boolean anyStageHasNoChildren;
+ if (enableFlexibleSplit()) {
+ anyStageHasNoChildren = mStageOrderOperator.getActiveStages().stream()
+ .anyMatch(stage -> stage.getChildCount() == 0);
+ } else {
+ anyStageHasNoChildren = mMainStage.getChildCount() == 0
+ || mSideStage.getChildCount() == 0;
+ }
+ if (anyStageHasNoChildren || dismissStages.size() == 1) {
// If the size of dismissStages == 1, one of the task is closed without prepare
// pending transition, which could happen if all activities were finished after
// finish top activity in a task, so the trigger task is null when handleRequest.
@@ -2735,24 +3150,48 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
shouldAnimate = startPendingDismissAnimation(
dismiss, info, startTransaction, finishTransaction);
if (shouldAnimate && dismiss.mReason == EXIT_REASON_DRAG_DIVIDER) {
- final StageTaskListener toTopStage =
- dismiss.mDismissTop == STAGE_TYPE_MAIN ? mMainStage : mSideStage;
+ StageTaskListener toTopStage;
+ if (enableFlexibleSplit()) {
+ toTopStage = mStageOrderOperator.getAllStages().stream()
+ .filter(stage -> stage.getId() == dismiss.mDismissTop)
+ .findFirst().orElseThrow();
+ } else {
+ toTopStage = dismiss.mDismissTop == STAGE_TYPE_MAIN ? mMainStage : mSideStage;
+ }
mSplitTransitions.playDragDismissAnimation(transition, info, startTransaction,
finishTransaction, finishCallback, toTopStage.mRootTaskInfo.token,
toTopStage.getSplitDecorManager(), mRootTaskInfo.token);
return true;
}
} else if (mSplitTransitions.isPendingResize(transition)) {
+ Map<WindowContainerToken, SplitDecorManager> tokenDecorMap = new HashMap<>();
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stageTaskListener ->
+ tokenDecorMap.put(stageTaskListener.mRootTaskInfo.getToken(),
+ stageTaskListener.getSplitDecorManager()));
+ } else {
+ tokenDecorMap.put(mMainStage.mRootTaskInfo.getToken(),
+ mMainStage.getSplitDecorManager());
+ tokenDecorMap.put(mSideStage.mRootTaskInfo.getToken(),
+ mSideStage.getSplitDecorManager());
+ }
mSplitTransitions.playResizeAnimation(transition, info, startTransaction,
- finishTransaction, finishCallback, mMainStage.mRootTaskInfo.token,
- mSideStage.mRootTaskInfo.token, mMainStage.getSplitDecorManager(),
- mSideStage.getSplitDecorManager());
+ finishTransaction, finishCallback, tokenDecorMap);
return true;
}
if (!shouldAnimate) return false;
+ WindowContainerToken mainToken;
+ WindowContainerToken sideToken;
+ if (enableFlexibleSplit()) {
+ mainToken = mStageOrderOperator.getActiveStages().get(0).mRootTaskInfo.token;
+ sideToken = mStageOrderOperator.getActiveStages().get(1).mRootTaskInfo.token;
+ } else {
+ mainToken = mMainStage.mRootTaskInfo.token;
+ sideToken = mSideStage.mRootTaskInfo.token;
+ }
mSplitTransitions.playAnimation(transition, info, startTransaction, finishTransaction,
- finishCallback, mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token,
+ finishCallback, mainToken, sideToken,
mRootTaskInfo.token);
return true;
}
@@ -2777,6 +3216,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// First, verify that we actually have opened apps in both splits.
TransitionInfo.Change mainChild = null;
TransitionInfo.Change sideChild = null;
+ StageTaskListener firstAppStage = null;
+ StageTaskListener secondAppStage = null;
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
for (int iC = 0; iC < info.getChanges().size(); ++iC) {
final TransitionInfo.Change change = info.getChanges().get(iC);
@@ -2785,14 +3226,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (mPausingTasks.contains(taskInfo.taskId)) {
continue;
}
- final @StageType int stageType = getStageType(getStageOfTask(taskInfo));
- if (mainChild == null && stageType == STAGE_TYPE_MAIN
+ StageTaskListener stage = getStageOfTask(taskInfo);
+ final @StageType int stageType = getStageType(stage);
+ if (mainChild == null
+ && stageType == (enableFlexibleSplit() ? STAGE_TYPE_A : STAGE_TYPE_MAIN)
&& (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
// Includes TRANSIT_CHANGE to cover reparenting top-most task to split.
mainChild = change;
- } else if (sideChild == null && stageType == STAGE_TYPE_SIDE
+ firstAppStage = getStageOfTask(taskInfo);
+ } else if (sideChild == null
+ && stageType == (enableFlexibleSplit() ? STAGE_TYPE_B : STAGE_TYPE_SIDE)
&& (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
sideChild = change;
+ secondAppStage = stage;
} else if (stageType != STAGE_TYPE_UNDEFINED && change.getMode() == TRANSIT_TO_BACK) {
// Collect all to back task's and evict them when transition finished.
evictWct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
@@ -2848,9 +3294,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// TODO(b/184679596): Find a way to either include task-org information in
// the transition, or synchronize task-org callbacks.
final boolean mainNotContainOpenTask =
- mainChild != null && !mMainStage.containsTask(mainChild.getTaskInfo().taskId);
+ mainChild != null && !firstAppStage.containsTask(mainChild.getTaskInfo().taskId);
final boolean sideNotContainOpenTask =
- sideChild != null && !mSideStage.containsTask(sideChild.getTaskInfo().taskId);
+ sideChild != null && !secondAppStage.containsTask(sideChild.getTaskInfo().taskId);
if (mainNotContainOpenTask) {
Log.w(TAG, "Expected onTaskAppeared on " + mMainStage
+ " to have been called with " + mainChild.getTaskInfo().taskId
@@ -2863,6 +3309,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
final TransitionInfo.Change finalMainChild = mainChild;
final TransitionInfo.Change finalSideChild = sideChild;
+ final StageTaskListener finalFirstAppStage = firstAppStage;
+ final StageTaskListener finalSecondAppStage = secondAppStage;
enterTransition.setFinishedCallback((callbackWct, callbackT) -> {
if (!enterTransition.mResizeAnim) {
// If resizing, we'll call notify at the end of the resizing animation (below)
@@ -2870,16 +3318,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
if (finalMainChild != null) {
if (!mainNotContainOpenTask) {
- mMainStage.evictOtherChildren(callbackWct, finalMainChild.getTaskInfo().taskId);
+ finalFirstAppStage.evictOtherChildren(callbackWct,
+ finalMainChild.getTaskInfo().taskId);
} else {
- mMainStage.evictInvisibleChildren(callbackWct);
+ finalFirstAppStage.evictInvisibleChildren(callbackWct);
}
}
if (finalSideChild != null) {
if (!sideNotContainOpenTask) {
- mSideStage.evictOtherChildren(callbackWct, finalSideChild.getTaskInfo().taskId);
+ finalSecondAppStage.evictOtherChildren(callbackWct,
+ finalSideChild.getTaskInfo().taskId);
} else {
- mSideStage.evictInvisibleChildren(callbackWct);
+ finalSecondAppStage.evictInvisibleChildren(callbackWct);
}
}
if (!evictWct.isEmpty()) {
@@ -2961,8 +3411,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
public void onPipExpandToSplit(WindowContainerTransaction wct,
ActivityManager.RunningTaskInfo taskInfo) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onPipExpandToSplit: task=%s", taskInfo);
+ // TODO(b/349828130) currently pass in index_undefined until we can revisit these
+ // flex split + pip interactions in the future
prepareEnterSplitScreen(wct, taskInfo, getActivateSplitPosition(taskInfo),
- false /*resizeAnim*/);
+ false /*resizeAnim*/, SPLIT_INDEX_UNDEFINED);
if (!isSplitScreenVisible() || mSplitRequest == null) {
return;
@@ -3067,13 +3519,28 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Wait until after animation to update divider
// Reset crops so they don't interfere with subsequent launches
- t.setCrop(mMainStage.mRootLeash, null);
- t.setCrop(mSideStage.mRootLeash, null);
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stage -> t.setCrop(stage.mRootLeash, null /*crop*/));
+ } else {
+ t.setCrop(mMainStage.mRootLeash, null);
+ t.setCrop(mSideStage.mRootLeash, null);
+ }
// Hide the non-top stage and set the top one to the fullscreen position.
if (toStage != STAGE_TYPE_UNDEFINED) {
- t.hide(toStage == STAGE_TYPE_MAIN ? mSideStage.mRootLeash : mMainStage.mRootLeash);
- t.setPosition(toStage == STAGE_TYPE_MAIN
- ? mMainStage.mRootLeash : mSideStage.mRootLeash, 0, 0);
+ if (enableFlexibleSplit()) {
+ StageTaskListener stageToKeep = mStageOrderOperator.getAllStages().stream()
+ .filter(stage -> stage.getId() == toStage)
+ .findFirst().orElseThrow();
+ List<StageTaskListener> stagesToHide = mStageOrderOperator.getAllStages().stream()
+ .filter(stage -> stage.getId() != toStage)
+ .toList();
+ stagesToHide.forEach(stage -> t.hide(stage.mRootLeash));
+ t.setPosition(stageToKeep.mRootLeash, 0, 0);
+ } else {
+ t.hide(toStage == STAGE_TYPE_MAIN ? mSideStage.mRootLeash : mMainStage.mRootLeash);
+ t.setPosition(toStage == STAGE_TYPE_MAIN
+ ? mMainStage.mRootLeash : mSideStage.mRootLeash, 0, 0);
+ }
} else {
for (int i = dismissingTasks.keySet().size() - 1; i >= 0; --i) {
finishT.hide(dismissingTasks.valueAt(i));
@@ -3088,8 +3555,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Hide divider and dim layer on transition finished.
setDividerVisibility(false, t);
- finishT.hide(mMainStage.mDimLayer);
- finishT.hide(mSideStage.mDimLayer);
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stage -> finishT.hide(stage.mRootLeash));
+ } else {
+ finishT.hide(mMainStage.mDimLayer);
+ finishT.hide(mSideStage.mDimLayer);
+ }
}
private boolean startPendingDismissAnimation(
@@ -3110,8 +3581,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return false;
}
dismissTransition.setFinishedCallback((callbackWct, callbackT) -> {
- mMainStage.getSplitDecorManager().release(callbackT);
- mSideStage.getSplitDecorManager().release(callbackT);
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stage -> stage.getSplitDecorManager().release(callbackT));
+ } else {
+ mMainStage.getSplitDecorManager().release(callbackT);
+ mSideStage.getSplitDecorManager().release(callbackT);
+ }
callbackWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, false);
});
return true;
@@ -3128,8 +3603,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (TransitionUtil.isClosingType(change.getMode())
&& change.getTaskInfo() != null) {
final int taskId = change.getTaskInfo().taskId;
- if (mMainStage.getTopVisibleChildTaskId() == taskId
- || mSideStage.getTopVisibleChildTaskId() == taskId) {
+ boolean anyStagesHaveTask;
+ if (enableFlexibleSplit()) {
+ anyStagesHaveTask = mStageOrderOperator.getActiveStages().stream()
+ .anyMatch(stage -> stage.getTopVisibleChildTaskId() == taskId);
+ } else {
+ anyStagesHaveTask = mMainStage.getTopVisibleChildTaskId() == taskId
+ || mSideStage.getTopVisibleChildTaskId() == taskId;
+ }
+ if (anyStagesHaveTask) {
mPausingTasks.add(taskId);
}
}
@@ -3161,9 +3643,16 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final WindowContainerTransaction.HierarchyOp op =
finishWct.getHierarchyOps().get(i);
final IBinder container = op.getContainer();
+ boolean anyStageContainsContainer;
+ if (enableFlexibleSplit()) {
+ anyStageContainsContainer = mStageOrderOperator.getActiveStages().stream()
+ .anyMatch(stage -> stage.containsContainer(container));
+ } else {
+ anyStageContainsContainer = mMainStage.containsContainer(container)
+ || mSideStage.containsContainer(container);
+ }
if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
- && (mMainStage.containsContainer(container)
- || mSideStage.containsContainer(container))) {
+ && anyStageContainsContainer) {
updateSurfaceBounds(mSplitLayout, finishT,
false /* applyResizingOffset */);
finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);
@@ -3190,10 +3679,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// user entering recents.
for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
final int taskId = mPausingTasks.get(i);
- if (mMainStage.containsTask(taskId)) {
- mMainStage.evictChild(finishWct, taskId, "recentsPairToPair");
- } else if (mSideStage.containsTask(taskId)) {
- mSideStage.evictChild(finishWct, taskId, "recentsPairToPair");
+ if (enableFlexibleSplit()) {
+ mStageOrderOperator.getActiveStages().stream()
+ .filter(stage -> stage.containsTask(taskId))
+ .findFirst()
+ .ifPresent(stageToEvict ->
+ stageToEvict.evictChild(finishWct, taskId, "recentsPairToPair"));
+ } else {
+ if (mMainStage.containsTask(taskId)) {
+ mMainStage.evictChild(finishWct, taskId, "recentsPairToPair");
+ } else if (mSideStage.containsTask(taskId)) {
+ mSideStage.evictChild(finishWct, taskId, "recentsPairToPair");
+ }
}
}
// If pending enter hasn't consumed, the mix handler will invoke start pending
@@ -3256,8 +3753,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
*/
private void setSplitsVisible(boolean visible) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setSplitsVisible: visible=%b", visible);
- mMainStage.mVisible = mSideStage.mVisible = visible;
- mMainStage.mHasChildren = mSideStage.mHasChildren = visible;
+ if (enableFlexibleSplit()) {
+ runForActiveStages(stage -> {
+ stage.mVisible = visible;
+ stage.mHasChildren = visible;
+ });
+ } else {
+ mMainStage.mVisible = mSideStage.mVisible = visible;
+ mMainStage.mHasChildren = mSideStage.mHasChildren = visible;
+ }
}
/**
@@ -3300,6 +3804,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
* executed.
*/
private void logExitToStage(@ExitReason int exitReason, boolean toMainStage) {
+ if (enableFlexibleSplit()) {
+ // TODO(b/374825718) update logging for 2+ apps
+ return;
+ }
mLogger.logExit(exitReason,
toMainStage ? getMainStagePosition() : SPLIT_POSITION_UNDEFINED,
toMainStage ? mMainStage.getTopChildTaskUid() : 0 /* mainStageUid */,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
new file mode 100644
index 000000000000..b7b3c9b62a58
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageOrderOperator.kt
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.splitscreen
+
+import android.content.Context
+import com.android.internal.protolog.ProtoLog
+import com.android.launcher3.icons.IconProvider
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.protolog.ShellProtoLogGroup
+import com.android.wm.shell.shared.split.SplitScreenConstants
+import com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_NONE
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_0
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_1
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_2
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED
+import com.android.wm.shell.shared.split.SplitScreenConstants.SnapPosition
+import com.android.wm.shell.shared.split.SplitScreenConstants.SplitIndex
+import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition
+import com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_A
+import com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_B
+import com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_C
+import com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString
+import com.android.wm.shell.windowdecor.WindowDecorViewModel
+import java.util.Optional
+
+/**
+ * Responsible for creating [StageTaskListener]s and maintaining their ordering on screen.
+ * Must be notified whenever stages positions change via swapping or starting/ending tasks
+ */
+class StageOrderOperator (
+ context: Context,
+ taskOrganizer: ShellTaskOrganizer,
+ displayId: Int,
+ stageCallbacks: StageTaskListener.StageListenerCallbacks,
+ syncQueue: SyncTransactionQueue,
+ iconProvider: IconProvider,
+ windowDecorViewModel: Optional<WindowDecorViewModel>
+ ) {
+
+ private val MAX_STAGES = 3
+ /**
+ * This somewhat acts as a replacement to stageTypes in the intermediary, so we want to start
+ * it after the @StageType constant values just to be safe and avoid potentially subtle bugs.
+ */
+ private var stageIds = listOf(STAGE_TYPE_A, STAGE_TYPE_B, STAGE_TYPE_C)
+
+ /**
+ * Active Stages, this list represent the current, ordered list of stages that are
+ * currently visible to the user. This map should be empty if the user is currently
+ * not in split screen. Note that this is different than if split screen is visible, which
+ * is determined by [StageListenerImpl.mVisible].
+ * Split stages can be active and in the background
+ */
+ val activeStages = mutableListOf<StageTaskListener>()
+ val allStages = mutableListOf<StageTaskListener>()
+ var isActive: Boolean = false
+ var isVisible: Boolean = false
+ @SnapPosition private var currentLayout: Int = SNAP_TO_NONE
+
+ init {
+ for(i in 0 until MAX_STAGES) {
+ allStages.add(StageTaskListener(context,
+ taskOrganizer,
+ displayId,
+ stageCallbacks,
+ syncQueue,
+ iconProvider,
+ windowDecorViewModel,
+ stageIds[i])
+ )
+ }
+ }
+
+ /**
+ * Updates internal state to keep record of "active" stages. Note that this does NOT call
+ * [StageTaskListener.activate] on the stages.
+ */
+ fun onEnteringSplit(@SnapPosition goingToLayout: Int) {
+ if (goingToLayout == currentLayout) {
+ // Add protolog here. Return for now, but maybe we want to handle swap case, TBD
+ return
+ }
+ val freeStages: List<StageTaskListener> =
+ allStages.filterNot { activeStages.contains(it) }
+ when(goingToLayout) {
+ SplitScreenConstants.SNAP_TO_2_50_50 -> {
+ if (activeStages.size < 2) {
+ // take from allStages and add into activeStages
+ for (i in 0 until (2 - activeStages.size)) {
+ val stage = freeStages[i]
+ activeStages.add(stage)
+ }
+ }
+ }
+ }
+ ProtoLog.d(
+ ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "Activated stages: %d ids=%s",
+ activeStages.size,
+ activeStages.joinToString(",") { stageTypeToString(it.id) }
+ )
+ isActive = true
+ }
+
+ fun onExitingSplit() {
+ activeStages.clear()
+ isActive = false
+ }
+
+ /**
+ * Given a legacy [SplitPosition] returns one of the stages from the actives stages.
+ * If there are no active stages and [checkAllStagesIfNotActive] is not true, then will return
+ * null
+ */
+ fun getStageForLegacyPosition(@SplitPosition position: Int,
+ checkAllStagesIfNotActive : Boolean = false) :
+ StageTaskListener? {
+ if (activeStages.size != 2 && !checkAllStagesIfNotActive) {
+ return null
+ }
+ val listToCheck = if (activeStages.isEmpty() and checkAllStagesIfNotActive)
+ allStages else
+ activeStages
+ if (position == SPLIT_POSITION_TOP_OR_LEFT) {
+ return listToCheck[0]
+ } else if (position == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ return listToCheck[1]
+ } else {
+ throw IllegalArgumentException("No stage for invalid position")
+ }
+ }
+
+ /**
+ * Returns a legacy split position for the given stage. If no stages are active then this will
+ * return [SPLIT_POSITION_UNDEFINED]
+ */
+ @SplitPosition
+ fun getLegacyPositionForStage(stage: StageTaskListener) : Int {
+ if (allStages[0] == stage) {
+ return SPLIT_POSITION_TOP_OR_LEFT
+ } else if (allStages[1] == stage) {
+ return SPLIT_POSITION_BOTTOM_OR_RIGHT
+ } else {
+ return SPLIT_POSITION_UNDEFINED
+ }
+ }
+
+ /**
+ * Returns the stageId from a given splitIndex. This will default to checking from all stages if
+ * [isActive] is false, otherwise will only check active stages.
+ */
+ fun getStageForIndex(@SplitIndex splitIndex: Int) : StageTaskListener {
+ // Probably should do a check for index to be w/in the bounds of the current split layout
+ // that we're currently in
+ val listToCheck = if (isActive) activeStages else allStages
+ if (splitIndex == SPLIT_INDEX_0) {
+ return listToCheck[0]
+ } else if (splitIndex == SPLIT_INDEX_1) {
+ return listToCheck[1]
+ } else if (splitIndex == SPLIT_INDEX_2) {
+ return listToCheck[2]
+ } else {
+ // Though I guess what if we're adding to the end? Maybe that indexing needs to be
+ // resolved elsewhere
+ throw IllegalStateException("No stage for the given splitIndex")
+ }
+ }
+} \ No newline at end of file
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 08cdfdb3b5a9..4a37169add36 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
@@ -22,10 +22,12 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
+import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE;
+import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
import android.annotation.CallSuper;
import android.annotation.Nullable;
@@ -72,6 +74,8 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
// No current way to enforce this but if enableFlexibleSplit() is enabled, then only 1 of the
// stages should have this be set/being used
private boolean mIsActive;
+ /** Unique identifier for this state, > 0 */
+ @StageType private final int mId;
/** Callback interface for listening to changes in a split-screen stage. */
public interface StageListenerCallbacks {
void onRootTaskAppeared();
@@ -110,13 +114,14 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
IconProvider iconProvider,
- Optional<WindowDecorViewModel> windowDecorViewModel) {
+ Optional<WindowDecorViewModel> windowDecorViewModel, int id) {
mContext = context;
mCallbacks = callbacks;
mSyncQueue = syncQueue;
mIconProvider = iconProvider;
mWindowDecorViewModel = windowDecorViewModel;
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
+ mId = id;
}
int getChildCount() {
@@ -161,6 +166,11 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
return contains(t -> t.isFocused);
}
+ @StageType
+ int getId() {
+ return mId;
+ }
+
private boolean contains(Predicate<ActivityManager.RunningTaskInfo> predicate) {
if (mRootTaskInfo != null && predicate.test(mRootTaskInfo)) {
return true;
@@ -197,10 +207,10 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
@CallSuper
public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskAppeared: taskId=%d taskParent=%d rootTask=%d "
- + "taskActivity=%s",
+ + "stageId=%s taskActivity=%s",
taskInfo.taskId, taskInfo.parentTaskId,
mRootTaskInfo != null ? mRootTaskInfo.taskId : -1,
- taskInfo.baseActivity);
+ stageTypeToString(mId), taskInfo.baseActivity);
if (mRootTaskInfo == null) {
mRootLeash = leash;
mRootTaskInfo = taskInfo;
@@ -230,8 +240,9 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
@CallSuper
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: taskId=%d taskAct=%s",
- taskInfo.taskId, taskInfo.baseActivity);
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: taskId=%d taskAct=%s "
+ + "stageId=%s",
+ taskInfo.taskId, taskInfo.baseActivity, stageTypeToString(mId));
mWindowDecorViewModel.ifPresent(viewModel -> viewModel.onTaskInfoChanged(taskInfo));
if (mRootTaskInfo.taskId == taskInfo.taskId) {
mRootTaskInfo = taskInfo;
@@ -261,7 +272,8 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
@Override
@CallSuper
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskVanished: task=%d", taskInfo.taskId);
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskVanished: task=%d stageId=%s",
+ taskInfo.taskId, stageTypeToString(mId));
final int taskId = taskInfo.taskId;
mWindowDecorViewModel.ifPresent(vm -> vm.onTaskVanished(taskInfo));
if (mRootTaskInfo.taskId == taskId) {
@@ -466,14 +478,17 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
void activate(WindowContainerTransaction wct, boolean includingTopTask) {
- if (mIsActive) return;
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "activate: includingTopTask=%b",
- includingTopTask);
+ if (mIsActive && !enableFlexibleSplit()) return;
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "activate: includingTopTask=%b stage=%s",
+ includingTopTask, stageTypeToString(mId));
if (includingTopTask) {
reparentTopTask(wct);
}
+ if (enableFlexibleSplit()) {
+ return;
+ }
mIsActive = true;
}
@@ -481,11 +496,14 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
deactivate(wct, false /* toTop */);
}
- void deactivate(WindowContainerTransaction wct, boolean toTop) {
- if (!mIsActive) return;
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "deactivate: toTop=%b rootTaskInfo=%s",
- toTop, mRootTaskInfo);
- mIsActive = false;
+ void deactivate(WindowContainerTransaction wct, boolean reparentTasksToTop) {
+ if (!mIsActive && !enableFlexibleSplit()) return;
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "deactivate: reparentTasksToTop=%b "
+ + "rootTaskInfo=%s stage=%s",
+ reparentTasksToTop, mRootTaskInfo, stageTypeToString(mId));
+ if (!enableFlexibleSplit()) {
+ mIsActive = false;
+ }
if (mRootTaskInfo == null) return;
final WindowContainerToken rootToken = mRootTaskInfo.token;
@@ -494,14 +512,15 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
null /* newParent */,
null /* windowingModes */,
null /* activityTypes */,
- toTop);
+ reparentTasksToTop);
}
// --------
- // Previously only used in SideStage
+ // Previously only used in SideStage. With flexible split this is called for all stages
boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "remove all side stage tasks: childCount=%d toTop=%b",
- mChildrenTaskInfo.size(), toTop);
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "remove all side stage tasks: childCount=%d toTop=%b "
+ + " stageI=%s",
+ mChildrenTaskInfo.size(), toTop, stageTypeToString(mId));
if (mChildrenTaskInfo.size() == 0) return false;
wct.reparentTasks(
mRootTaskInfo.token,
@@ -522,6 +541,15 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
}
@Override
+ public String toString() {
+ return "mId: " + stageTypeToString(mId)
+ + " mVisible: " + mVisible
+ + " mActive: " + mIsActive
+ + " mHasRootTask: " + mHasRootTask
+ + " childSize: " + mChildrenTaskInfo.size();
+ }
+
+ @Override
@CallSuper
public void dump(@NonNull PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
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 17483dd68632..92d1f9c26bbc 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
@@ -370,7 +370,8 @@ public class DefaultMixedHandler implements MixedTransitionHandler,
if (mRecentsHandler != null) {
if (mSplitHandler.isSplitScreenVisible()) {
return this::setRecentsTransitionDuringSplit;
- } else if (mKeyguardHandler.isKeyguardShowing()) {
+ } else if (mKeyguardHandler.isKeyguardShowing()
+ && !mKeyguardHandler.isKeyguardAnimating()) {
return this::setRecentsTransitionDuringKeyguard;
} else if (mDesktopTasksController != null
// Check on the default display. Recents/gesture nav is only available there
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
index fd4d568326d0..8cdbe26a2c76 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
@@ -117,6 +117,11 @@ class RecentsMixedTransition extends DefaultMixedHandler.MixedTransition {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Mixed transition for Recents during"
+ " Keyguard #%d", info.getDebugId());
+ if (!mKeyguardHandler.isKeyguardShowing() || mKeyguardHandler.isKeyguardAnimating()) {
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Cancel mixed transition because "
+ + "keyguard state was changed #%d", info.getDebugId());
+ return false;
+ }
if (mInfo == null) {
mInfo = info;
mFinishT = finishTransaction;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
index d28287da83b6..32f3cd820421 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
@@ -334,8 +334,8 @@ public class SplitTaskUnfoldAnimator implements UnfoldTaskAnimator,
// Sides adjacent to split bar or task bar are not be animated.
Insets margins;
- final boolean isLandscape = mRootStageBounds.width() > mRootStageBounds.height();
- if (isLandscape) { // Left and right splits.
+ final boolean isLeftRightSplit = mSplitScreenController.get().get().isLeftRightSplit();
+ if (isLeftRightSplit) {
margins = getLandscapeMargins(margin, taskbarExpanded);
} else { // Top and bottom splits.
margins = getPortraitMargins(margin, taskbarExpanded);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
index 7b71e41874c7..b8c91519422c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
@@ -23,6 +23,7 @@ import android.graphics.Rect
import android.view.WindowManager
import android.window.TaskSnapshot
import androidx.compose.ui.graphics.toArgb
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.ManageWindowsViewContainer
import com.android.wm.shell.shared.split.SplitScreenConstants
import com.android.wm.shell.splitscreen.SplitScreenController
@@ -101,6 +102,7 @@ class DesktopHandleManageWindowsMenu(
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
view = menuView.rootView,
+ ignoreCutouts = DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context),
)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index f89b0d108bad..43ed23b3b52a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -33,6 +33,7 @@ import static android.view.WindowInsets.Type.statusBars;
import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
+import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod;
import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
@@ -78,6 +79,7 @@ import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.WindowManager;
import android.window.DesktopModeFlags;
import android.window.TaskSnapshot;
import android.window.WindowContainerToken;
@@ -412,7 +414,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
} catch (RemoteException e) {
Log.e(TAG, "Failed to register window manager callbacks", e);
}
- if (DesktopModeStatus.canEnterDesktopMode(mContext)
+ if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(mContext)
&& Flags.enableDesktopWindowingAppHandleEducation()) {
mAppHandleEducationController.setAppHandleEducationTooltipCallbacks(
/* appHandleTooltipClickCallback= */(taskId) -> {
@@ -589,7 +591,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.closeMaximizeMenu();
}
- public void onSnapResize(int taskId, boolean left, @Nullable MotionEvent motionEvent) {
+ public void onSnapResize(int taskId, boolean left, InputMethod inputMethod) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
if (decoration == null) {
return;
@@ -601,7 +603,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.mTaskInfo,
left ? SnapPosition.LEFT : SnapPosition.RIGHT,
left ? ResizeTrigger.SNAP_LEFT_MENU : ResizeTrigger.SNAP_RIGHT_MENU,
- motionEvent,
+ inputMethod,
decoration);
decoration.closeHandleMenu();
@@ -957,7 +959,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
public boolean handleMotionEvent(@Nullable View v, MotionEvent e) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
final RunningTaskInfo taskInfo = decoration.mTaskInfo;
- if (DesktopModeStatus.canEnterDesktopMode(mContext)
+ if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(mContext)
&& !taskInfo.isFreeform()) {
return handleNonFreeformMotionEvent(decoration, v, e);
} else {
@@ -1483,7 +1485,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
if (isPartOfDefaultHomePackage(taskInfo)) {
return false;
}
- return DesktopModeStatus.canEnterDesktopMode(mContext)
+ final boolean isOnLargeScreen = taskInfo.getConfiguration().smallestScreenWidthDp
+ >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
+ if (!DesktopModeStatus.canEnterDesktopMode(mContext)
+ && DesktopModeStatus.overridesShowAppHandle(mContext) && !isOnLargeScreen) {
+ // Devices with multiple screens may enable the app handle but it should not show on
+ // small screens
+ return false;
+ }
+ return DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(mContext)
&& !DesktopWallpaperActivity.isWallpaperTask(taskInfo)
&& taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED
&& taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
@@ -1544,6 +1554,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
final DesktopModeTouchEventListener touchEventListener =
new DesktopModeTouchEventListener(taskInfo, taskPositioner);
+ InputMethod inputMethod = DesktopModeEventLogger.Companion.getInputMethodFromMotionEvent(
+ touchEventListener.mMotionEvent);
windowDecoration.setOnMaximizeOrRestoreClickListener(() -> {
onMaximizeOrRestore(taskInfo.taskId, "maximize_menu", ResizeTrigger.MAXIMIZE_MENU,
touchEventListener.mMotionEvent);
@@ -1554,11 +1566,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
return Unit.INSTANCE;
});
windowDecoration.setOnLeftSnapClickListener(() -> {
- onSnapResize(taskInfo.taskId, /* isLeft= */ true, touchEventListener.mMotionEvent);
+ onSnapResize(taskInfo.taskId, /* isLeft= */ true, inputMethod);
return Unit.INSTANCE;
});
windowDecoration.setOnRightSnapClickListener(() -> {
- onSnapResize(taskInfo.taskId, /* isLeft= */ false, touchEventListener.mMotionEvent);
+ onSnapResize(taskInfo.taskId, /* isLeft= */ false, inputMethod);
return Unit.INSTANCE;
});
windowDecoration.setOnToDesktopClickListener(desktopModeTransitionSource -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 723bbd318803..b6fa059e891d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -30,6 +30,7 @@ import static android.window.DesktopModeFlags.ENABLE_CAPTION_COMPAT_INSET_FORCE_
import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode;
+import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopModeOrShowAppHandle;
import static com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.DisabledEdge;
@@ -1397,10 +1398,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mAppIconBitmap,
mAppName,
mSplitScreenController,
- canEnterDesktopMode(mContext),
+ canEnterDesktopModeOrShowAppHandle(mContext),
supportsMultiInstance,
shouldShowManageWindowsButton,
shouldShowChangeAspectRatioButton,
+ canEnterDesktopMode(mContext),
isBrowserApp,
isBrowserApp ? getAppLink() : getBrowserLink(),
mResult.mCaptionWidth,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 420409705b05..b3213996b868 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -460,7 +460,9 @@ class DragResizeInputListener implements AutoCloseable {
|| ctrlType == CTRL_TYPE_RIGHT || ctrlType == CTRL_TYPE_LEFT)
? ResizeTrigger.EDGE : ResizeTrigger.CORNER;
mDesktopModeEventLogger.logTaskResizingStarted(mResizeTrigger,
- e, mTaskInfo, /* displayController= */ null,
+ DesktopModeEventLogger.Companion.getInputMethodFromMotionEvent(e),
+ mTaskInfo, mDragStartTaskBounds.width(),
+ mDragStartTaskBounds.height(), /* displayController= */ null,
/* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
// Increase the input sink region to cover the whole screen; this is to
// prevent input and focus from going to other tasks during a drag resize.
@@ -512,8 +514,9 @@ class DragResizeInputListener implements AutoCloseable {
}
mDesktopModeEventLogger.logTaskResizingEnded(mResizeTrigger,
- mLastMotionEventOnDown, mTaskInfo, taskBounds.height(),
- taskBounds.width(),
+ DesktopModeEventLogger.Companion.getInputMethodFromMotionEvent(
+ mLastMotionEventOnDown), mTaskInfo, taskBounds.width(),
+ taskBounds.height(),
/* displayController= */ null,
/* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index 62be2c78d59b..049b8d621427 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -45,6 +45,7 @@ import androidx.annotation.StringRes
import androidx.annotation.VisibleForTesting
import androidx.compose.ui.graphics.toArgb
import androidx.core.view.isGone
+import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.apptoweb.isBrowserApp
import com.android.wm.shell.shared.split.SplitScreenConstants
@@ -75,6 +76,7 @@ class HandleMenu(
private val shouldShowNewWindowButton: Boolean,
private val shouldShowManageWindowsButton: Boolean,
private val shouldShowChangeAspectRatioButton: Boolean,
+ private val shouldShowDesktopModeButton: Boolean,
private val isBrowserApp: Boolean,
private val openInAppOrBrowserIntent: Intent?,
private val captionWidth: Int,
@@ -185,6 +187,7 @@ class HandleMenu(
shouldShowNewWindowButton = shouldShowNewWindowButton,
shouldShowManageWindowsButton = shouldShowManageWindowsButton,
shouldShowChangeAspectRatioButton = shouldShowChangeAspectRatioButton,
+ shouldShowDesktopModeButton = shouldShowDesktopModeButton,
isBrowserApp = isBrowserApp
).apply {
bind(taskInfo, appIconBitmap, appName, shouldShowMoreActionsPill)
@@ -218,7 +221,8 @@ class HandleMenu(
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
view = handleMenuView.rootView,
- forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 }
+ forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 },
+ ignoreCutouts = Flags.showAppHandleLargeScreens()
)
} else {
parentDecor.addWindow(
@@ -462,6 +466,7 @@ class HandleMenu(
private val shouldShowNewWindowButton: Boolean,
private val shouldShowManageWindowsButton: Boolean,
private val shouldShowChangeAspectRatioButton: Boolean,
+ private val shouldShowDesktopModeButton: Boolean,
private val isBrowserApp: Boolean
) {
val rootView = LayoutInflater.from(context)
@@ -658,12 +663,15 @@ class HandleMenu(
floatingBtn.isSelected = taskInfo.isPinned
floatingBtn.isEnabled = !taskInfo.isPinned
floatingBtn.imageTintList = style.windowingButtonColor
+ desktopBtn.isGone = !shouldShowDesktopModeButton
desktopBtn.isSelected = taskInfo.isFreeform
desktopBtn.isEnabled = !taskInfo.isFreeform
desktopBtn.imageTintList = style.windowingButtonColor
}
private fun bindMoreActionsPill(style: MenuStyle) {
+ moreActionsPill.background.setTint(style.backgroundColor)
+
arrayOf(
screenshotBtn to SHOULD_SHOW_SCREENSHOT_BUTTON,
newWindowBtn to shouldShowNewWindowButton,
@@ -674,7 +682,6 @@ class HandleMenu(
val shouldShow = it.second
button.apply {
isGone = !shouldShow
- background.setTint(style.backgroundColor)
setTextColor(style.textColor)
compoundDrawableTintList = ColorStateList.valueOf(style.textColor)
}
@@ -738,6 +745,7 @@ interface HandleMenuFactory {
shouldShowNewWindowButton: Boolean,
shouldShowManageWindowsButton: Boolean,
shouldShowChangeAspectRatioButton: Boolean,
+ shouldShowDesktopModeButton: Boolean,
isBrowserApp: Boolean,
openInAppOrBrowserIntent: Intent?,
captionWidth: Int,
@@ -760,6 +768,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory {
shouldShowNewWindowButton: Boolean,
shouldShowManageWindowsButton: Boolean,
shouldShowChangeAspectRatioButton: Boolean,
+ shouldShowDesktopModeButton: Boolean,
isBrowserApp: Boolean,
openInAppOrBrowserIntent: Intent?,
captionWidth: Int,
@@ -778,6 +787,7 @@ object DefaultHandleMenuFactory : HandleMenuFactory {
shouldShowNewWindowButton,
shouldShowManageWindowsButton,
shouldShowChangeAspectRatioButton,
+ shouldShowDesktopModeButton,
isBrowserApp,
openInAppOrBrowserIntent,
captionWidth,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 4bb1e7b6cc05..11a7cf8da8d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -70,6 +70,7 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHo
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
import com.android.wm.shell.windowdecor.common.OPACITY_12
import com.android.wm.shell.windowdecor.common.OPACITY_40
+import com.android.wm.shell.windowdecor.common.OPACITY_60
import com.android.wm.shell.windowdecor.common.withAlpha
import java.util.function.Supplier
@@ -310,8 +311,6 @@ class MaximizeMenu(
.desktop_mode_maximize_menu_immersive_button_fill_padding)
private val maximizeFillPaddingDefault = context.resources.getDimensionPixelSize(R.dimen
.desktop_mode_maximize_menu_snap_and_maximize_buttons_fill_padding)
- private val maximizeFillPaddingBottom = context.resources.getDimensionPixelSize(R.dimen
- .desktop_mode_maximize_menu_snap_and_maximize_buttons_fill_padding_bottom)
private val maximizeRestoreFillPaddingVertical = context.resources.getDimensionPixelSize(
R.dimen.desktop_mode_maximize_menu_restore_button_fill_vertical_padding)
private val maximizeRestoreFillPaddingHorizontal = context.resources.getDimensionPixelSize(
@@ -320,7 +319,7 @@ class MaximizeMenu(
maximizeFillPaddingDefault,
maximizeFillPaddingDefault,
maximizeFillPaddingDefault,
- maximizeFillPaddingBottom
+ maximizeFillPaddingDefault
)
private val maximizeRestoreFillPaddingRect = Rect(
maximizeRestoreFillPaddingHorizontal,
@@ -684,7 +683,7 @@ class MaximizeMenu(
inactiveSnapSideColor = colorScheme.outlineVariant.toArgb(),
semiActiveSnapSideColor = colorScheme.primary.toArgb().withAlpha(OPACITY_40),
activeSnapSideColor = colorScheme.primary.toArgb(),
- inactiveStrokeColor = colorScheme.outlineVariant.toArgb(),
+ inactiveStrokeColor = colorScheme.outlineVariant.toArgb().withAlpha(OPACITY_60),
activeStrokeColor = colorScheme.primary.toArgb(),
inactiveBackgroundColor = menuBackgroundColor,
activeBackgroundColor = colorScheme.primary.toArgb().withAlpha(OPACITY_12)
@@ -753,7 +752,8 @@ class MaximizeMenu(
val activeStrokeAndFill = colorScheme.primary.toArgb()
val activeBackground = colorScheme.primary.toArgb().withAlpha(OPACITY_12)
val activeDrawable = createMaximizeOrImmersiveButtonDrawable(
- strokeAndFillColor = activeStrokeAndFill,
+ strokeColor = activeStrokeAndFill,
+ fillColor = activeStrokeAndFill,
backgroundColor = activeBackground,
// Add a mask with the menu background's color because the active background color is
// semi transparent, otherwise the transparency will reveal the stroke/fill color
@@ -770,7 +770,8 @@ class MaximizeMenu(
addState(
StateSet.WILD_CARD,
createMaximizeOrImmersiveButtonDrawable(
- strokeAndFillColor = colorScheme.outlineVariant.toArgb(),
+ strokeColor = colorScheme.outlineVariant.toArgb().withAlpha(OPACITY_60),
+ fillColor = colorScheme.outlineVariant.toArgb(),
backgroundColor = colorScheme.surfaceContainerLow.toArgb(),
backgroundMask = null, // not needed because the bg color is fully opaque
fillPadding = fillPadding,
@@ -780,7 +781,8 @@ class MaximizeMenu(
}
private fun createMaximizeOrImmersiveButtonDrawable(
- @ColorInt strokeAndFillColor: Int,
+ @ColorInt strokeColor: Int,
+ @ColorInt fillColor: Int,
@ColorInt backgroundColor: Int,
@ColorInt backgroundMask: Int?,
fillPadding: Rect,
@@ -794,7 +796,7 @@ class MaximizeMenu(
null /* inset */,
null /* innerRadii */
)
- paint.color = strokeAndFillColor
+ paint.color = strokeColor
paint.style = Paint.Style.FILL
})
// Second layer, a mask for the next (background) layer if needed because of
@@ -829,7 +831,7 @@ class MaximizeMenu(
null /* inset */,
null /* innerRadii */
)
- paint.color = strokeAndFillColor
+ paint.color = fillColor
paint.style = Paint.Style.FILL
})
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
index 8b6aaaf619e0..4a01e8e3d455 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
@@ -25,6 +25,7 @@ import android.view.SurfaceControl
import android.view.View
import android.view.WindowInsets
import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
import com.android.wm.shell.windowdecor.WindowManagerWrapper
/**
@@ -40,6 +41,7 @@ class AdditionalSystemViewContainer(
height: Int,
flags: Int,
@WindowInsets.Type.InsetsType forciblyShownTypes: Int = 0,
+ ignoreCutouts: Boolean = false,
override val view: View
) : AdditionalViewContainer() {
val lp: WindowManager.LayoutParams = WindowManager.LayoutParams(
@@ -52,6 +54,10 @@ class AdditionalSystemViewContainer(
gravity = Gravity.LEFT or Gravity.TOP
setTrustedOverlay()
this.forciblyShownTypes = forciblyShownTypes
+ if (ignoreCutouts) {
+ fitInsetsTypes = 0
+ layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ }
}
constructor(
@@ -63,7 +69,8 @@ class AdditionalSystemViewContainer(
width: Int,
height: Int,
flags: Int,
- @LayoutRes layoutId: Int
+ @LayoutRes layoutId: Int,
+ ignoreCutouts: Boolean = false
) : this(
windowManagerWrapper = windowManagerWrapper,
taskId = taskId,
@@ -72,7 +79,8 @@ class AdditionalSystemViewContainer(
width = width,
height = height,
flags = flags,
- view = LayoutInflater.from(context).inflate(layoutId, null /* parent */)
+ view = LayoutInflater.from(context).inflate(layoutId, null /* parent */),
+ ignoreCutouts = ignoreCutouts
)
constructor(
@@ -83,7 +91,8 @@ class AdditionalSystemViewContainer(
y: Int,
width: Int,
height: Int,
- flags: Int
+ flags: Int,
+ ignoreCutouts: Boolean = false
) : this(
windowManagerWrapper = windowManagerWrapper,
taskId = taskId,
@@ -92,7 +101,8 @@ class AdditionalSystemViewContainer(
width = width,
height = height,
flags = flags,
- view = View(context)
+ view = View(context),
+ ignoreCutouts = ignoreCutouts
)
init {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt
index f7cfbfa88485..c5057aa3cc18 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt
@@ -52,6 +52,7 @@ const val OPACITY_12 = 31
const val OPACITY_15 = 38
const val OPACITY_40 = 102
const val OPACITY_55 = 140
+const val OPACITY_60 = 153
const val OPACITY_65 = 166
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 418b8ecd5534..bc7576c91da2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -225,18 +225,23 @@ class DesktopTilingWindowDecoration(
fun onDividerHandleDragStart(motionEvent: MotionEvent) {
val leftTiledTask = leftTaskResizingHelper ?: return
val rightTiledTask = rightTaskResizingHelper ?: return
+ val inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent)
desktopModeEventLogger.logTaskResizingStarted(
ResizeTrigger.TILING_DIVIDER,
- motionEvent,
+ inputMethod,
leftTiledTask.taskInfo,
+ leftTiledTask.bounds.width(),
+ leftTiledTask.bounds.height(),
displayController,
)
desktopModeEventLogger.logTaskResizingStarted(
ResizeTrigger.TILING_DIVIDER,
- motionEvent,
+ inputMethod,
rightTiledTask.taskInfo,
+ rightTiledTask.bounds.width(),
+ rightTiledTask.bounds.height(),
displayController,
)
}
@@ -296,22 +301,23 @@ class DesktopTilingWindowDecoration(
) {
val leftTiledTask = leftTaskResizingHelper ?: return
val rightTiledTask = rightTaskResizingHelper ?: return
+ val inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent)
desktopModeEventLogger.logTaskResizingEnded(
ResizeTrigger.TILING_DIVIDER,
- motionEvent,
+ inputMethod,
leftTiledTask.taskInfo,
- leftTiledTask.newBounds.height(),
leftTiledTask.newBounds.width(),
+ leftTiledTask.newBounds.height(),
displayController,
)
desktopModeEventLogger.logTaskResizingEnded(
ResizeTrigger.TILING_DIVIDER,
- motionEvent,
+ inputMethod,
rightTiledTask.taskInfo,
- rightTiledTask.newBounds.height(),
rightTiledTask.newBounds.width(),
+ rightTiledTask.newBounds.height(),
displayController,
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 5f25f42039ef..3f65d9318692 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -38,6 +38,7 @@ import android.window.DesktopModeFlags
import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
import com.android.internal.policy.SystemBarUtils
+import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.shared.animation.Interpolators
import com.android.wm.shell.windowdecor.WindowManagerWrapper
@@ -143,7 +144,8 @@ internal class AppHandleViewHolder(
if (!DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) return
statusBarInputLayer = AdditionalSystemViewContainer(context, windowManagerWrapper,
taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ ignoreCutouts = Flags.showAppHandleLargeScreens()
)
val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View")
val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer " +
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index 65e50f86e8fe..19829e7e5677 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -6,6 +6,7 @@ pablogamito@google.com
lbill@google.com
madym@google.com
hwwang@google.com
+gabiyev@google.com
chenghsiuchang@google.com
atsjenk@google.com
jorgegil@google.com
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
index 88dc5489b404..0cc8b0c7ba8d 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
@@ -50,6 +50,7 @@ import android.tools.flicker.config.common.Components.LAUNCHER
import android.tools.flicker.config.desktopmode.Components.DESKTOP_MODE_APP
import android.tools.flicker.config.desktopmode.Components.DESKTOP_WALLPAPER
import android.tools.flicker.config.desktopmode.Components.NON_RESIZABLE_APP
+import android.tools.flicker.config.desktopmode.Components.SIMPLE_APP
import android.tools.flicker.extractors.ITransitionMatcher
import android.tools.flicker.extractors.ShellTransitionScenarioExtractor
import android.tools.flicker.extractors.TaggedCujTransitionMatcher
@@ -444,5 +445,25 @@ class DesktopModeFlickerScenarios {
AppWindowOnTopAtEnd(LAUNCHER),
).associateBy({ it }, { AssertionInvocationGroup.BLOCKING })
)
+ val OPEN_UNLIMITED_APPS =
+ FlickerConfigEntry(
+ scenarioId = ScenarioId("OPEN_UNLIMITED_APPS"),
+ extractor =
+ ShellTransitionScenarioExtractor(
+ transitionMatcher =
+ object : ITransitionMatcher {
+ override fun findAll(
+ transitions: Collection<Transition>
+ ): Collection<Transition> {
+ return transitions.filter { it.type == TransitionType.OPEN }
+ }
+ }
+ ),
+ assertions =
+ listOf(
+ AppWindowBecomesVisible(DESKTOP_MODE_APP),
+ AppWindowIsVisibleAlways(SIMPLE_APP)
+ ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
+ )
}
}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenUnlimitedApps.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenUnlimitedApps.kt
new file mode 100644
index 000000000000..0a3984612987
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenUnlimitedApps.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.OPEN_UNLIMITED_APPS
+import com.android.wm.shell.scenarios.OpenUnlimitedApps
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Open many apps on the device without the window limit.
+ *
+ * Assert that the desktop task limit is not triggered.
+ */
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenUnlimitedApps : OpenUnlimitedApps() {
+ @ExpectedScenarios(["OPEN_UNLIMITED_APPS"])
+ @Test
+ override fun openUnlimitedApps() = super.openUnlimitedApps()
+
+ companion object {
+ @JvmStatic
+ @FlickerConfigProvider
+ fun flickerConfigProvider(): FlickerConfig =
+ FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(OPEN_UNLIMITED_APPS)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
index 0f546cdf97c5..8d04749d76a5 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
@@ -49,7 +49,8 @@ constructor(
@Test
open fun enterDesktopWithDrag() {
- testApp.enterDesktopModeWithDrag(wmHelper, device)
+ // By default this method uses drag to desktop
+ testApp.enterDesktopMode(wmHelper, device)
}
@After
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/Android.bp b/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/Android.bp
deleted file mode 100644
index 85e6a8d1d865..000000000000
--- a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/Android.bp
+++ /dev/null
@@ -1,38 +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 {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
- name: "WMShellFlickerTestsMediaProjection",
- defaults: ["WMShellFlickerTestsDefault"],
- manifest: "AndroidManifest.xml",
- test_config_template: "AndroidTestTemplate.xml",
- srcs: ["src/**/*.kt"],
- static_libs: [
- "WMShellFlickerTestsBase",
- "WMShellScenariosMediaProjection",
- "WMShellTestUtils",
- ],
- data: ["trace_config/*"],
-}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidManifest.xml
deleted file mode 100644
index 74b0daf3a2aa..000000000000
--- a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidManifest.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.android.wm.shell.flicker">
-
- <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
- <!-- Read and write traces from external storage -->
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <!-- Allow the test to write directly to /sdcard/ -->
- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
- <!-- Write secure settings -->
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <!-- Capture screen contents -->
- <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
- <!-- Enable / Disable tracing !-->
- <uses-permission android:name="android.permission.DUMP" />
- <!-- Run layers trace -->
- <uses-permission android:name="android.permission.HARDWARE_TEST"/>
- <!-- Capture screen recording -->
- <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
- <!-- Workaround grant runtime permission exception from b/152733071 -->
- <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
- <uses-permission android:name="android.permission.READ_LOGS"/>
- <!-- Force-stop test apps -->
- <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
- <!-- Control test app's media session -->
- <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
- <!-- ATM.removeRootTasksWithActivityTypes() -->
- <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
- <!-- Enable bubble notification-->
- <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
- <!-- Allow the test to connect to perfetto trace processor -->
- <uses-permission android:name="android.permission.INTERNET"/>
- <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
- <uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION" />
-
- <!-- Allow the test to write directly to /sdcard/ and connect to trace processor -->
- <application android:requestLegacyExternalStorage="true"
- android:networkSecurityConfig="@xml/network_security_config"
- android:largeHeap="true">
- <uses-library android:name="android.test.runner"/>
-
- <service android:name=".NotificationListener"
- android:exported="true"
- android:label="WMShellTestsNotificationListenerService"
- android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
- <intent-filter>
- <action android:name="android.service.notification.NotificationListenerService" />
- </intent-filter>
- </service>
-
- <service android:name="com.android.wm.shell.flicker.utils.MediaProjectionService"
- android:foregroundServiceType="mediaProjection"
- android:label="WMShellTestsMediaProjectionService"
- android:enabled="true">
- </service>
-
- <!-- (b/197936012) Remove startup provider due to test timeout issue -->
- <provider
- android:name="androidx.startup.InitializationProvider"
- android:authorities="${applicationId}.androidx-startup"
- tools:node="remove" />
- </application>
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker"
- android:label="WindowManager Shell Flicker Tests">
- </instrumentation>
-</manifest>
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidTestTemplate.xml
deleted file mode 100644
index 40dbbac32c7f..000000000000
--- a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/AndroidTestTemplate.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
- <option name="test-tag" value="FlickerTests"/>
- <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
- <option name="isolated-storage" value="false"/>
-
- <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
- <!-- disable DeprecatedTargetSdk warning -->
- <option name="run-command" value="setprop debug.wm.disable_deprecated_target_sdk_dialog 1"/>
- <!-- keeps the screen on during tests -->
- <option name="screen-always-on" value="on"/>
- <!-- prevents the phone from restarting -->
- <option name="force-skip-system-props" value="true"/>
- <!-- set WM tracing verbose level to all -->
- <option name="run-command" value="cmd window tracing level all"/>
- <!-- set WM tracing to frame (avoid incomplete states) -->
- <option name="run-command" value="cmd window tracing frame"/>
- <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
- <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
- <!-- ensure lock screen mode is swipe -->
- <option name="run-command" value="locksettings set-disabled false"/>
- <!-- restart launcher to activate TAPL -->
- <option name="run-command"
- value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
- <!-- Increase trace size: 20mb for WM and 80mb for SF -->
- <option name="run-command" value="cmd window tracing size 20480"/>
- <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="test-user-token" value="%TEST_USER%"/>
- <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
- <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
- <option name="run-command" value="settings put system show_touches 1"/>
- <option name="run-command" value="settings put system pointer_location 1"/>
- <option name="teardown-command"
- value="settings delete secure show_ime_with_hard_keyboard"/>
- <option name="teardown-command" value="settings delete system show_touches"/>
- <option name="teardown-command" value="settings delete system pointer_location"/>
- <option name="teardown-command"
- value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="cleanup-apks" value="true"/>
- <option name="test-file-name" value="{MODULE}.apk"/>
- <option name="test-file-name" value="FlickerTestApp.apk"/>
- </target_preparer>
-
- <!-- Needed for pushing the trace config file -->
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="push-file"
- key="trace_config.textproto"
- value="/data/misc/perfetto-traces/trace_config.textproto"
- />
- <!--Install the content provider automatically when we push some file in sdcard folder.-->
- <!--Needed to avoid the installation during the test suite.-->
- <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
- </target_preparer>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest">
- <option name="package" value="{PACKAGE}"/>
- <option name="shell-timeout" value="6600s"/>
- <option name="test-timeout" value="6000s"/>
- <option name="hidden-api-checks" value="false"/>
- <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
- <!-- PerfettoListener related arguments -->
- <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
- <option name="instrumentation-arg"
- key="perfetto_config_file"
- value="trace_config.textproto"
- />
- <option name="instrumentation-arg" key="per_run" value="true"/>
- <option name="instrumentation-arg" key="perfetto_persist_pid_track" value="true"/>
- </test>
- <!-- Needed for pulling the collected trace config on to the host -->
- <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
- <option name="pull-pattern-keys" value="perfetto_file_path"/>
- <option name="directory-keys"
- value="/data/user/0/com.android.wm.shell.flicker/files"/>
- <option name="collect-on-run-ended-only" value="true"/>
- <option name="clean-up" value="true"/>
- </metrics_collector>
-</configuration>
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/trace_config/trace_config.textproto
deleted file mode 100644
index 9f2e49755fec..000000000000
--- a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/trace_config/trace_config.textproto
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) 2023 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# proto-message: TraceConfig
-
-# Enable periodic flushing of the trace buffer into the output file.
-write_into_file: true
-
-# Writes the userspace buffer into the file every 1s.
-file_write_period_ms: 2500
-
-# See b/126487238 - we need to guarantee ordering of events.
-flush_period_ms: 30000
-
-# The trace buffers needs to be big enough to hold |file_write_period_ms| of
-# trace data. The trace buffer sizing depends on the number of trace categories
-# enabled and the device activity.
-
-# RSS events
-buffers: {
- size_kb: 63488
- fill_policy: RING_BUFFER
-}
-
-data_sources {
- config {
- name: "linux.process_stats"
- target_buffer: 0
- # polled per-process memory counters and process/thread names.
- # If you don't want the polled counters, remove the "process_stats_config"
- # section, but keep the data source itself as it still provides on-demand
- # thread/process naming for ftrace data below.
- process_stats_config {
- scan_all_processes_on_start: true
- }
- }
-}
-
-data_sources: {
- config {
- name: "linux.ftrace"
- ftrace_config {
- ftrace_events: "ftrace/print"
- ftrace_events: "task/task_newtask"
- ftrace_events: "task/task_rename"
- atrace_categories: "ss"
- atrace_categories: "wm"
- atrace_categories: "am"
- atrace_categories: "aidl"
- atrace_categories: "input"
- atrace_categories: "binder_driver"
- atrace_categories: "sched_process_exit"
- atrace_apps: "com.android.server.wm.flicker.testapp"
- atrace_apps: "com.android.systemui"
- atrace_apps: "com.android.wm.shell.flicker.service"
- atrace_apps: "com.google.android.apps.nexuslauncher"
- }
- }
-}
-
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionFromSplitScreenTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionFromSplitScreenTest.kt
new file mode 100644
index 000000000000..2b9772d9cbdd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionFromSplitScreenTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartAppMediaProjectionFromSplitScreen
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartAppMediaProjectionFromSplitScreen]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartAppMediaProjectionFromSplitScreenTest() : StartAppMediaProjectionFromSplitScreen() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionInSplitScreenTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionInSplitScreenTest.kt
new file mode 100644
index 000000000000..e92297b48166
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionInSplitScreenTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartAppMediaProjectionInSplitScreen
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartAppMediaProjectionInSplitScreen]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartAppMediaProjectionInSplitScreenTest() : StartAppMediaProjectionInSplitScreen() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionTest.kt
new file mode 100644
index 000000000000..3f8107592667
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartAppMediaProjection
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartAppMediaProjection]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartAppMediaProjectionTest() : StartAppMediaProjection() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionWithExtraIntentTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionWithExtraIntentTest.kt
new file mode 100644
index 000000000000..1975cc7f86d2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartAppMediaProjectionWithExtraIntentTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartAppMediaProjectionWithExtraIntent
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartAppMediaProjectionWithExtraIntent]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartAppMediaProjectionWithExtraIntentTest : StartAppMediaProjectionWithExtraIntent() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionFromSplitScreenTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionFromSplitScreenTest.kt
new file mode 100644
index 000000000000..943033c1819c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionFromSplitScreenTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartRecentAppMediaProjectionFromSplitScreen
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartRecentAppMediaProjectionFromSplitScreen]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartRecentAppMediaProjectionFromSplitScreenTest() : StartRecentAppMediaProjectionFromSplitScreen() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionInSplitScreenTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionInSplitScreenTest.kt
new file mode 100644
index 000000000000..6facfd5b0063
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionInSplitScreenTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartRecentAppMediaProjectionInSplitScreen
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartRecentAppMediaProjectionInSplitScreen]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartRecentAppMediaProjectionInSplitScreenTest() : StartRecentAppMediaProjectionInSplitScreen() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionTest.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionTest.kt
new file mode 100644
index 000000000000..bab09052715a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/functional/StartRecentAppMediaProjectionTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.StartRecentAppMediaProjection
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [StartRecentAppMediaProjection]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class StartRecentAppMediaProjectionTest() : StartRecentAppMediaProjection() \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjection.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjection.kt
new file mode 100644
index 000000000000..fe2c57801f72
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjection.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session.
+ *
+ * This is for testing that the requested app is opened as expected upon selecting it from the app
+ * selector, so capture can proceed as expected.
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartAppMediaProjection {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(initialRotation.value)
+ testApp.launchViaIntent(wmHelper)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ testApp.startSingleAppMediaProjection(wmHelper, targetApp)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionFromSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionFromSplitScreen.kt
new file mode 100644
index 000000000000..3beece8c38b8
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionFromSplitScreen.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import com.android.wm.shell.flicker.utils.SplitScreenUtils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session, while the HOST app is in
+ * split screen
+ *
+ * This is for testing that the requested app is opened as expected upon selecting it from the app
+ * selector, so capture can proceed as expected.
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartAppMediaProjectionFromSplitScreen {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val simpleApp = SimpleAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.workspace.switchToOverview().dismissAllTasks()
+
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(initialRotation.value)
+ SplitScreenUtils.enterSplit(wmHelper, tapl, device, simpleApp, testApp, initialRotation)
+ SplitScreenUtils.waitForSplitComplete(wmHelper, simpleApp, testApp)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ testApp.startSingleAppMediaProjection(wmHelper, targetApp)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionInSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionInSplitScreen.kt
new file mode 100644
index 000000000000..d3186ae88081
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionInSplitScreen.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import com.android.wm.shell.flicker.utils.SplitScreenUtils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session, while the TARGET app is in
+ * split screen (next to the host app)
+ *
+ * This is for testing that the split pair isn't broken, and capture still proceeds as expected
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartAppMediaProjectionInSplitScreen {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.workspace.switchToOverview().dismissAllTasks()
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(initialRotation.value)
+ SplitScreenUtils.enterSplit(wmHelper, tapl, device, targetApp, testApp, initialRotation)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ testApp.startSingleAppMediaProjection(wmHelper, targetApp)
+
+ wmHelper
+ .StateSyncBuilder()
+ .withAppTransitionIdle()
+ .withWindowSurfaceAppeared(targetApp)
+ .withWindowSurfaceAppeared(testApp)
+ .waitForAndVerify()
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ targetApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionWithExtraIntent.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionWithExtraIntent.kt
new file mode 100644
index 000000000000..0b2a1ca23cdb
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartAppMediaProjectionWithExtraIntent.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session but launches an intent to
+ * return to the home screen, before the intent for opening the requested app to capture.
+ *
+ * This is for testing that even if a different intent interrupts the process the launching the
+ * requested capture target, the MediaProjection process isn't interrupted and the device is still
+ * interactive.
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartAppMediaProjectionWithExtraIntent {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.setEnableRotation(true)
+ testApp.launchViaIntent(wmHelper)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ testApp.startSingleAppMediaProjectionWithExtraIntent(wmHelper, targetApp)
+
+ // Check we can still interact with device after
+ tapl.workspace.switchToAllApps().getAppIcon(targetApp.appName).launch(targetApp.packageName)
+
+ wmHelper
+ .StateSyncBuilder()
+ .withAppTransitionIdle()
+ .withWindowSurfaceAppeared(targetApp)
+ .waitForAndVerify()
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjection.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjection.kt
new file mode 100644
index 000000000000..30e0e4aa490a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjection.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session from recents.
+ *
+ * This is for testing that the app is started from recents and capture proceeds as expected.
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartRecentAppMediaProjection {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(initialRotation.value)
+ targetApp.open()
+ testApp.launchViaIntent(wmHelper)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ testApp.startSingleAppMediaProjectionFromRecents(wmHelper, targetApp)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionFromSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionFromSplitScreen.kt
new file mode 100644
index 000000000000..f1dcf1fab140
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionFromSplitScreen.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import com.android.wm.shell.flicker.utils.SplitScreenUtils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session from recents while the HOST
+ * app is in split screen.
+ *
+ * This is for testing that the split pair isn't broken, and capture still proceeds as expected
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartRecentAppMediaProjectionFromSplitScreen {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val simpleApp = SimpleAppHelper(instrumentation)
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.workspace.switchToOverview().dismissAllTasks()
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(initialRotation.value)
+ targetApp.open()
+ SplitScreenUtils.enterSplit(wmHelper, tapl, device, simpleApp, testApp, initialRotation)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ // The app we want to open for PSS will be the second item in the carousel,
+ // because the first will be the app open in split screen alongside the MediaProjection app
+ testApp.startSingleAppMediaProjectionFromRecents(wmHelper, targetApp, recentTasksIndex = 1)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionInSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionInSplitScreen.kt
new file mode 100644
index 000000000000..0a6992f9a152
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/mediaprojection/scenarios/src/com/android/wm/shell/scenarios/StartRecentAppMediaProjectionInSplitScreen.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.device.apphelpers.CalculatorAppHelper
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.StartMediaProjectionAppHelper
+import com.android.wm.shell.Utils
+import com.android.wm.shell.flicker.utils.SplitScreenUtils
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/**
+ * Test scenario which requests an a single-app MediaProjection session from recents while the
+ * TARGET app is in split screen (with host app).
+ *
+ * This is for testing that the split pair isn't broken, and capture still proceeds as expected
+ */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class StartRecentAppMediaProjectionInSplitScreen {
+
+ val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ val tapl = LauncherInstrumentation()
+ val wmHelper = WindowManagerStateHelper(instrumentation)
+ val device = UiDevice.getInstance(instrumentation)
+
+ private val initialRotation = Rotation.ROTATION_0
+ private val targetApp = CalculatorAppHelper(instrumentation)
+ private val testApp = StartMediaProjectionAppHelper(instrumentation)
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, initialRotation)
+
+ @Before
+ fun setup() {
+ tapl.workspace.switchToOverview().dismissAllTasks()
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(initialRotation.value)
+ SplitScreenUtils.enterSplit(wmHelper, tapl, device, targetApp, testApp, initialRotation)
+ }
+
+ @Test
+ open fun startMediaProjection() {
+ testApp.startSingleAppMediaProjectionFromRecents(wmHelper, targetApp)
+
+ wmHelper
+ .StateSyncBuilder()
+ .withAppTransitionIdle()
+ .withWindowSurfaceAppeared(targetApp)
+ .withWindowSurfaceAppeared(testApp)
+ .waitForAndVerify()
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ targetApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MediaProjectionUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MediaProjectionUtils.kt
index f9706969ff11..8c2bdad364fc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MediaProjectionUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MediaProjectionUtils.kt
@@ -17,7 +17,11 @@
package com.android.wm.shell.flicker.utils
object MediaProjectionUtils {
- const val REQUEST_CODE: Int = 99
+ // Request code for the normal media projection request
+ const val REQUEST_CODE_NORMAL: Int = 11
+ // Request code for the media projection request which will include an extra intent to open
+ // home screen before starting requested app
+ const val REQUEST_CODE_EXTRA_INTENT: Int = 12
const val MSG_START_FOREGROUND_DONE: Int = 1
const val MSG_SERVICE_DESTROYED: Int = 2
const val EXTRA_MESSENGER: String = "messenger"
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index f935ac76bbeb..9c31b46a80e5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -45,6 +45,7 @@ public final class TestRunningTaskInfoBuilder {
private Intent mBaseIntent = new Intent();
private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
private @WindowConfiguration.WindowingMode int mWindowingMode = WINDOWING_MODE_UNDEFINED;
+ private @WindowConfiguration.ActivityType int mTopActivityType = ACTIVITY_TYPE_STANDARD;
private int mDisplayId = Display.DEFAULT_DISPLAY;
private ActivityManager.TaskDescription.Builder mTaskDescriptionBuilder = null;
private final Point mPositionInParent = new Point();
@@ -102,6 +103,12 @@ public final class TestRunningTaskInfoBuilder {
return this;
}
+ public TestRunningTaskInfoBuilder setTopActivityType(
+ @WindowConfiguration.ActivityType int activityType) {
+ mTopActivityType = activityType;
+ return this;
+ }
+
public TestRunningTaskInfoBuilder setWindowingMode(
@WindowConfiguration.WindowingMode int windowingMode) {
mWindowingMode = windowingMode;
@@ -154,6 +161,7 @@ public final class TestRunningTaskInfoBuilder {
info.configuration.windowConfiguration.setBounds(mBounds);
info.configuration.windowConfiguration.setActivityType(mActivityType);
info.configuration.windowConfiguration.setWindowingMode(mWindowingMode);
+ info.topActivityType = mTopActivityType;
info.token = mToken;
info.isResizeable = true;
info.supportsMultiWindow = true;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 13a8518ae8ed..c3e396524da1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -57,6 +57,8 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContentResolver;
@@ -91,6 +93,7 @@ import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -140,6 +143,8 @@ public class BackAnimationControllerTest extends ShellTestCase {
private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
@Mock
private Handler mHandler;
+ @Mock
+ private Transitions.TransitionHandler mTakeoverHandler;
private BackAnimationController mController;
private TestableContentResolver mContentResolver;
@@ -152,6 +157,9 @@ public class BackAnimationControllerTest extends ShellTestCase {
private BackAnimationController.BackTransitionHandler mBackTransitionHandler;
+ @Rule
+ public SetFlagsRule mSetflagsRule = new SetFlagsRule();
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -605,6 +613,51 @@ public class BackAnimationControllerTest extends ShellTestCase {
verify(mAnimatorCallback, never()).onBackInvoked();
}
+ @EnableFlags({com.android.systemui.shared.Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LIBRARY,
+ com.android.systemui.shared.Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LONG_LIVED,
+ com.android.window.flags.Flags.FLAG_UNIFY_BACK_NAVIGATION_TRANSITION})
+ @Test
+ public void appCallback_receivesTakeoverHandler_whenAvailable() throws RemoteException {
+ registerAnimation(BackNavigationInfo.TYPE_CROSS_TASK);
+ mBackTransitionHandler.mTakeoverHandler = mTakeoverHandler;
+
+ final int type = BackNavigationInfo.TYPE_CALLBACK;
+ final ResultListener result = new ResultListener();
+ createNavigationInfo(new BackNavigationInfo.Builder()
+ .setType(type)
+ .setOnBackInvokedCallback(mAppCallback)
+ .setOnBackNavigationDone(new RemoteCallback(result))
+ .setTouchableRegion(mTouchableRegion)
+ .setAppProgressAllowed(true));
+
+ triggerBackGesture();
+ mShellExecutor.flushAll();
+ releaseBackGesture();
+ mShellExecutor.flushAll();
+
+ verify(mAppCallback).setHandoffHandler(any());
+ }
+
+ @Test
+ public void appCallback_doesNotReceiveTakeoverHandler_whenUnavailable() throws RemoteException {
+ registerAnimation(BackNavigationInfo.TYPE_CROSS_TASK);
+
+ final int type = BackNavigationInfo.TYPE_CALLBACK;
+ final ResultListener result = new ResultListener();
+ createNavigationInfo(new BackNavigationInfo.Builder()
+ .setType(type)
+ .setOnBackInvokedCallback(mAppCallback)
+ .setOnBackNavigationDone(new RemoteCallback(result))
+ .setTouchableRegion(mTouchableRegion)
+ .setAppProgressAllowed(true));
+ triggerBackGesture();
+ mShellExecutor.flushAll();
+ releaseBackGesture();
+ mShellExecutor.flushAll();
+
+ verify(mAppCallback, never()).setHandoffHandler(any());
+ }
+
@Test
public void skipsCancelWithoutStart() throws RemoteException {
final int type = BackNavigationInfo.TYPE_CALLBACK;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
index 2ed7d07ac75e..bf54e79119bf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
@@ -63,6 +63,7 @@ public class BackProgressAnimatorTest {
@Before
public void setUp() throws Exception {
mTargetProgressCalled = new CountDownLatch(1);
+ mTargetProgress = 0.5f;
mMainThreadHandler = new Handler(Looper.getMainLooper());
final BackMotionEvent backEvent = backMotionEventFrom(0, 0);
mMainThreadHandler.post(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 6fa37885b724..ce640b5e5195 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -47,6 +47,7 @@ import android.view.WindowManager;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.bubbles.BubbleData.TimeSource;
import com.android.wm.shell.common.ShellExecutor;
@@ -102,6 +103,7 @@ public class BubbleDataTest extends ShellTestCase {
private BubbleData mBubbleData;
private TestableBubblePositioner mPositioner;
+ private UiEventLoggerFake mUiEventLogger;
@Mock
private TimeSource mTimeSource;
@@ -112,8 +114,6 @@ public class BubbleDataTest extends ShellTestCase {
@Mock
private PendingIntent mDeleteIntent;
@Mock
- private BubbleLogger mBubbleLogger;
- @Mock
private BubbleEducationController mEducationController;
@Mock
private ShellExecutor mMainExecutor;
@@ -196,10 +196,12 @@ public class BubbleDataTest extends ShellTestCase {
mock(Icon.class),
mMainExecutor, mBgExecutor);
+ mUiEventLogger = new UiEventLoggerFake();
+
mPositioner = new TestableBubblePositioner(mContext,
mContext.getSystemService(WindowManager.class));
- mBubbleData = new BubbleData(getContext(), mBubbleLogger, mPositioner, mEducationController,
- mMainExecutor, mBgExecutor);
+ mBubbleData = new BubbleData(getContext(), new BubbleLogger(mUiEventLogger), mPositioner,
+ mEducationController, mMainExecutor, mBgExecutor);
// Used by BubbleData to set lastAccessedTime
when(mTimeSource.currentTimeMillis()).thenReturn(1000L);
@@ -297,6 +299,82 @@ public class BubbleDataTest extends ShellTestCase {
}
@Test
+ public void testRemoveBubbleFromBubbleBar_notifCancelled_logEvent() {
+ mPositioner.setShowingInBubbleBar(true);
+
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_NOTIF_CANCEL);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ BubbleLogger.Event.BUBBLE_BAR_BUBBLE_REMOVED_CANCELED.getId());
+ }
+
+ @Test
+ public void testRemoveBubbleFromBubbleBar_taskFinished_logEvent() {
+ mPositioner.setShowingInBubbleBar(true);
+
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_TASK_FINISHED);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ BubbleLogger.Event.BUBBLE_BAR_BUBBLE_ACTIVITY_FINISH.getId());
+ }
+
+ @Test
+ public void testRemoveBubbleFromBubbleBar_notifBlocked_logEvent() {
+ mPositioner.setShowingInBubbleBar(true);
+
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_BLOCKED);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ BubbleLogger.Event.BUBBLE_BAR_BUBBLE_REMOVED_BLOCKED.getId());
+ }
+
+ @Test
+ public void testRemoveBubbleFromBubbleBar_noLongerBubble_logEvent() {
+ mPositioner.setShowingInBubbleBar(true);
+
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_NO_LONGER_BUBBLE);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ BubbleLogger.Event.BUBBLE_BAR_BUBBLE_REMOVED_BLOCKED.getId());
+ }
+
+ @Test
+ public void testRemoveBubbleFromBubbleBar_addToOverflow_logEvent() {
+ mPositioner.setShowingInBubbleBar(true);
+
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_AGED);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ BubbleLogger.Event.BUBBLE_BAR_OVERFLOW_ADD_AGED.getId());
+ }
+
+ @Test
+ public void testRemoveBubble_notifCancelled_noLog() {
+ mPositioner.setShowingInBubbleBar(false);
+
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.dismissBubbleWithKey(mEntryA1.getKey(), Bubbles.DISMISS_BLOCKED);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(0);
+ }
+
+ @Test
public void ifSuppress_hideFlyout() {
// Setup
mBubbleData.setListener(mListener);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
index a4f4d05d2079..4666276c2fae 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
@@ -42,6 +42,7 @@ import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitReason.USER_INTERACTION
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
@@ -168,7 +169,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.moveTaskToNonImmersive(task)
+ controller.moveTaskToNonImmersive(task, USER_INTERACTION)
controller.onTransitionReady(
transition = mockBinder,
info = createTransitionInfo(
@@ -195,7 +196,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
)
desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, Rect(100, 100, 600, 600))
- controller.moveTaskToNonImmersive(task)
+ controller.moveTaskToNonImmersive(task, USER_INTERACTION)
controller.onTransitionReady(
transition = mockBinder,
info = createTransitionInfo(
@@ -252,8 +253,8 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
whenever(mockTransitions.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller)))
.thenReturn(mockBinder)
- controller.moveTaskToNonImmersive(task)
- controller.moveTaskToNonImmersive(task)
+ controller.moveTaskToNonImmersive(task, USER_INTERACTION)
+ controller.moveTaskToNonImmersive(task, USER_INTERACTION)
verify(mockTransitions, times(1))
.startTransition(eq(TRANSIT_CHANGE), any(), eq(controller))
@@ -272,7 +273,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
assertThat(controller.pendingExternalExitTransitions.any { exit ->
exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
@@ -293,7 +294,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = false
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
assertThat(controller.pendingExternalExitTransitions.any { exit ->
exit.transition == transition && exit.displayId == DEFAULT_DISPLAY
@@ -314,7 +315,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
assertThat(wct.hasBoundsChange(task.token)).isTrue()
}
@@ -332,7 +333,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = false
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
assertThat(wct.hasBoundsChange(task.token)).isFalse()
}
@@ -353,7 +354,8 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
controller.exitImmersiveIfApplicable(
wct = wct,
displayId = DEFAULT_DISPLAY,
- excludeTaskId = task.taskId
+ excludeTaskId = task.taskId,
+ reason = USER_INTERACTION,
).asExit()?.runOnTransitionStart?.invoke(transition)
assertThat(controller.pendingExternalExitTransitions.any { exit ->
@@ -374,7 +376,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+ controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
assertThat(wct.hasBoundsChange(task.token)).isTrue()
}
@@ -391,7 +393,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = false
)
- controller.exitImmersiveIfApplicable(wct, task)
+ controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
assertThat(wct.hasBoundsChange(task.token)).isFalse()
}
@@ -409,7 +411,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(wct, task)
+ controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
.asExit()?.runOnTransitionStart?.invoke(transition)
assertThat(controller.pendingExternalExitTransitions.any { exit ->
@@ -430,7 +432,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = false
)
- val result = controller.exitImmersiveIfApplicable(wct, task)
+ val result = controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
assertThat(result).isEqualTo(DesktopImmersiveController.ExitResult.NoExit)
}
@@ -447,7 +449,8 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = false
)
- val result = controller.exitImmersiveIfApplicable(wct, task.displayId)
+ val result = controller.exitImmersiveIfApplicable(
+ wct, task.displayId, excludeTaskId = null, USER_INTERACTION)
assertThat(result).isEqualTo(DesktopImmersiveController.ExitResult.NoExit)
}
@@ -464,7 +467,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
taskId = task.taskId,
immersive = true
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
controller.onTransitionReady(
transition = transition,
@@ -495,7 +498,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
taskId = task.taskId,
immersive = true
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
controller.onTransitionReady(
transition = transition,
@@ -530,7 +533,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
taskId = task.taskId,
immersive = true
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
controller.onTransitionReady(
transition = transition,
@@ -560,7 +563,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, Rect(100, 100, 600, 600))
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
controller.onTransitionReady(
transition = transition,
@@ -587,7 +590,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+ controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
assertThat(
wct.hasBoundsChange(task.token, calculateMaximizeBounds(mockDisplayLayout, task))
@@ -611,7 +614,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
val preImmersiveBounds = Rect(100, 100, 500, 500)
desktopRepository.saveBoundsBeforeFullImmersive(task.taskId, preImmersiveBounds)
- controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+ controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
assertThat(
wct.hasBoundsChange(task.token, preImmersiveBounds)
@@ -634,7 +637,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task)
+ controller.exitImmersiveIfApplicable(wct = wct, taskInfo = task, reason = USER_INTERACTION)
assertThat(
wct.hasBoundsChange(task.token, calculateInitialBounds(mockDisplayLayout, task))
@@ -652,10 +655,10 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
taskId = task.taskId,
immersive = true
)
- controller.exitImmersiveIfApplicable(wct, task)
+ controller.exitImmersiveIfApplicable(wct, task, USER_INTERACTION)
.asExit()?.runOnTransitionStart?.invoke(Binder())
- controller.moveTaskToNonImmersive(task)
+ controller.moveTaskToNonImmersive(task, USER_INTERACTION)
verify(mockTransitions, never()).startTransition(any(), any(), any())
}
@@ -674,7 +677,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY)
+ controller.exitImmersiveIfApplicable(transition, wct, DEFAULT_DISPLAY, USER_INTERACTION)
assertThat(controller.isImmersiveChange(transition, change)).isTrue()
}
@@ -692,7 +695,7 @@ class DesktopImmersiveControllerTest : ShellTestCase() {
immersive = true
)
- controller.moveTaskToNonImmersive(task)
+ controller.moveTaskToNonImmersive(task, USER_INTERACTION)
controller.animateResizeChange(
change = TransitionInfo.Change(task.token, SurfaceControl()).apply {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
index 2a82e6e4f7b8..2f225f22cce0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
@@ -487,7 +487,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
@Test
fun logTaskResizingStarted_noOngoingSession_doesNotLog() {
desktopModeEventLogger.logTaskResizingStarted(ResizeTrigger.CORNER,
- null, createTaskInfo())
+ InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo())
verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -499,7 +499,8 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
val sessionId = startDesktopModeSession()
desktopModeEventLogger.logTaskResizingStarted(ResizeTrigger.CORNER,
- null, createTaskInfo(), displayController)
+ InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo(), TASK_SIZE_UPDATE.taskWidth,
+ TASK_SIZE_UPDATE.taskHeight, displayController)
verify {
FrameworkStatsLog.write(
@@ -516,10 +517,10 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(TASK_SIZE_UPDATE.instanceId),
/* uid */
eq(TASK_SIZE_UPDATE.uid),
- /* task_height */
- eq(TASK_SIZE_UPDATE.taskHeight),
/* task_width */
eq(TASK_SIZE_UPDATE.taskWidth),
+ /* task_height */
+ eq(TASK_SIZE_UPDATE.taskHeight),
/* display_area */
eq(DISPLAY_AREA),
)
@@ -530,7 +531,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
@Test
fun logTaskResizingEnded_noOngoingSession_doesNotLog() {
desktopModeEventLogger.logTaskResizingEnded(ResizeTrigger.CORNER,
- null, createTaskInfo())
+ InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo())
verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -542,7 +543,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
val sessionId = startDesktopModeSession()
desktopModeEventLogger.logTaskResizingEnded(ResizeTrigger.CORNER,
- null, createTaskInfo(), displayController = displayController)
+ InputMethod.UNKNOWN_INPUT_METHOD, createTaskInfo(), displayController = displayController)
verify {
FrameworkStatsLog.write(
@@ -559,10 +560,10 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
eq(TASK_SIZE_UPDATE.instanceId),
/* uid */
eq(TASK_SIZE_UPDATE.uid),
- /* task_height */
- eq(TASK_SIZE_UPDATE.taskHeight),
/* task_width */
eq(TASK_SIZE_UPDATE.taskWidth),
+ /* task_height */
+ eq(TASK_SIZE_UPDATE.taskHeight),
/* display_area */
eq(DISPLAY_AREA),
)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
index 9e63a6d922b8..7adc339c010d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
@@ -205,7 +205,9 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
assertThat(result).isTrue()
- verify(desktopModeWindowDecorViewModel).onSnapResize(task.taskId, true, null)
+ verify(desktopModeWindowDecorViewModel).onSnapResize(
+ task.taskId, true, DesktopModeEventLogger.Companion.InputMethod.KEYBOARD
+ )
}
@Test
@@ -232,7 +234,9 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
val result = keyGestureEventHandler.handleKeyGestureEvent(event, null)
assertThat(result).isTrue()
- verify(desktopModeWindowDecorViewModel).onSnapResize(task.taskId, false, null)
+ verify(desktopModeWindowDecorViewModel).onSnapResize(
+ task.taskId, false, DesktopModeEventLogger.Companion.InputMethod.KEYBOARD
+ )
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 936835c34c04..a8cfef7c1262 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -94,6 +94,7 @@ import com.android.wm.shell.common.MultiInstanceHelper
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitResult
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopTasksController.DesktopModeEntryExitTransitionListener
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
@@ -113,9 +114,12 @@ import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
import com.android.wm.shell.recents.RecentTasksController
import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.recents.RecentsTransitionStateListener
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING
+import com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.UNKNOWN
import com.android.wm.shell.shared.split.SplitScreenConstants
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellController
@@ -290,10 +294,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda)
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), any<RunningTaskInfo>()))
+ .exitImmersiveIfApplicable(any(), any<RunningTaskInfo>(), any()))
.thenReturn(ExitResult.NoExit)
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull()))
+ .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull(), any()))
.thenReturn(ExitResult.NoExit)
controller = createController()
@@ -376,10 +380,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task1,
- STABLE_BOUNDS.height(),
STABLE_BOUNDS.width(),
+ STABLE_BOUNDS.height(),
displayController
)
assertThat(argumentCaptor.value).isTrue()
@@ -403,7 +407,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task1,
0,
0,
@@ -1792,7 +1796,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.minimizeTask(task)
- verify(mMockDesktopImmersiveController).exitImmersiveIfApplicable(any(), eq(task))
+ verify(mMockDesktopImmersiveController).exitImmersiveIfApplicable(any(), eq(task), any())
}
@Test
@@ -1802,7 +1806,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val runOnTransit = RunOnStartTransitionCallback()
whenever(freeformTaskTransitionStarter.startMinimizedModeTransition(any()))
.thenReturn(transition)
- whenever(mMockDesktopImmersiveController.exitImmersiveIfApplicable(any(), eq(task)))
+ whenever(mMockDesktopImmersiveController.exitImmersiveIfApplicable(any(), eq(task), any()))
.thenReturn(
ExitResult.Exit(
exitingTask = task.taskId,
@@ -1919,6 +1923,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
fun handleRequest_fullscreenTask_noTasks_enforceDesktop_freeformDisplay_returnFreeformWCT() {
whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
@@ -1930,8 +1935,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertNotNull(wct, "should handle request")
assertThat(wct.changes[fullscreenTask.token.asBinder()]?.windowingMode)
.isEqualTo(WINDOWING_MODE_UNDEFINED)
- assertThat(wct.hierarchyOps).hasSize(1)
- wct.assertReorderAt(0, fullscreenTask, toTop = true)
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // There are 3 hops that are happening in this case:
+ // 1. Moving the fullscreen task to top as we add moveToDesktop() changes
+ // 2. Pending intent for the wallpaper
+ // 3. Bringing the fullscreen task back at the top
+ wct.assertPendingIntentAt(1, desktopWallpaperIntent)
+ wct.assertReorderAt(2, fullscreenTask, toTop = true)
}
@Test
@@ -2191,7 +2201,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
markTaskVisible(freeformTask)
// Mark recents animation running
- recentsTransitionStateListener.onAnimationStateChanged(true)
+ recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING)
// Open a fullscreen task, check that it does not result in a WCT with changes to it
val fullscreenTask = createFullscreenTask()
@@ -2205,7 +2215,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
markTaskVisible(freeformTask)
// Mark recents animation running
- recentsTransitionStateListener.onAnimationStateChanged(true)
+ recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING)
// Should become undefined as the TDA is set to fullscreen. It will inherit from the TDA.
val result = controller.handleRequest(Binder(), createTransition(freeformTask))
@@ -3012,16 +3022,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
// Assert event is properly logged
verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
+ task.configuration.windowConfiguration.bounds.width(),
+ task.configuration.windowConfiguration.bounds.height(),
displayController
)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- STABLE_BOUNDS.height(),
STABLE_BOUNDS.width(),
+ STABLE_BOUNDS.height(),
displayController
)
}
@@ -3070,7 +3082,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
)
// Assert no event is logged
verify(desktopModeEventLogger, never()).logTaskResizingStarted(
- any(), any(), any(), any(), any()
+ any(), any(), any(), any(), any(), any(), any()
)
verify(desktopModeEventLogger, never()).logTaskResizingEnded(
any(), any(), any(), any(), any(), any(), any()
@@ -3158,7 +3170,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
runOpenNewWindow(task)
verify(splitScreenController)
.startIntent(any(), anyInt(), any(), any(),
- optionsCaptor.capture(), anyOrNull(), eq(true)
+ optionsCaptor.capture(), anyOrNull(), eq(true), eq(SPLIT_INDEX_UNDEFINED)
)
assertThat(ActivityOptions.fromBundle(optionsCaptor.value).launchWindowingMode)
.isEqualTo(WINDOWING_MODE_MULTI_WINDOW)
@@ -3174,7 +3186,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
verify(splitScreenController)
.startIntent(
any(), anyInt(), any(), any(),
- optionsCaptor.capture(), anyOrNull(), eq(true)
+ optionsCaptor.capture(), anyOrNull(), eq(true), eq(SPLIT_INDEX_UNDEFINED)
)
assertThat(ActivityOptions.fromBundle(optionsCaptor.value).launchWindowingMode)
.isEqualTo(WINDOWING_MODE_MULTI_WINDOW)
@@ -3188,7 +3200,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val wctCaptor = argumentCaptor<WindowContainerTransaction>()
val transition = Binder()
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull()))
+ .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull(), any()))
.thenReturn(ExitResult.NoExit)
whenever(desktopMixedTransitionHandler
.startLaunchTransition(anyInt(), any(), anyOrNull(), anyOrNull(), anyOrNull()))
@@ -3211,7 +3223,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val runOnStart = RunOnStartTransitionCallback()
val transition = Binder()
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull()))
+ .exitImmersiveIfApplicable(any(), anyInt(), anyOrNull(), any()))
.thenReturn(ExitResult.Exit(immersiveTask.taskId, runOnStart))
whenever(desktopMixedTransitionHandler
.startLaunchTransition(anyInt(), any(), anyOrNull(), anyOrNull(), anyOrNull()))
@@ -3314,7 +3326,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull()))
.thenReturn(transition)
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId)))
+ .exitImmersiveIfApplicable(
+ any(), eq(immersiveTask.displayId), eq(freeformTask.taskId), any()))
.thenReturn(
ExitResult.Exit(
exitingTask = immersiveTask.taskId,
@@ -3324,7 +3337,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
runOpenInstance(immersiveTask, freeformTask.taskId)
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId))
+ .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId), any())
runOnStartTransit.assertOnlyInvocation(transition)
}
@@ -3351,10 +3364,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertThat(findBoundsChange(wct, task)).isEqualTo(STABLE_BOUNDS)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- STABLE_BOUNDS.height(),
STABLE_BOUNDS.width(),
+ STABLE_BOUNDS.height(),
displayController
)
}
@@ -3377,16 +3390,16 @@ class DesktopTasksControllerTest : ShellTestCase() {
)
controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT,
- ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+ ResizeTrigger.SNAP_LEFT_MENU, InputMethod.TOUCH, desktopWindowDecoration)
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.SNAP_LEFT_MENU,
- motionEvent,
+ InputMethod.TOUCH,
task,
- expectedBounds.height(),
expectedBounds.width(),
+ expectedBounds.height(),
displayController
)
}
@@ -3409,7 +3422,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
// Attempt to snap left again
val currentDragBounds = Rect(bounds).apply { offset(-100, 0) }
controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT,
- ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+ ResizeTrigger.SNAP_LEFT_MENU, InputMethod.TOUCH, desktopWindowDecoration)
// Assert that task is NOT updated via WCT
verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
@@ -3423,10 +3436,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.SNAP_LEFT_MENU,
- motionEvent,
+ InputMethod.TOUCH,
task,
- bounds.height(),
bounds.width(),
+ bounds.height(),
displayController
)
}
@@ -3453,8 +3466,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
)
verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
ResizeTrigger.DRAG_LEFT,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
+ preDragBounds.width(),
+ preDragBounds.height(),
displayController
)
}
@@ -3483,6 +3498,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
any(),
any(),
any(),
+ any(),
+ any(),
any()
)
}
@@ -3498,7 +3515,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
controller.handleInstantSnapResizingTask(
- task, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+ task,
+ SnapPosition.LEFT,
+ ResizeTrigger.SNAP_LEFT_MENU,
+ InputMethod.MOUSE,
+ desktopWindowDecoration
+ )
// Assert that task is NOT updated via WCT
verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
@@ -3518,7 +3540,9 @@ class DesktopTasksControllerTest : ShellTestCase() {
)
controller.handleInstantSnapResizingTask(
- task, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, motionEvent, desktopWindowDecoration)
+ task, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, InputMethod.MOUSE,
+ desktopWindowDecoration
+ )
// Assert bounds set to half of the stable bounds
val wct = getLatestToggleResizeDesktopTaskWct(taskBounds)
@@ -3526,16 +3550,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
verify(mockToast, never()).show()
verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
ResizeTrigger.SNAP_LEFT_MENU,
- motionEvent,
+ InputMethod.MOUSE,
task,
+ taskBounds.width(),
+ taskBounds.height(),
displayController
)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.SNAP_LEFT_MENU,
- motionEvent,
+ InputMethod.MOUSE,
task,
- expectedBounds.height(),
expectedBounds.width(),
+ expectedBounds.height(),
displayController
)
}
@@ -3563,10 +3589,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- expectedBounds.height(),
expectedBounds.width(),
+ expectedBounds.height(),
displayController
)
}
@@ -3601,10 +3627,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- boundsBeforeMaximize.height(),
boundsBeforeMaximize.width(),
+ boundsBeforeMaximize.height(),
displayController
)
}
@@ -3629,10 +3655,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- boundsBeforeMaximize.height(),
boundsBeforeMaximize.width(),
+ boundsBeforeMaximize.height(),
displayController
)
}
@@ -3657,10 +3683,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- boundsBeforeMaximize.height(),
boundsBeforeMaximize.width(),
+ boundsBeforeMaximize.height(),
displayController
)
}
@@ -3681,10 +3707,10 @@ class DesktopTasksControllerTest : ShellTestCase() {
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- motionEvent,
+ InputMethod.UNKNOWN_INPUT_METHOD,
task,
- boundsBeforeMaximize.height(),
boundsBeforeMaximize.width(),
+ boundsBeforeMaximize.height(),
displayController
)
}
@@ -3739,7 +3765,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.toggleDesktopTaskFullImmersiveState(task)
- verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(task)
+ verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(eq(task), any())
}
@Test
@@ -3751,7 +3777,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
task.requestedVisibleTypes = WindowInsets.Type.statusBars()
controller.onTaskInfoChanged(task)
- verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(task)
+ verify(mMockDesktopImmersiveController).moveTaskToNonImmersive(eq(task), any())
}
@Test
@@ -3763,7 +3789,20 @@ class DesktopTasksControllerTest : ShellTestCase() {
task.requestedVisibleTypes = WindowInsets.Type.statusBars()
controller.onTaskInfoChanged(task)
- verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(task)
+ verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(eq(task), any())
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
+ fun onTaskInfoChanged_inImmersiveUnrequestsImmersive_inRecentsTransition_noExit() {
+ val task = setUpFreeformTask(DEFAULT_DISPLAY)
+ taskRepository.setTaskInFullImmersiveState(DEFAULT_DISPLAY, task.taskId, immersive = true)
+ recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_REQUESTED)
+
+ task.requestedVisibleTypes = WindowInsets.Type.statusBars()
+ controller.onTaskInfoChanged(task)
+
+ verify(mMockDesktopImmersiveController, never()).moveTaskToNonImmersive(eq(task), any())
}
@Test
@@ -3773,7 +3812,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val runOnStartTransit = RunOnStartTransitionCallback()
val transition = Binder()
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(wct, task.displayId, task.taskId))
+ .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any()))
.thenReturn(
ExitResult.Exit(
exitingTask = 5,
@@ -3784,7 +3823,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)
+ .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any())
runOnStartTransit.assertOnlyInvocation(transition)
}
@@ -3795,7 +3834,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val runOnStartTransit = RunOnStartTransitionCallback()
val transition = Binder()
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(wct, task.displayId, task.taskId))
+ .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any()))
.thenReturn(
ExitResult.Exit(
exitingTask = 5,
@@ -3806,7 +3845,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)
+ .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any())
runOnStartTransit.assertOnlyInvocation(transition)
}
@@ -3816,7 +3855,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val runOnStartTransit = RunOnStartTransitionCallback()
val transition = Binder()
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)))
+ .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any()))
.thenReturn(
ExitResult.Exit(
exitingTask = 5,
@@ -3829,7 +3868,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.moveTaskToFront(task.taskId, remoteTransition = null)
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))
+ .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any())
runOnStartTransit.assertOnlyInvocation(transition)
}
@@ -3839,7 +3878,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val runOnStartTransit = RunOnStartTransitionCallback()
val transition = Binder()
whenever(mMockDesktopImmersiveController
- .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)))
+ .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any()))
.thenReturn(
ExitResult.Exit(
exitingTask = 5,
@@ -3852,7 +3891,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.moveTaskToFront(task.taskId, remoteTransition = null)
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))
+ .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId), any())
runOnStartTransit.assertOnlyInvocation(transition)
}
@@ -3866,7 +3905,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.handleRequest(binder, createTransition(task))
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId))
+ .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId), any())
}
@Test
@@ -3878,7 +3917,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
controller.handleRequest(binder, createTransition(task))
verify(mMockDesktopImmersiveController)
- .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId))
+ .exitImmersiveIfApplicable(eq(binder), any(), eq(task.displayId), any())
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
index 52da7fb811d0..2134f3bb35cc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -46,17 +46,23 @@ class DesktopTestHelpers {
.build()
}
- /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
+ /** Create a task builder that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
@JvmStatic
@JvmOverloads
- fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+ fun createFullscreenTaskBuilder(displayId: Int = DEFAULT_DISPLAY): TestRunningTaskInfoBuilder {
return TestRunningTaskInfoBuilder()
.setDisplayId(displayId)
.setToken(MockToken().token())
.setActivityType(ACTIVITY_TYPE_STANDARD)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN)
.setLastActiveTime(100)
- .build()
+ }
+
+ /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
+ @JvmStatic
+ @JvmOverloads
+ fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+ return createFullscreenTaskBuilder(displayId).build()
}
/** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */
@@ -84,5 +90,15 @@ class DesktopTestHelpers {
.setLastActiveTime(100)
.build()
}
+
+ /** Create a new System Modal task, i.e. a task with a single transparent activity. */
+ @JvmStatic
+ @JvmOverloads
+ fun createSystemModalTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+ return createFullscreenTaskBuilder(displayId)
+ .setTopActivityTransparent(true)
+ .setNumActivities(1)
+ .build()
+ }
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
new file mode 100644
index 000000000000..79d90838cecc
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode.compatui
+
+import android.os.Binder
+import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_CLOSE
+import android.view.WindowManager.TRANSIT_OPEN
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTaskBuilder
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSystemModalTask
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.transition.TransitionInfoBuilder
+import com.android.wm.shell.transition.Transitions
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SystemModalsTransitionHandlerTest : ShellTestCase() {
+ private val mainExecutor = mock<ShellExecutor>()
+ private val animExecutor = mock<ShellExecutor>()
+ private val shellInit = mock<ShellInit>()
+ private val transitions = mock<Transitions>()
+ private val desktopRepository = mock<DesktopRepository>()
+ private val startT = mock<SurfaceControl.Transaction>()
+ private val finishT = mock<SurfaceControl.Transaction>()
+
+ private lateinit var transitionHandler: SystemModalsTransitionHandler
+
+ @Before
+ fun setUp() {
+ // Simulate having one Desktop task so that we see Desktop Mode as active
+ whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
+ transitionHandler = createTransitionHandler()
+ }
+
+ private fun createTransitionHandler() =
+ SystemModalsTransitionHandler(
+ context,
+ mainExecutor,
+ animExecutor,
+ shellInit,
+ transitions,
+ desktopRepository,
+ )
+
+ @Test
+ fun instantiate_addsInitCallback() {
+ verify(shellInit).addInitCallback(any(), any<SystemModalsTransitionHandler>())
+ }
+
+ @Test
+ fun startAnimation_desktopNotActive_doesNotAnimate() {
+ whenever(desktopRepository.getVisibleTaskCount(anyInt())).thenReturn(1)
+ val info =
+ TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, createSystemModalTask())
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
+ }
+
+ @Test
+ fun startAnimation_launchingSystemModal_animates() {
+ val info =
+ TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, createSystemModalTask())
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
+ }
+
+ @Test
+ fun startAnimation_nonLaunchingSystemModal_doesNotAnimate() {
+ val info =
+ TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_CHANGE, createSystemModalTask())
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
+ }
+
+ @Test
+ fun startAnimation_launchingFullscreenTask_doesNotAnimate() {
+ val info =
+ TransitionInfoBuilder(TRANSIT_OPEN)
+ .addChange(TRANSIT_OPEN, createFullscreenTask())
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
+ }
+
+ @Test
+ fun startAnimation_closingSystemModal_animates() {
+ val info =
+ TransitionInfoBuilder(TRANSIT_CLOSE)
+ .addChange(TRANSIT_CLOSE, createSystemModalTask())
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isTrue()
+ }
+
+ @Test
+ fun startAnimation_closingFullscreenTask_doesNotAnimate() {
+ val info =
+ TransitionInfoBuilder(TRANSIT_CLOSE)
+ .addChange(TRANSIT_CLOSE, createFullscreenTask())
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), info, startT, finishT) {}).isFalse()
+ }
+
+ @Test
+ fun startAnimation_closingPreviouslyLaunchedSystemModal_animates() {
+ val systemModalTask = createSystemModalTask()
+ val nonModalSystemModalTask =
+ createFullscreenTaskBuilder().setTaskId(systemModalTask.taskId).build()
+ val launchInfo =
+ TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, systemModalTask).build()
+ transitionHandler.startAnimation(Binder(), launchInfo, startT, finishT) {}
+ val closeInfo =
+ TransitionInfoBuilder(TRANSIT_CLOSE)
+ .addChange(TRANSIT_CLOSE, nonModalSystemModalTask)
+ .build()
+
+ assertThat(transitionHandler.startAnimation(Binder(), closeInfo, startT, finishT) {})
+ .isTrue()
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/SplitDragPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/SplitDragPolicyTest.java
index 2cfce6933e1b..0cf15baf30b0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/SplitDragPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/SplitDragPolicyTest.java
@@ -24,6 +24,7 @@ import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED;
import static com.android.wm.shell.draganddrop.DragTestUtils.createAppClipData;
import static com.android.wm.shell.draganddrop.DragTestUtils.createIntentClipData;
import static com.android.wm.shell.draganddrop.DragTestUtils.createTaskInfo;
@@ -226,7 +227,7 @@ public class SplitDragPolicyTest extends ShellTestCase {
mPolicy.onDropped(filterTargetByType(targets, TYPE_FULLSCREEN), null /* hideTaskToken */);
verify(mFullscreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_UNDEFINED), any(), any());
+ eq(SPLIT_POSITION_UNDEFINED), any(), any(), eq(SPLIT_INDEX_UNDEFINED));
}
private void dragOverFullscreenApp_expectSplitScreenTargets(ClipData data) {
@@ -241,12 +242,12 @@ public class SplitDragPolicyTest extends ShellTestCase {
mPolicy.onDropped(filterTargetByType(targets, TYPE_SPLIT_LEFT), null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any(), eq(SPLIT_INDEX_UNDEFINED));
reset(mSplitScreenStarter);
mPolicy.onDropped(filterTargetByType(targets, TYPE_SPLIT_RIGHT), null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any());
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any(), eq(SPLIT_INDEX_UNDEFINED));
}
private void dragOverFullscreenAppPhone_expectVerticalSplitScreenTargets(ClipData data) {
@@ -261,13 +262,13 @@ public class SplitDragPolicyTest extends ShellTestCase {
mPolicy.onDropped(filterTargetByType(targets, TYPE_SPLIT_TOP), null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any(), eq(SPLIT_INDEX_UNDEFINED));
reset(mSplitScreenStarter);
mPolicy.onDropped(filterTargetByType(targets, TYPE_SPLIT_BOTTOM),
null /* hideTaskToken */);
verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any());
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any(), eq(SPLIT_INDEX_UNDEFINED));
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 5f58265b45f5..289fd2d838fd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -36,6 +36,8 @@ import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.os.RemoteException;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Rational;
@@ -46,6 +48,7 @@ import android.window.WindowContainerToken;
import androidx.test.filters.SmallTest;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.MockSurfaceControlHelper;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -67,6 +70,8 @@ import com.android.wm.shell.pip.phone.PhonePipMenuController;
import com.android.wm.shell.splitscreen.SplitScreenController;
import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
@@ -81,7 +86,13 @@ import java.util.Optional;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
+@DisableFlags(Flags.FLAG_ENABLE_PIP2)
public class PipTaskOrganizerTest extends ShellTestCase {
+ @ClassRule
+ public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule();
+
private PipTaskOrganizer mPipTaskOrganizer;
@Mock private DisplayController mMockDisplayController;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 96003515a485..b123f4dfac9e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -42,11 +42,14 @@ import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
@@ -74,6 +77,8 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -88,7 +93,11 @@ import java.util.Set;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
+@DisableFlags(Flags.FLAG_ENABLE_PIP2)
public class PipControllerTest extends ShellTestCase {
+ @ClassRule public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule();
+ @Rule public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule();
+
private PipController mPipController;
private ShellInit mShellInit;
private ShellController mShellController;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
index 6087763b4978..f0f5fe159069 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java
@@ -16,7 +16,16 @@
package com.android.wm.shell.recents;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING;
+import static com.android.wm.shell.recents.RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED;
+import static com.android.wm.shell.transition.Transitions.TRANSIT_START_RECENTS_TRANSITION;
+
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
@@ -27,6 +36,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IApplicationThread;
import android.app.KeyguardManager;
@@ -38,7 +48,10 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -47,6 +60,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.internal.os.IResultReceiver;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
@@ -56,7 +70,9 @@ import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.HomeTransitionObserver;
+import com.android.wm.shell.transition.TransitionInfoBuilder;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.StubTransaction;
import org.junit.After;
import org.junit.Before;
@@ -93,6 +109,8 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
private IRecentTasksListener mRecentTasksListener;
@Mock
private TaskStackTransitionObserver mTaskStackTransitionObserver;
+ @Mock
+ private Transitions mTransitions;
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -129,10 +147,9 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController),
mMainExecutor);
- final Transitions transitions = mock(Transitions.class);
- doReturn(mMainExecutor).when(transitions).getMainExecutor();
+ doReturn(mMainExecutor).when(mTransitions).getMainExecutor();
mRecentsTransitionHandler = new RecentsTransitionHandler(mShellInit, mShellTaskOrganizer,
- transitions, mRecentTasksController, mock(HomeTransitionObserver.class));
+ mTransitions, mRecentTasksController, mock(HomeTransitionObserver.class));
mShellInit.init();
}
@@ -146,12 +163,8 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
public void testStartSyntheticRecentsTransition_callsOnAnimationStartAndFinishCallback() throws Exception {
final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class);
final IResultReceiver finishCallback = mock(IResultReceiver.class);
- doReturn(new Binder()).when(runner).asBinder();
- Bundle options = new Bundle();
- options.putBoolean("is_synthetic_recents_transition", true);
- IBinder transition = mRecentsTransitionHandler.startRecentsTransition(
- mock(PendingIntent.class), new Intent(), options, mock(IApplicationThread.class),
- runner);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner);
verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any());
// Finish and verify no transition remains and that the provided finish callback is called
@@ -165,12 +178,8 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
@Test
public void testStartSyntheticRecentsTransition_callsOnAnimationCancel() throws Exception {
final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class);
- doReturn(new Binder()).when(runner).asBinder();
- Bundle options = new Bundle();
- options.putBoolean("is_synthetic_recents_transition", true);
- IBinder transition = mRecentsTransitionHandler.startRecentsTransition(
- mock(PendingIntent.class), new Intent(), options, mock(IApplicationThread.class),
- runner);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner);
verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any());
mRecentsTransitionHandler.findController(transition).cancel("test");
@@ -178,4 +187,137 @@ public class RecentsTransitionHandlerTest extends ShellTestCase {
verify(runner).onAnimationCanceled(any(), any());
assertNull(mRecentsTransitionHandler.findController(transition));
}
+
+ @Test
+ public void testStartTransition_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ startRecentsTransition(/* synthetic= */ false);
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_REQUESTED);
+ }
+
+ @Test
+ public void testStartAnimation_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ false);
+ mRecentsTransitionHandler.startAnimation(
+ transition, createTransitionInfo(), new StubTransaction(), new StubTransaction(),
+ mock(Transitions.TransitionFinishCallback.class));
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_ANIMATING);
+ }
+
+ @Test
+ public void testFinishTransition_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ false);
+ mRecentsTransitionHandler.startAnimation(
+ transition, createTransitionInfo(), new StubTransaction(), new StubTransaction(),
+ mock(Transitions.TransitionFinishCallback.class));
+ mRecentsTransitionHandler.findController(transition).finish(true /* toHome */,
+ false /* sendUserLeaveHint */, mock(IResultReceiver.class));
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+ }
+
+ @Test
+ public void testCancelTransition_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ false);
+ mRecentsTransitionHandler.findController(transition).cancel("test");
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+ }
+
+ @Test
+ public void testStartAnimation_synthetic_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ startRecentsTransition(/* synthetic= */ true);
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_ANIMATING);
+ }
+
+ @Test
+ public void testFinishTransition_synthetic_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ true);
+ mRecentsTransitionHandler.findController(transition).finish(true /* toHome */,
+ false /* sendUserLeaveHint */, mock(IResultReceiver.class));
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+ }
+
+ @Test
+ public void testCancelTransition_synthetic_updatesStateListeners() {
+ final TestTransitionStateListener listener = new TestTransitionStateListener();
+ mRecentsTransitionHandler.addTransitionStateListener(listener);
+
+ final IBinder transition = startRecentsTransition(/* synthetic= */ true);
+ mRecentsTransitionHandler.findController(transition).cancel("test");
+ mMainExecutor.flushAll();
+
+ assertThat(listener.getState()).isEqualTo(TRANSITION_STATE_NOT_RUNNING);
+ }
+
+ private IBinder startRecentsTransition(boolean synthetic) {
+ return startRecentsTransition(synthetic, mock(IRecentsAnimationRunner.class));
+ }
+
+ private IBinder startRecentsTransition(boolean synthetic,
+ @NonNull IRecentsAnimationRunner runner) {
+ doReturn(new Binder()).when(runner).asBinder();
+ final Bundle options = new Bundle();
+ options.putBoolean("is_synthetic_recents_transition", synthetic);
+ final IBinder transition = new Binder();
+ when(mTransitions.startTransition(anyInt(), any(), any())).thenReturn(transition);
+ return mRecentsTransitionHandler.startRecentsTransition(
+ mock(PendingIntent.class), new Intent(), options, mock(IApplicationThread.class),
+ runner);
+ }
+
+ private TransitionInfo createTransitionInfo() {
+ final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder()
+ .setTopActivityType(ACTIVITY_TYPE_HOME)
+ .build();
+ final TransitionInfo.Change homeChange = new TransitionInfo.Change(
+ task.token, new SurfaceControl());
+ homeChange.setMode(TRANSIT_TO_FRONT);
+ homeChange.setTaskInfo(task);
+ return new TransitionInfoBuilder(TRANSIT_START_RECENTS_TRANSITION)
+ .addChange(homeChange)
+ .build();
+ }
+
+ private static class TestTransitionStateListener implements RecentsTransitionStateListener {
+ @RecentsTransitionState
+ private int mState = TRANSITION_STATE_NOT_RUNNING;
+
+ @Override
+ public void onTransitionStateChanged(int state) {
+ mState = state;
+ }
+
+ @RecentsTransitionState
+ int getState() {
+ return mState;
+ }
+ }
}
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 966651f19711..72a7a3f5ec99 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
@@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_0;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
@@ -200,10 +201,11 @@ public class SplitScreenControllerTests extends ShellTestCase {
PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
+ SPLIT_INDEX_0);
verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull(), eq(SPLIT_INDEX_0));
assertEquals(FLAG_ACTIVITY_NO_USER_ACTION,
mIntentCaptor.getValue().getFlags() & FLAG_ACTIVITY_NO_USER_ACTION);
}
@@ -220,10 +222,11 @@ public class SplitScreenControllerTests extends ShellTestCase {
doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
+ SPLIT_INDEX_0);
verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
- eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull());
+ eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull(), eq(SPLIT_INDEX_0));
assertEquals(FLAG_ACTIVITY_MULTIPLE_TASK,
mIntentCaptor.getValue().getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK);
}
@@ -243,10 +246,11 @@ public class SplitScreenControllerTests extends ShellTestCase {
doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt(), any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
+ SPLIT_INDEX_0);
verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
- isNull(), isNull());
+ isNull(), isNull(), eq(SPLIT_INDEX_0));
verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any());
verify(mStageCoordinator, never()).switchSplitPosition(any());
}
@@ -269,10 +273,11 @@ public class SplitScreenControllerTests extends ShellTestCase {
.findTaskInBackground(any(), anyInt(), any());
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
+ SPLIT_INDEX_0);
verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any());
verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
- isNull(), isNull());
+ isNull(), isNull(), eq(SPLIT_INDEX_0));
}
@Test
@@ -289,7 +294,8 @@ public class SplitScreenControllerTests extends ShellTestCase {
SPLIT_POSITION_BOTTOM_OR_RIGHT);
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
- SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
+ SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
+ SPLIT_INDEX_0);
verify(mStageCoordinator).switchSplitPosition(anyString());
}
@@ -301,7 +307,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
- true /* forceLaunchNewTask */);
+ true /* forceLaunchNewTask */, SPLIT_INDEX_0);
verify(mRecentTasks, never()).findTaskInBackground(any(), anyInt(), any());
}
@@ -312,7 +318,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */,
- false /* forceLaunchNewTask */);
+ false /* forceLaunchNewTask */, SPLIT_INDEX_0);
verify(mRecentTasks).findTaskInBackground(any(), anyInt(), any());
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
index 66dcef6f14cc..d13a8888edc7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -53,8 +53,8 @@ public class SplitTestUtils {
doReturn(dividerBounds).when(out).getDividerBounds();
doReturn(dividerBounds).when(out).getRefDividerBounds();
doReturn(leash).when(out).getDividerLeash();
- doReturn(bounds1).when(out).getBounds1();
- doReturn(bounds2).when(out).getBounds2();
+ doReturn(bounds1).when(out).getTopLeftBounds();
+ doReturn(bounds2).when(out).getBottomRightBounds();
return out;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index ce3944a5855e..e32cf3899a03 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -27,6 +27,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
@@ -133,11 +134,11 @@ public class SplitTransitionTests extends ShellTestCase {
mSplitLayout = SplitTestUtils.createMockSplitLayout();
mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
StageTaskListener.StageListenerCallbacks.class), mSyncQueue,
- mIconProvider, Optional.of(mWindowDecorViewModel)));
+ mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN));
mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
StageTaskListener.StageListenerCallbacks.class), mSyncQueue,
- mIconProvider, Optional.of(mWindowDecorViewModel)));
+ mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE));
mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
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 a252a9db7095..1e739cd446ae 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
@@ -19,6 +19,7 @@ package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -33,6 +34,7 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -140,8 +142,8 @@ public class StageCoordinatorTests extends ShellTestCase {
Optional.empty()));
mDividerLeash = new SurfaceControl.Builder().setName("fakeDivider").build();
- when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
- when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
+ when(mSplitLayout.getTopLeftBounds()).thenReturn(mBounds1);
+ when(mSplitLayout.getBottomRightBounds()).thenReturn(mBounds2);
when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
when(mSplitLayout.isLeftRightSplit()).thenReturn(false);
when(mSplitLayout.applyTaskChanges(any(), any(), any())).thenReturn(true);
@@ -165,8 +167,9 @@ public class StageCoordinatorTests extends ShellTestCase {
final WindowContainerTransaction wct = spy(new WindowContainerTransaction());
mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
+ // TODO(b/349828130) Address this once we remove index_undefined called
verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), eq(false));
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), eq(false), eq(SPLIT_INDEX_UNDEFINED));
verify(mMainStage).reparentTopTask(eq(wct));
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
@@ -183,8 +186,9 @@ public class StageCoordinatorTests extends ShellTestCase {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
+ // TODO(b/349828130) Address this once we remove index_undefined called
verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), eq(false));
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), eq(false), eq(SPLIT_INDEX_UNDEFINED));
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
}
@@ -195,8 +199,9 @@ public class StageCoordinatorTests extends ShellTestCase {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
+ // TODO(b/349828130) Address this once we remove index_undefined called
verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
- eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), eq(false));
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), eq(false), eq(SPLIT_INDEX_UNDEFINED));
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
}
@@ -292,7 +297,8 @@ public class StageCoordinatorTests extends ShellTestCase {
public void testFinishEnterSplitScreen_applySurfaceLayout() {
mStageCoordinator.finishEnterSplitScreen(new SurfaceControl.Transaction());
- verify(mSplitLayout).applySurfaceChanges(any(), any(), any(), any(), any(), eq(false));
+ verify(mSplitLayout, atLeastOnce())
+ .applySurfaceChanges(any(), any(), any(), any(), any(), eq(false));
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index 7144a1e038f9..fe91440b106f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -19,6 +19,8 @@ package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
@@ -93,7 +95,8 @@ public final class StageTaskListenerTests extends ShellTestCase {
mCallbacks,
mSyncQueue,
mIconProvider,
- Optional.of(mWindowDecorViewModel));
+ Optional.of(mWindowDecorViewModel),
+ STAGE_TYPE_UNDEFINED);
mRootTask = new TestRunningTaskInfoBuilder().build();
mRootTask.parentTaskId = INVALID_TASK_ID;
mSurfaceControl = new SurfaceControl.Builder().setName("test").build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
new file mode 100644
index 000000000000..a15b61122713
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WindowingMode
+import android.content.ComponentName
+import android.content.pm.ActivityInfo
+import android.platform.test.annotations.EnableFlags
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.Display.DEFAULT_DISPLAY
+import android.view.SurfaceControl
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.window.flags.Flags
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.times
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.verify
+import org.mockito.quality.Strictness
+
+/**
+ * Tests of [DesktopModeWindowDecorViewModelAppHandleOnlyTest]
+ *
+ * A subset of tests from [DesktopModeWindowDecorViewModel] for when DesktopMode is not active
+ * but we still need to show AppHandle
+ * Usage: atest WMShellUnitTests:DesktopModeWindowDecorViewModelAppHandleOnlyTest
+ */
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@EnableFlags(Flags.FLAG_UNIVERSAL_RESIZABLE_BY_DEFAULT)
+@RunWithLooper
+class DesktopModeWindowDecorViewModelAppHandleOnlyTest :
+ DesktopModeWindowDecorViewModelTestsBase() {
+
+ @Before
+ fun setUp() {
+ mockitoSession =
+ mockitoSession()
+ .strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java)
+ .spyStatic(DragPositioningCallbackUtility::class.java)
+ .startMocking()
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ doReturn(true).`when` { DesktopModeStatus.overridesShowAppHandle(any())}
+ setUpCommon()
+ }
+
+ @Test
+ fun testWindowDecor_showAppHandle_decorCreated() {
+ val task = createTask()
+
+ setUpMockDecorationForTask(task)
+
+ onTaskOpening(task)
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
+ }
+
+ @Test
+ fun testWindowDecor_dontShowAppHandle_decorNotCreated() {
+ // Simulate device that doesn't support showing app handle
+ doReturn(false).`when` { DesktopModeStatus.overridesShowAppHandle(any())}
+
+ val task = createTask()
+
+ onTaskOpening(task)
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
+ }
+
+ @Test
+ fun testDeleteDecorationOnChangeTransitionWhenNecessary() {
+ val task = createTask()
+ val taskSurface = SurfaceControl()
+ val decoration = setUpMockDecorationForTask(task)
+
+ onTaskOpening(task, taskSurface)
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
+ task.setActivityType(ACTIVITY_TYPE_UNDEFINED)
+ onTaskChanging(task, taskSurface)
+
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
+ verify(decoration).close()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
+ fun testDecor_invokeOpenHandleMenuCallback_openHandleMenu() {
+ val task = createTask()
+ val decor = setUpMockDecorationForTask(task)
+ val openHandleMenuCallbackCaptor = argumentCaptor<(Int) -> Unit>()
+ // Set task as gmail
+ val gmailPackageName = "com.google.android.gm"
+ val baseComponent = ComponentName(gmailPackageName, /* class */ "")
+ task.baseActivity = baseComponent
+
+ onTaskOpening(task)
+ verify(
+ mockAppHandleEducationController,
+ times(1)
+ ).setAppHandleEducationTooltipCallbacks(openHandleMenuCallbackCaptor.capture(), any())
+ openHandleMenuCallbackCaptor.lastValue.invoke(task.taskId)
+
+ verify(decor, times(1)).createHandleMenu(anyBoolean())
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+ fun testDecorationIsNotCreatedForSystemUIActivities() {
+ val task = createTask()
+
+ // Set task as systemUI package
+ val systemUIPackageName = context.resources.getString(
+ com.android.internal.R.string.config_systemUi)
+ val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
+ task.baseActivity = baseComponent
+
+ onTaskOpening(task)
+
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
+ }
+
+ @Test
+ fun testAppHandleShowsOnlyOnLargeDisplay() {
+ val task = createTask()
+ val taskSurface = SurfaceControl()
+ setUpMockDecorationForTask(task)
+ onTaskOpening(task, taskSurface)
+ assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
+
+
+ task.setOnLargeScreen(false)
+ setUpMockDecorationForTask(task)
+ onTaskChanging(task, taskSurface)
+ assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
+ }
+
+ private fun createTask(
+ displayId: Int = DEFAULT_DISPLAY,
+ @WindowingMode windowingMode: Int = WINDOWING_MODE_FULLSCREEN,
+ activityType: Int = ACTIVITY_TYPE_STANDARD,
+ activityInfo: ActivityInfo = ActivityInfo(),
+ requestingImmersive: Boolean = false,
+ shouldShowAspectRatioButton: Boolean = true
+ ): RunningTaskInfo {
+ val task = createTask(
+ displayId, windowingMode, activityType, activityInfo, requestingImmersive)
+ task.setOnLargeScreen(shouldShowAspectRatioButton)
+ return task
+ }
+
+ private fun RunningTaskInfo.setOnLargeScreen(large: Boolean) {
+ configuration.smallestScreenWidthDp = if (large) 1000 else 100
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index ef9b30c1c4ca..7bb8e891e33b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -28,31 +28,19 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_MAIN
-import android.content.pm.ActivityInfo
import android.graphics.Rect
import android.graphics.Region
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.hardware.input.InputManager
import android.net.Uri
-import android.os.Handler
import android.os.SystemClock
-import android.os.UserHandle
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import android.platform.test.flag.junit.CheckFlagsRule
-import android.platform.test.flag.junit.DeviceFlagsValueProvider
-import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
-import android.testing.TestableContext
import android.testing.TestableLooper.RunWithLooper
-import android.util.SparseArray
-import android.view.Choreographer
import android.view.Display.DEFAULT_DISPLAY
import android.view.ISystemGestureExclusionListener
-import android.view.IWindowManager
-import android.view.InputChannel
-import android.view.InputMonitor
import android.view.InsetsSource
import android.view.InsetsState
import android.view.KeyEvent
@@ -69,67 +57,29 @@ import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
-import com.android.dx.mockito.inline.extended.StaticMockitoSession
-import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.wm.shell.R
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer
-import com.android.wm.shell.ShellTaskOrganizer
-import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.TestRunningTaskInfoBuilder
-import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser
-import com.android.wm.shell.apptoweb.AssistContentRequester
-import com.android.wm.shell.common.DisplayChangeController
-import com.android.wm.shell.common.DisplayController
-import com.android.wm.shell.common.DisplayInsetsController
-import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.common.MultiInstanceHelper
-import com.android.wm.shell.common.SyncTransactionQueue
-import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler
-import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
-import com.android.wm.shell.desktopmode.DesktopRepository
-import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
-import com.android.wm.shell.desktopmode.DesktopTasksLimiter
-import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository
-import com.android.wm.shell.desktopmode.education.AppHandleEducationController
-import com.android.wm.shell.desktopmode.education.AppToWebEducationController
-import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.splitscreen.SplitScreenController
-import com.android.wm.shell.sysui.ShellCommandHandler
-import com.android.wm.shell.sysui.ShellController
-import com.android.wm.shell.sysui.ShellInit
-import com.android.wm.shell.transition.FocusTransitionObserver
-import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeKeyguardChangeListener
-import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener
-import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder
-import java.util.Optional
-import java.util.function.Consumer
-import java.util.function.Supplier
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
-import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentCaptor.forClass
-import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.kotlin.KArgumentCaptor
-import org.mockito.kotlin.verify
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.argThat
@@ -137,9 +87,10 @@ import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
-import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
+import java.util.function.Consumer
/**
@@ -150,72 +101,7 @@ import org.mockito.quality.Strictness
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
-class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
- @JvmField
- @Rule
- val setFlagsRule = SetFlagsRule()
-
- @JvmField
- @Rule
- val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
-
- @Mock private lateinit var mockDesktopModeWindowDecorFactory:
- DesktopModeWindowDecoration.Factory
- @Mock private lateinit var mockMainHandler: Handler
- @Mock private lateinit var mockMainChoreographer: Choreographer
- @Mock private lateinit var mockTaskOrganizer: ShellTaskOrganizer
- @Mock private lateinit var mockDisplayController: DisplayController
- @Mock private lateinit var mockSplitScreenController: SplitScreenController
- @Mock private lateinit var mockDesktopRepository: DesktopRepository
- @Mock private lateinit var mockDisplayLayout: DisplayLayout
- @Mock private lateinit var displayInsetsController: DisplayInsetsController
- @Mock private lateinit var mockSyncQueue: SyncTransactionQueue
- @Mock private lateinit var mockDesktopTasksController: DesktopTasksController
- @Mock private lateinit var mockInputMonitor: InputMonitor
- @Mock private lateinit var mockTransitions: Transitions
- @Mock private lateinit var mockInputMonitorFactory:
- DesktopModeWindowDecorViewModel.InputMonitorFactory
- @Mock private lateinit var mockShellController: ShellController
- private val testShellExecutor = TestShellExecutor()
- @Mock private lateinit var mockAppHeaderViewHolderFactory: AppHeaderViewHolder.Factory
- @Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
- @Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
- @Mock private lateinit var mockWindowManager: IWindowManager
- @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
- @Mock private lateinit var mockGenericLinksParser: AppToWebGenericLinksParser
- @Mock private lateinit var mockUserHandle: UserHandle
- @Mock private lateinit var mockAssistContentRequester: AssistContentRequester
- private val bgExecutor = TestShellExecutor()
- @Mock private lateinit var mockMultiInstanceHelper: MultiInstanceHelper
- @Mock private lateinit var mockTasksLimiter: DesktopTasksLimiter
- @Mock private lateinit var mockFreeformTaskTransitionStarter: FreeformTaskTransitionStarter
- @Mock private lateinit var mockActivityOrientationChangeHandler:
- DesktopActivityOrientationChangeHandler
- @Mock private lateinit var mockInputManager: InputManager
- @Mock private lateinit var mockTaskPositionerFactory:
- DesktopModeWindowDecorViewModel.TaskPositionerFactory
- @Mock private lateinit var mockTaskPositioner: TaskPositioner
- @Mock private lateinit var mockAppHandleEducationController: AppHandleEducationController
- @Mock private lateinit var mockAppToWebEducationController: AppToWebEducationController
- @Mock private lateinit var mockFocusTransitionObserver: FocusTransitionObserver
- @Mock private lateinit var mockCaptionHandleRepository: WindowDecorCaptionHandleRepository
- @Mock private lateinit var motionEvent: MotionEvent
- @Mock lateinit var displayController: DisplayController
- @Mock lateinit var displayLayout: DisplayLayout
- private lateinit var spyContext: TestableContext
- private lateinit var desktopModeEventLogger: DesktopModeEventLogger
-
- private val transactionFactory = Supplier<SurfaceControl.Transaction> {
- SurfaceControl.Transaction()
- }
- private val windowDecorByTaskIdSpy = spy(SparseArray<DesktopModeWindowDecoration>())
-
- private lateinit var mockitoSession: StaticMockitoSession
- private lateinit var shellInit: ShellInit
- private lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener
- private lateinit var displayChangingListener: DisplayChangeController.OnDisplayChangingListener
- private lateinit var desktopModeOnKeyguardChangedListener: DesktopModeKeyguardChangeListener
- private lateinit var desktopModeWindowDecorViewModel: DesktopModeWindowDecorViewModel
+class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTestsBase() {
@Before
fun setUp() {
@@ -225,98 +111,11 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
.spyStatic(DesktopModeStatus::class.java)
.spyStatic(DragPositioningCallbackUtility::class.java)
.startMocking()
- doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(Mockito.any()) }
-
- spyContext = spy(mContext)
- doNothing().`when`(spyContext).startActivity(any())
- shellInit = ShellInit(testShellExecutor)
- windowDecorByTaskIdSpy.clear()
- spyContext.addMockSystemService(InputManager::class.java, mockInputManager)
- desktopModeEventLogger = mock<DesktopModeEventLogger>()
- desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
- spyContext,
- testShellExecutor,
- mockMainHandler,
- mockMainChoreographer,
- bgExecutor,
- shellInit,
- mockShellCommandHandler,
- mockWindowManager,
- mockTaskOrganizer,
- mockDesktopRepository,
- mockDisplayController,
- mockShellController,
- displayInsetsController,
- mockSyncQueue,
- mockTransitions,
- Optional.of(mockDesktopTasksController),
- mockGenericLinksParser,
- mockAssistContentRequester,
- mockMultiInstanceHelper,
- mockDesktopModeWindowDecorFactory,
- mockInputMonitorFactory,
- transactionFactory,
- mockAppHeaderViewHolderFactory,
- mockRootTaskDisplayAreaOrganizer,
- windowDecorByTaskIdSpy,
- mockInteractionJankMonitor,
- Optional.of(mockTasksLimiter),
- mockAppHandleEducationController,
- mockAppToWebEducationController,
- mockCaptionHandleRepository,
- Optional.of(mockActivityOrientationChangeHandler),
- mockTaskPositionerFactory,
- mockFocusTransitionObserver,
- desktopModeEventLogger
- )
- desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
- whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
- whenever(mockDisplayLayout.stableInsets()).thenReturn(STABLE_INSETS)
- whenever(mockInputMonitorFactory.create(any(), any())).thenReturn(mockInputMonitor)
- whenever(
- mockTaskPositionerFactory.create(
- any(),
- any(),
- any(),
- any(),
- any(),
- any(),
- any(),
- any()
- )
- )
- .thenReturn(mockTaskPositioner)
-
- // InputChannel cannot be mocked because it passes to InputEventReceiver.
- val inputChannels = InputChannel.openInputChannelPair(TAG)
- inputChannels.first().dispose()
- whenever(mockInputMonitor.inputChannel).thenReturn(inputChannels[1])
- shellInit.init()
-
- val displayChangingListenerCaptor =
- argumentCaptor<DisplayChangeController.OnDisplayChangingListener>()
- verify(mockDisplayController)
- .addDisplayChangingController(displayChangingListenerCaptor.capture())
- displayChangingListener = displayChangingListenerCaptor.firstValue
- val insetsChangedCaptor =
- argumentCaptor<DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener>()
- verify(displayInsetsController)
- .addGlobalInsetsChangedListener(insetsChangedCaptor.capture())
- desktopModeOnInsetsChangedListener = insetsChangedCaptor.firstValue
- val keyguardChangedCaptor =
- argumentCaptor<DesktopModeKeyguardChangeListener>()
- verify(mockShellController).addKeyguardChangeListener(keyguardChangedCaptor.capture())
- desktopModeOnKeyguardChangedListener = keyguardChangedCaptor.firstValue
- whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
- whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
- (i.arguments.first() as Rect).set(STABLE_BOUNDS)
- }
- }
+ doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(Mockito.any()) }
+ doReturn(false).`when` { DesktopModeStatus.overridesShowAppHandle(Mockito.any()) }
- @After
- fun tearDown() {
- mockitoSession.finishMocking()
+ setUpCommon()
}
@Test
@@ -559,20 +358,6 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun testWindowDecor_desktopModeUnsupportedOnDevice_decorNotCreated() {
- // Simulate default enforce device restrictions system property
- whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
-
- val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN)
- // Simulate device that doesn't support desktop mode
- doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
-
- onTaskOpening(task)
- assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
fun testWindowDecor_desktopModeUnsupportedOnDevice_deviceRestrictionsOverridden_decorCreated() {
// Simulate enforce device restrictions system property overridden to false
whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(false)
@@ -648,7 +433,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
eq(SnapPosition.LEFT),
eq(ResizeTrigger.SNAP_LEFT_MENU),
- eq(null),
+ eq(InputMethod.UNKNOWN_INPUT_METHOD),
eq(decor)
)
}
@@ -684,7 +469,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
eq(SnapPosition.LEFT),
eq(ResizeTrigger.SNAP_LEFT_MENU),
- eq(null),
+ eq(InputMethod.UNKNOWN_INPUT_METHOD),
eq(decor),
)
}
@@ -705,7 +490,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
verify(mockDesktopTasksController, never())
.snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT),
eq(ResizeTrigger.MAXIMIZE_BUTTON),
- eq(null),
+ eq(InputMethod.UNKNOWN_INPUT_METHOD),
eq(decor),
)
}
@@ -725,7 +510,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
eq(SnapPosition.RIGHT),
eq(ResizeTrigger.SNAP_RIGHT_MENU),
- eq(null),
+ eq(InputMethod.UNKNOWN_INPUT_METHOD),
eq(decor),
)
}
@@ -761,7 +546,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
eq(SnapPosition.RIGHT),
eq(ResizeTrigger.SNAP_RIGHT_MENU),
- eq(null),
+ eq(InputMethod.UNKNOWN_INPUT_METHOD),
eq(decor),
)
}
@@ -782,7 +567,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
verify(mockDesktopTasksController, never())
.snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT),
eq(ResizeTrigger.MAXIMIZE_BUTTON),
- eq(null),
+ eq(InputMethod.UNKNOWN_INPUT_METHOD),
eq(decor),
)
}
@@ -1419,64 +1204,6 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
return decor
}
- private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
- desktopModeWindowDecorViewModel.onTaskOpening(
- task,
- leash,
- SurfaceControl.Transaction(),
- SurfaceControl.Transaction()
- )
- }
-
- private fun onTaskChanging(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
- desktopModeWindowDecorViewModel.onTaskChanging(
- task,
- leash,
- SurfaceControl.Transaction(),
- SurfaceControl.Transaction()
- )
- }
-
- private fun createTask(
- displayId: Int = DEFAULT_DISPLAY,
- @WindowingMode windowingMode: Int,
- activityType: Int = ACTIVITY_TYPE_STANDARD,
- activityInfo: ActivityInfo = ActivityInfo(),
- requestingImmersive: Boolean = false
- ): RunningTaskInfo {
- return TestRunningTaskInfoBuilder()
- .setDisplayId(displayId)
- .setWindowingMode(windowingMode)
- .setVisible(true)
- .setActivityType(activityType)
- .build().apply {
- topActivityInfo = activityInfo
- isResizeable = true
- requestedVisibleTypes = if (requestingImmersive) {
- statusBars().inv()
- } else {
- statusBars()
- }
- }
- }
-
- private fun setUpMockDecorationForTask(task: RunningTaskInfo): DesktopModeWindowDecoration {
- val decoration = mock(DesktopModeWindowDecoration::class.java)
- whenever(
- mockDesktopModeWindowDecorFactory.create(
- any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(),
- any(), any(), any(), any(), any(), any(), any(), any())
- ).thenReturn(decoration)
- decoration.mTaskInfo = task
- whenever(decoration.user).thenReturn(mockUserHandle)
- if (task.windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
- whenever(mockSplitScreenController.isTaskInSplitScreen(task.taskId))
- .thenReturn(true)
- }
- whenever(decoration.calculateValidDragArea()).thenReturn(Rect(0, 60, 2560, 1600))
- return decoration
- }
-
private fun setUpMockDecorationsForTasks(vararg tasks: RunningTaskInfo) {
tasks.forEach { setUpMockDecorationForTask(it) }
}
@@ -1493,19 +1220,4 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
)
}
-
- private fun RunningTaskInfo.setWindowingMode(@WindowingMode mode: Int) {
- configuration.windowConfiguration.windowingMode = mode
- }
-
- private fun RunningTaskInfo.setActivityType(type: Int) {
- configuration.windowConfiguration.activityType = type
- }
-
- companion object {
- private const val TAG = "DesktopModeWindowDecorViewModelTests"
- private val STABLE_INSETS = Rect(0, 100, 0, 0)
- private val INITIAL_BOUNDS = Rect(0, 0, 100, 100)
- private val STABLE_BOUNDS = Rect(0, 0, 1000, 1000)
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
new file mode 100644
index 000000000000..91eaadaf1f18
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.app.WindowConfiguration.WindowingMode
+import android.content.pm.ActivityInfo
+import android.graphics.Rect
+import android.hardware.input.InputManager
+import android.os.Handler
+import android.os.UserHandle
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.platform.test.flag.junit.SetFlagsRule
+import android.testing.TestableContext
+import android.util.SparseArray
+import android.view.Choreographer
+import android.view.Display.DEFAULT_DISPLAY
+import android.view.IWindowManager
+import android.view.InputChannel
+import android.view.InputMonitor
+import android.view.MotionEvent
+import android.view.SurfaceControl
+import android.view.WindowInsets.Type.statusBars
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser
+import com.android.wm.shell.apptoweb.AssistContentRequester
+import com.android.wm.shell.common.DisplayChangeController
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayInsetsController
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.common.MultiInstanceHelper
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopTasksController
+import com.android.wm.shell.desktopmode.DesktopTasksLimiter
+import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository
+import com.android.wm.shell.desktopmode.education.AppHandleEducationController
+import com.android.wm.shell.desktopmode.education.AppToWebEducationController
+import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
+import com.android.wm.shell.splitscreen.SplitScreenController
+import com.android.wm.shell.sysui.ShellCommandHandler
+import com.android.wm.shell.sysui.ShellController
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.transition.FocusTransitionObserver
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.util.StubTransaction
+import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeKeyguardChangeListener
+import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener
+import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder
+import org.junit.After
+import org.junit.Rule
+import org.mockito.Mockito
+import org.mockito.Mockito.anyInt
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doNothing
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import java.util.Optional
+import java.util.function.Supplier
+
+/**
+ * Utility class for tests of [DesktopModeWindowDecorViewModel]
+ */
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
+ @JvmField
+ @Rule
+ val setFlagsRule = SetFlagsRule()
+
+ @JvmField
+ @Rule
+ val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+ private val mockDesktopModeWindowDecorFactory = mock<DesktopModeWindowDecoration.Factory>()
+ protected val mockMainHandler = mock<Handler>()
+ protected val mockMainChoreographer = mock<Choreographer>()
+ protected val mockTaskOrganizer = mock<ShellTaskOrganizer>()
+ protected val mockDisplayController = mock<DisplayController>()
+ protected val mockSplitScreenController = mock<SplitScreenController>()
+ protected val mockDesktopRepository = mock<DesktopRepository>()
+ protected val mockDisplayLayout = mock<DisplayLayout>()
+ protected val displayInsetsController = mock<DisplayInsetsController>()
+ protected val mockSyncQueue = mock<SyncTransactionQueue>()
+ protected val mockDesktopTasksController = mock<DesktopTasksController>()
+ protected val mockInputMonitor = mock<InputMonitor>()
+ protected val mockTransitions = mock<Transitions>()
+ internal val mockInputMonitorFactory =
+ mock<DesktopModeWindowDecorViewModel.InputMonitorFactory>()
+ protected val mockShellController = mock<ShellController>()
+ protected val testShellExecutor = TestShellExecutor()
+ protected val mockAppHeaderViewHolderFactory = mock<AppHeaderViewHolder.Factory>()
+ protected val mockRootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>()
+ protected val mockShellCommandHandler = mock<ShellCommandHandler>()
+ protected val mockWindowManager = mock<IWindowManager>()
+ protected val mockInteractionJankMonitor = mock<InteractionJankMonitor>()
+ protected val mockGenericLinksParser = mock<AppToWebGenericLinksParser>()
+ protected val mockUserHandle = mock<UserHandle>()
+ protected val mockAssistContentRequester = mock<AssistContentRequester>()
+ protected val bgExecutor = TestShellExecutor()
+ protected val mockMultiInstanceHelper = mock<MultiInstanceHelper>()
+ protected val mockTasksLimiter = mock<DesktopTasksLimiter>()
+ protected val mockFreeformTaskTransitionStarter = mock<FreeformTaskTransitionStarter>()
+ protected val mockActivityOrientationChangeHandler =
+ mock<DesktopActivityOrientationChangeHandler>()
+ protected val mockInputManager = mock<InputManager>()
+ private val mockTaskPositionerFactory =
+ mock<DesktopModeWindowDecorViewModel.TaskPositionerFactory>()
+ protected val mockTaskPositioner = mock<TaskPositioner>()
+ protected val mockAppHandleEducationController = mock<AppHandleEducationController>()
+ protected val mockAppToWebEducationController = mock<AppToWebEducationController>()
+ protected val mockFocusTransitionObserver = mock<FocusTransitionObserver>()
+ protected val mockCaptionHandleRepository = mock<WindowDecorCaptionHandleRepository>()
+ protected val motionEvent = mock<MotionEvent>()
+ val displayController = mock<DisplayController>()
+ val displayLayout = mock<DisplayLayout>()
+ protected lateinit var spyContext: TestableContext
+ private lateinit var desktopModeEventLogger: DesktopModeEventLogger
+
+ private val transactionFactory = Supplier<SurfaceControl.Transaction> {
+ SurfaceControl.Transaction()
+ }
+ protected val windowDecorByTaskIdSpy = spy(SparseArray<DesktopModeWindowDecoration>())
+
+ protected lateinit var mockitoSession: StaticMockitoSession
+ protected lateinit var shellInit: ShellInit
+ internal lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener
+ protected lateinit var displayChangingListener:
+ DisplayChangeController.OnDisplayChangingListener
+ internal lateinit var desktopModeOnKeyguardChangedListener: DesktopModeKeyguardChangeListener
+ protected lateinit var desktopModeWindowDecorViewModel: DesktopModeWindowDecorViewModel
+
+ fun setUpCommon() {
+ spyContext = spy(mContext)
+ doNothing().`when`(spyContext).startActivity(any())
+ shellInit = ShellInit(testShellExecutor)
+ windowDecorByTaskIdSpy.clear()
+ spyContext.addMockSystemService(InputManager::class.java, mockInputManager)
+ desktopModeEventLogger = mock<DesktopModeEventLogger>()
+ desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
+ spyContext,
+ testShellExecutor,
+ mockMainHandler,
+ mockMainChoreographer,
+ bgExecutor,
+ shellInit,
+ mockShellCommandHandler,
+ mockWindowManager,
+ mockTaskOrganizer,
+ mockDesktopRepository,
+ mockDisplayController,
+ mockShellController,
+ displayInsetsController,
+ mockSyncQueue,
+ mockTransitions,
+ Optional.of(mockDesktopTasksController),
+ mockGenericLinksParser,
+ mockAssistContentRequester,
+ mockMultiInstanceHelper,
+ mockDesktopModeWindowDecorFactory,
+ mockInputMonitorFactory,
+ transactionFactory,
+ mockAppHeaderViewHolderFactory,
+ mockRootTaskDisplayAreaOrganizer,
+ windowDecorByTaskIdSpy,
+ mockInteractionJankMonitor,
+ Optional.of(mockTasksLimiter),
+ mockAppHandleEducationController,
+ mockAppToWebEducationController,
+ mockCaptionHandleRepository,
+ Optional.of(mockActivityOrientationChangeHandler),
+ mockTaskPositionerFactory,
+ mockFocusTransitionObserver,
+ desktopModeEventLogger
+ )
+ desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
+ whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
+ whenever(mockDisplayLayout.stableInsets()).thenReturn(STABLE_INSETS)
+ whenever(mockInputMonitorFactory.create(any(), any())).thenReturn(mockInputMonitor)
+ whenever(
+ mockTaskPositionerFactory.create(
+ any(),
+ any(),
+ any(),
+ any(),
+ any(),
+ any(),
+ any(),
+ any()
+ )
+ )
+ .thenReturn(mockTaskPositioner)
+
+ // InputChannel cannot be mocked because it passes to InputEventReceiver.
+ val inputChannels = InputChannel.openInputChannelPair(TAG)
+ inputChannels.first().dispose()
+ whenever(mockInputMonitor.inputChannel).thenReturn(inputChannels[1])
+
+ shellInit.init()
+
+ val displayChangingListenerCaptor =
+ argumentCaptor<DisplayChangeController.OnDisplayChangingListener>()
+ verify(mockDisplayController)
+ .addDisplayChangingController(displayChangingListenerCaptor.capture())
+ displayChangingListener = displayChangingListenerCaptor.firstValue
+ val insetsChangedCaptor =
+ argumentCaptor<DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener>()
+ verify(displayInsetsController)
+ .addGlobalInsetsChangedListener(insetsChangedCaptor.capture())
+ desktopModeOnInsetsChangedListener = insetsChangedCaptor.firstValue
+ val keyguardChangedCaptor =
+ argumentCaptor<DesktopModeKeyguardChangeListener>()
+ verify(mockShellController).addKeyguardChangeListener(keyguardChangedCaptor.capture())
+ desktopModeOnKeyguardChangedListener = keyguardChangedCaptor.firstValue
+ whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
+ whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+ (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+ }
+ }
+
+ @After
+ fun tearDown() {
+ mockitoSession.finishMocking()
+ }
+
+ protected fun createTask(
+ displayId: Int = DEFAULT_DISPLAY,
+ @WindowingMode windowingMode: Int,
+ activityType: Int = ACTIVITY_TYPE_STANDARD,
+ activityInfo: ActivityInfo = ActivityInfo(),
+ requestingImmersive: Boolean = false
+ ): RunningTaskInfo {
+ return TestRunningTaskInfoBuilder()
+ .setDisplayId(displayId)
+ .setWindowingMode(windowingMode)
+ .setVisible(true)
+ .setActivityType(activityType)
+ .build().apply {
+ topActivityInfo = activityInfo
+ isResizeable = true
+ requestedVisibleTypes = if (requestingImmersive) {
+ statusBars().inv()
+ } else {
+ statusBars()
+ }
+ }
+ }
+
+ protected fun setUpMockDecorationForTask(task: RunningTaskInfo): DesktopModeWindowDecoration {
+ val decoration = Mockito.mock(DesktopModeWindowDecoration::class.java)
+ whenever(
+ mockDesktopModeWindowDecorFactory.create(
+ any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(),
+ any(), any(), any(), any(), any(), any(), any(), any())
+ ).thenReturn(decoration)
+ decoration.mTaskInfo = task
+ whenever(decoration.user).thenReturn(mockUserHandle)
+ if (task.windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
+ whenever(mockSplitScreenController.isTaskInSplitScreen(task.taskId))
+ .thenReturn(true)
+ }
+ whenever(decoration.calculateValidDragArea()).thenReturn(Rect(0, 60, 2560, 1600))
+ return decoration
+ }
+
+
+ protected fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
+ desktopModeWindowDecorViewModel.onTaskOpening(
+ task,
+ leash,
+ StubTransaction(),
+ StubTransaction()
+ )
+ }
+
+ protected fun onTaskChanging(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
+ desktopModeWindowDecorViewModel.onTaskChanging(
+ task,
+ leash,
+ StubTransaction(),
+ StubTransaction()
+ )
+ }
+
+ protected fun RunningTaskInfo.setWindowingMode(@WindowingMode mode: Int) {
+ configuration.windowConfiguration.windowingMode = mode
+ }
+
+ protected fun RunningTaskInfo.setActivityType(type: Int) {
+ configuration.windowConfiguration.activityType = type
+ }
+
+ companion object {
+ const val TAG = "DesktopModeWindowDecorViewModelTestsBase"
+ val STABLE_INSETS = Rect(0, 100, 0, 0)
+ val INITIAL_BOUNDS = Rect(0, 0, 100, 100)
+ val STABLE_BOUNDS = Rect(0, 0, 1000, 1000)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index f653622d0460..e390fbbd751f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -265,8 +265,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
when(mMockHandleMenuFactory.create(any(), any(), anyInt(), any(), any(), any(),
- anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), any(),
- anyInt(), anyInt(), anyInt(), anyInt()))
+ anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
+ any(), anyInt(), anyInt(), anyInt(), anyInt()))
.thenReturn(mMockHandleMenu);
when(mMockMultiInstanceHelper.supportsMultiInstanceSplit(any())).thenReturn(false);
when(mMockAppHeaderViewHolderFactory.create(any(), any(), any(), any(), any(), any(), any(),
@@ -1577,7 +1577,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private void verifyHandleMenuCreated(@Nullable Uri uri) {
verify(mMockHandleMenuFactory).create(any(), any(), anyInt(), any(), any(),
any(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean(),
- argThat(intent -> (uri == null && intent == null) || intent.getData().equals(uri)),
+ anyBoolean(), argThat(intent ->
+ (uri == null && intent == null) || intent.getData().equals(uri)),
anyInt(), anyInt(), anyInt(), anyInt());
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index 7ec2cbf9460e..6babf817686a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -266,8 +266,8 @@ class HandleMenuTest : ShellTestCase() {
WindowManagerWrapper(mockWindowManager),
layoutId, appIcon, appName, splitScreenController, shouldShowWindowingPill = true,
shouldShowNewWindowButton = true, shouldShowManageWindowsButton = false,
- shouldShowChangeAspectRatioButton = false, isBrowserApp = false,
- null /* openInAppOrBrowserIntent */, captionWidth = HANDLE_WIDTH,
+ shouldShowChangeAspectRatioButton = false, shouldShowDesktopModeButton = true,
+ isBrowserApp = false, null /* openInAppOrBrowserIntent */, captionWidth = HANDLE_WIDTH,
captionHeight = 50,
captionX = captionX,
captionY = 0,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index d7b971de94ac..ad6fdf4d5c59 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -464,8 +464,10 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
// this test, so we verify the same log twice.
verify(desktopModeEventLogger, times(2)).logTaskResizingStarted(
ResizeTrigger.TILING_DIVIDER,
- motionEvent,
+ DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
task1,
+ BOUNDS.width() / 2,
+ BOUNDS.height(),
displayController,
)
@@ -475,10 +477,10 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
// this test, so we verify the same log twice.
verify(desktopModeEventLogger, times(2)).logTaskResizingEnded(
ResizeTrigger.TILING_DIVIDER,
- motionEvent,
+ DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
task1,
- BOUNDS.height(),
BOUNDS.width(),
+ BOUNDS.height(),
displayController,
)
}
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index fb58a69747b3..b72e066e64ae 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -84,6 +84,7 @@ public:
// this value is only valid after the GPU has been initialized and there is a valid graphics
// context or if you are using the HWUI_NULL_GPU
int maxTextureSize() const;
+ bool hasMaxTextureSize() const { return mMaxTextureSize > 0; }
sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
SkColorType getWideColorType() {
static std::once_flag kFlag;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 2c23864317a4..4801bd1038a3 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -186,7 +186,7 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
// If we are not a layer OR we cannot be rendered (eg, view was detached)
// we need to destroy any Layers we may have had previously
if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable()) ||
- CC_UNLIKELY(properties().getWidth() == 0) || CC_UNLIKELY(properties().getHeight() == 0) ||
+ CC_UNLIKELY(properties().getWidth() <= 0) || CC_UNLIKELY(properties().getHeight() <= 0) ||
CC_UNLIKELY(!properties().fitsOnLayer())) {
if (CC_UNLIKELY(hasLayer())) {
this->setLayerSurface(nullptr);
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index b1ad8b2eb1b9..4dc57004e401 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -545,7 +545,8 @@ public:
bool fitsOnLayer() const {
const DeviceInfo* deviceInfo = DeviceInfo::get();
return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize() &&
- mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
+ mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize() &&
+ mPrimitiveFields.mWidth > 0 && mPrimitiveFields.mHeight > 0;
}
bool promotedToLayer() const {
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index a7d855d7e8ca..8d3a5eb2b4af 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -619,7 +619,16 @@ namespace PaintGlue {
// restore the original settings.
font->setSkewX(saveSkewX);
font->setEmbolden(savefakeBold);
- if (paint->getFamilyVariant() == minikin::FamilyVariant::ELEGANT) {
+
+ // Don't use hard coded vertical metrics if target SDK is 35 or later.
+#ifdef __ANDROID__
+ uint32_t isTargetSdk35OrLater = android_get_application_target_sdk_version() >= 35;
+#else
+ uint32_t isTargetSdk35OrLater = true;
+#endif // __ANDROID
+ bool useHardCodedMetrics = !isTargetSdk35OrLater &&
+ (paint->getFamilyVariant() == minikin::FamilyVariant::ELEGANT);
+ if (useHardCodedMetrics) {
SkScalar size = font->getSize();
metrics->fTop = -size * kElegantTop / 2048;
metrics->fBottom = -size * kElegantBottom / 2048;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 8ec04304a808..b36b8be10779 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -418,6 +418,11 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy
RenderNode* target) {
mRenderThread.removeFrameCallback(this);
+ // Make sure we have a valid device info
+ if (!DeviceInfo::get()->hasMaxTextureSize()) {
+ (void)mRenderThread.requireGrContext();
+ }
+
// If the previous frame was dropped we don't need to hold onto it, so
// just keep using the previous frame's structure instead
const auto reason = wasSkipped(mCurrentFrameInfo);
diff --git a/libs/hwui/tests/unit/RenderPropertiesTests.cpp b/libs/hwui/tests/unit/RenderPropertiesTests.cpp
index 3e8e0576bf49..6ec042cf23b0 100644
--- a/libs/hwui/tests/unit/RenderPropertiesTests.cpp
+++ b/libs/hwui/tests/unit/RenderPropertiesTests.cpp
@@ -40,7 +40,11 @@ TEST(RenderProperties, layerValidity) {
props.setLeftTopRightBottom(0, 0, maxTextureSize + 1, maxTextureSize + 1);
ASSERT_FALSE(props.fitsOnLayer());
- // Too small, but still 'fits'. Not fitting is an error case, so don't report empty as such.
+ // Too small, we can't create a layer for a 0 width or height
props.setLeftTopRightBottom(0, 0, 100, 0);
- ASSERT_TRUE(props.fitsOnLayer());
+ ASSERT_FALSE(props.fitsOnLayer());
+
+ // Can't create a negative-sized layer
+ props.setLeftTopRightBottom(0, 0, -100, 300);
+ ASSERT_FALSE(props.fitsOnLayer());
}
diff --git a/libs/input/SpriteIcon.cpp b/libs/input/SpriteIcon.cpp
index 59e36e4b0d1e..2f8d4735c69b 100644
--- a/libs/input/SpriteIcon.cpp
+++ b/libs/input/SpriteIcon.cpp
@@ -25,6 +25,8 @@
namespace android {
bool SpriteIcon::draw(sp<Surface> surface) const {
+ LOG_ALWAYS_FATAL_IF(!isValid(), "Cannot draw SpriteIcon: not valid");
+
ANativeWindow_Buffer outBuffer;
status_t status = surface->lock(&outBuffer, NULL);
if (status) {
diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java
index f5913c763b82..4b3962e6dd74 100644
--- a/media/java/android/media/AudioDevicePort.java
+++ b/media/java/android/media/AudioDevicePort.java
@@ -22,6 +22,7 @@ import android.os.Build;
import com.android.aconfig.annotations.VisibleForTesting;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -68,14 +69,14 @@ public class AudioDevicePort extends AudioPort {
return new AudioDevicePort(
new AudioHandle(/* id= */ 0),
/* name= */ "testAudioDevicePort",
- /* profiles= */ null,
+ /* profiles= */ new ArrayList<>(),
/* gains= */ null,
/* type= */ AudioManager.DEVICE_OUT_SPEAKER,
/* address= */ "testAddress",
/* speakerLayoutChannelMask= */ speakerLayoutChannelMask,
/* encapsulationModes= */ null,
/* encapsulationMetadataTypes= */ null,
- /* descriptors= */ null);
+ /* descriptors= */ new ArrayList<>());
}
private final int mType;
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 96edd63a9b12..302969f58ba8 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -16,14 +16,15 @@
package android.media;
-import static android.media.Utils.intersectSortedDistinctRanges;
-import static android.media.Utils.sortDistinctRanges;
+import static android.media.audio.Flags.FLAG_IAMF_DEFINITIONS_API;
import static android.media.codec.Flags.FLAG_DYNAMIC_COLOR_ASPECTS;
import static android.media.codec.Flags.FLAG_HLG_EDITING;
import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE;
import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
import static android.media.codec.Flags.FLAG_APV_SUPPORT;
+import static android.media.Utils.intersectSortedDistinctRanges;
+import static android.media.Utils.sortDistinctRanges;
import static android.media.MediaCodec.GetFlag;
import android.annotation.FlaggedApi;
@@ -1876,6 +1877,8 @@ public final class MediaCodecInfo {
* Codecs with this security model is not included in
* {@link MediaCodecList#REGULAR_CODECS}, but included in
* {@link MediaCodecList#ALL_CODECS}.
+ *
+ * @hide
*/
@FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2;
@@ -4756,6 +4759,139 @@ public final class MediaCodecInfo {
@FlaggedApi(FLAG_APV_SUPPORT)
public static final int APVLevel71Band3 = 0x200008;
+ // IAMF profiles are defined as the combination of the (listed from LSB to MSB):
+ // - audio codec (2 bytes)
+ // - profile (1 byte, offset 16)
+ // - specification version (1 byte, offset 24)
+ private static final int IAMF_CODEC_OPUS = 0x1;
+ private static final int IAMF_CODEC_AAC = 0x1 << 1;
+ private static final int IAMF_CODEC_FLAC = 0x1 << 2;
+ private static final int IAMF_CODEC_PCM = 0x1 << 3;
+ private static final int IAMF_PROFILE_SIMPLE = 0x1 << 16;
+ private static final int IAMF_PROFILE_BASE = 0x1 << 17;
+ private static final int IAMF_PROFILE_BASE_ENHANCED = 0x1 << 18;
+ private static final int IAMF_v1 = 0x1 << 24;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in OPUS.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileSimpleOpus =
+ IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_OPUS;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in AAC.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileSimpleAac =
+ IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_AAC;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in FLAC.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileSimpleFlac =
+ IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_FLAC;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-simple">simple profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in PCM.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileSimplePcm =
+ IAMF_v1 + IAMF_PROFILE_SIMPLE + IAMF_CODEC_PCM;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in OPUS.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseOpus =
+ IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_OPUS;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in AAC.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseAac =
+ IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_AAC;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in FLAC.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseFlac =
+ IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_FLAC;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base">base profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in PCM.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBasePcm =
+ IAMF_v1 + IAMF_PROFILE_BASE + IAMF_CODEC_PCM;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in OPUS.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseEnhancedOpus =
+ IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_OPUS;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in AAC.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseEnhancedAac =
+ IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_AAC;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in FLAC.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseEnhancedFlac =
+ IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_FLAC;
+ /**
+ * IAMF profile using the
+ * <a href="https://aomediacodec.github.io/iamf/#profiles-base-enhanced">base-enhanced profile</a>
+ * with audio streams <a href="https://aomediacodec.github.io/iamf/#codec_id">encoded</a>
+ * in PCM.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final int IAMFProfileBaseEnhancedPcm =
+ IAMF_v1 + IAMF_PROFILE_BASE_ENHANCED + IAMF_CODEC_PCM;
+
/**
* The profile of the media content. Depending on the type of media this can be
* one of the profile values defined in this class.
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index bd65b2ecb76a..4f94c3e984db 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -16,6 +16,8 @@
package android.media;
+
+import static android.media.audio.Flags.FLAG_IAMF_DEFINITIONS_API;
import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
import static android.media.codec.Flags.FLAG_NUM_INPUT_SLOTS;
import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
@@ -262,6 +264,11 @@ public final class MediaFormat {
* MIME type for the IEC61937 audio stream encapsulation. This type isn't defined by IANA.
*/
public static final String MIMETYPE_AUDIO_IEC61937 = "audio/x-iec61937";
+ /**
+ * MIME type for IAMF audio stream
+ */
+ @FlaggedApi(FLAG_IAMF_DEFINITIONS_API)
+ public static final String MIMETYPE_AUDIO_IAMF = "audio/iamf";
/**
* MIME type for HEIF still image data encoded in HEVC.
@@ -1748,6 +1755,7 @@ public final class MediaFormat {
(1 << MediaCodecInfo.SECURITY_MODEL_MEMORY_SAFE);
/**
* Flag for {@link MediaCodecInfo#SECURITY_MODEL_TRUSTED_CONTENT_ONLY}.
+ * @hide
*/
@FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY =
@@ -1759,8 +1767,7 @@ public final class MediaFormat {
* The associated value is a flag of the following values:
* {@link FLAG_SECURITY_MODEL_SANDBOXED},
* {@link FLAG_SECURITY_MODEL_MEMORY_SAFE},
- * {@link FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. The default value is
- * {@link FLAG_SECURITY_MODEL_SANDBOXED}.
+ * The default value is {@link FLAG_SECURITY_MODEL_SANDBOXED}.
* <p>
* When passed to {@link MediaCodecList#findDecoderForFormat} or
* {@link MediaCodecList#findEncoderForFormat}, MediaCodecList filters
diff --git a/media/java/android/media/flags/projection.aconfig b/media/java/android/media/flags/projection.aconfig
index 1bb9a8e1d6d3..b4dee0cab24e 100644
--- a/media/java/android/media/flags/projection.aconfig
+++ b/media/java/android/media/flags/projection.aconfig
@@ -4,14 +4,6 @@ container: "system"
# Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
flag {
- name: "limit_manage_media_projection"
- namespace: "lse_desktop_experience"
- description: "Limit signature permission manage_media_projection to the SystemUI role"
- bug: "323008518"
- is_fixed_read_only: true
-}
-
-flag {
name: "media_projection_connected_display"
namespace: "virtual_devices"
description: "Enable recording connected display"
diff --git a/media/java/android/media/quality/AmbientBacklightEvent.java b/media/java/android/media/quality/AmbientBacklightEvent.java
index 273f21e01f86..b1483c685fdb 100644
--- a/media/java/android/media/quality/AmbientBacklightEvent.java
+++ b/media/java/android/media/quality/AmbientBacklightEvent.java
@@ -30,7 +30,6 @@ import java.util.Objects;
/**
* Ambient backlight event
- * @hide
*/
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
public final class AmbientBacklightEvent implements Parcelable {
diff --git a/media/java/android/media/quality/AmbientBacklightMetadata.java b/media/java/android/media/quality/AmbientBacklightMetadata.java
index 5cea10d2de43..ad19d0456ab0 100644
--- a/media/java/android/media/quality/AmbientBacklightMetadata.java
+++ b/media/java/android/media/quality/AmbientBacklightMetadata.java
@@ -32,7 +32,6 @@ import java.util.Arrays;
*
* <p>A metadata instance is sent from ambient backlight hardware in a {@link AmbientBacklightEvent}
* with {@link AmbientBacklightEvent#AMBIENT_BACKLIGHT_EVENT_METADATA}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
public final class AmbientBacklightMetadata implements Parcelable {
@@ -78,7 +77,6 @@ public final class AmbientBacklightMetadata implements Parcelable {
/**
* Gets package name of the metadata.
- * @hide
*/
@NonNull
public String getPackageName() {
@@ -130,11 +128,18 @@ public final class AmbientBacklightMetadata implements Parcelable {
}
/**
- * Gets color data of vertical color zones.
- * @hide
+ * Gets color data of all available color zones.
+ *
+ * <p>The format of the color data can be found at {@link #getColorFormat()}.
+ *
+ * @return an array of color data, in row by row (left-to-right then top-to-bottom) order of the
+ * color zones.
+ *
+ * @see #getHorizontalZonesNumber()
+ * @see #getVerticalZonesNumber()
*/
@NonNull
- public int[] getVerticalZonesColors() {
+ public int[] getZonesColors() {
return mZonesColors;
}
diff --git a/media/java/android/media/quality/AmbientBacklightSettings.java b/media/java/android/media/quality/AmbientBacklightSettings.java
index d904cf728da7..aa06341977fe 100644
--- a/media/java/android/media/quality/AmbientBacklightSettings.java
+++ b/media/java/android/media/quality/AmbientBacklightSettings.java
@@ -31,7 +31,6 @@ import java.lang.annotation.RetentionPolicy;
/**
* Settings to configure ambient backlight hardware.
- * @hide
*/
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
public final class AmbientBacklightSettings implements Parcelable {
@@ -60,16 +59,6 @@ public final class AmbientBacklightSettings implements Parcelable {
*/
public static final int SOURCE_AUDIO_VIDEO = 3;
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({COLOR_FORMAT_RGB888})
- public @interface ColorFormat {}
-
- /**
- * The color format is RGB888.
- * @hide
- */
- public static final int COLOR_FORMAT_RGB888 = 1;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -201,7 +190,6 @@ public final class AmbientBacklightSettings implements Parcelable {
*
* <p>Letter-box is a technique to keep the original aspect ratio when displayed on a screen
* with different aspect ratio. Black bars are added to the top and bottom.
- * @hide
*/
public boolean isLetterboxOmitted() {
return mIsLetterboxOmitted;
@@ -210,9 +198,8 @@ public final class AmbientBacklightSettings implements Parcelable {
/**
* Gets the detection threshold of the ambient light.
*
- * <p>If the color of a color zone is changed by the difference is smaller than the threshold,
+ * <p>If the color of a color zone is changed but the difference is smaller than the threshold,
* the change is ignored.
- * @hide
*/
public int getThreshold() {
return mThreshold;
diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/IMediaQualityManager.aidl
index aaedf21999f7..b7e75b7e6649 100644
--- a/media/java/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/IMediaQualityManager.aidl
@@ -21,6 +21,7 @@ import android.media.quality.IAmbientBacklightCallback;
import android.media.quality.IPictureProfileCallback;
import android.media.quality.ISoundProfileCallback;
import android.media.quality.ParamCapability;
+import android.media.quality.PictureProfileHandle;
import android.media.quality.PictureProfile;
import android.media.quality.SoundProfile;
@@ -38,6 +39,7 @@ interface IMediaQualityManager {
List<String> getPictureProfilePackageNames();
List<String> getPictureProfileAllowList();
void setPictureProfileAllowList(in List<String> packages);
+ PictureProfileHandle getPictureProfileHandle(in String id);
SoundProfile createSoundProfile(in SoundProfile pp);
void updateSoundProfile(in String id, in SoundProfile pp);
@@ -65,4 +67,5 @@ interface IMediaQualityManager {
void setAmbientBacklightSettings(in AmbientBacklightSettings settings);
void setAmbientBacklightEnabled(in boolean enabled);
+ boolean isAmbientBacklightEnabled();
}
diff --git a/media/java/android/media/quality/MediaQualityContract.java b/media/java/android/media/quality/MediaQualityContract.java
index 5fec86a81a53..3fac74b2a37d 100644
--- a/media/java/android/media/quality/MediaQualityContract.java
+++ b/media/java/android/media/quality/MediaQualityContract.java
@@ -79,12 +79,34 @@ public class MediaQualityContract {
}
/**
- * @hide
+ * Parameters for sound quality.
*/
- public static final class SoundQuality implements BaseParameters {
+ public static final class SoundQuality {
+ /**
+ * The audio volume balance.
+ *
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_BALANCE = "balance";
+
+ /**
+ * The bass.
+ *
+ * <p>Bass setting adjust the low sound frequencies.
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_BASS = "bass";
+
+ /**
+ * The treble.
+ *
+ * <p>Treble setting adjust the high sound frequencies.
+ * <p>Type: INTEGER
+ */
public static final String PARAMETER_TREBLE = "treble";
+
+ private SoundQuality() {
+ }
}
private MediaQualityContract() {
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 28fe9b6c8112..50055971d66d 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -271,6 +271,17 @@ public final class MediaQualityManager {
}
}
+ /**
+ * Gets picture profile handle by profile ID.
+ * @hide
+ */
+ public PictureProfileHandle getPictureProfileHandle(String id) {
+ try {
+ return mService.getPictureProfileHandle(id);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
/**
* Creates a picture profile and store it in the system.
@@ -312,7 +323,6 @@ public final class MediaQualityManager {
/**
* Registers a {@link SoundProfileCallback}.
- * @hide
*/
public void registerSoundProfileCallback(
@NonNull @CallbackExecutor Executor executor,
@@ -326,7 +336,6 @@ public final class MediaQualityManager {
/**
* Unregisters the existing {@link SoundProfileCallback}.
- * @hide
*/
public void unregisterSoundProfileCallback(@NonNull final SoundProfileCallback callback) {
Preconditions.checkNotNull(callback);
@@ -348,7 +357,6 @@ public final class MediaQualityManager {
*
* @return the corresponding sound profile if available; {@code null} if the name doesn't
* exist.
- * @hide
*/
@Nullable
public SoundProfile getSoundProfile(
@@ -362,9 +370,11 @@ public final class MediaQualityManager {
/**
- * @SystemApi gets profiles that available to the given package
+ * Gets profiles that available to the given package.
+ *
* @hide
*/
+ @SystemApi
@NonNull
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<SoundProfile> getSoundProfilesByPackage(@NonNull String packageName) {
@@ -376,8 +386,7 @@ public final class MediaQualityManager {
}
/**
- * Gets profiles that available to the caller package
- * @hide
+ * Gets profiles that available to the caller package.
*/
@NonNull
public List<SoundProfile> getAvailableSoundProfiles() {
@@ -389,11 +398,13 @@ public final class MediaQualityManager {
}
/**
- * @SystemApi Gets all package names whose sound profiles are available.
+ * Gets all package names whose sound profiles are available.
*
* @see #getSoundProfilesByPackage(String)
+ *
* @hide
*/
+ @SystemApi
@NonNull
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<String> getSoundProfilePackageNames() {
@@ -409,8 +420,7 @@ public final class MediaQualityManager {
* Creates a sound profile and store it in the system.
*
* <p>If the profile is created successfully,
- * {@link SoundProfileCallback#onSoundProfileAdded(long, SoundProfile)} is invoked.
- * @hide
+ * {@link SoundProfileCallback#onSoundProfileAdded(String, SoundProfile)} is invoked.
*/
public void createSoundProfile(@NonNull SoundProfile sp) {
try {
@@ -423,7 +433,6 @@ public final class MediaQualityManager {
/**
* Updates an existing sound profile and store it in the system.
- * @hide
*/
public void updateSoundProfile(@NonNull String profileId, @NonNull SoundProfile sp) {
try {
@@ -436,7 +445,6 @@ public final class MediaQualityManager {
/**
* Removes a sound profile from the system.
- * @hide
*/
public void removeSoundProfile(@NonNull String profileId) {
try {
@@ -497,6 +505,7 @@ public final class MediaQualityManager {
* @see #removeSoundProfile(String)
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
@NonNull
public List<String> getSoundProfileAllowList() {
@@ -511,6 +520,7 @@ public final class MediaQualityManager {
* Sets the allowlist of packages that can create and removed sound profiles
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setSoundProfileAllowList(@NonNull List<String> packageNames) {
try {
@@ -597,6 +607,7 @@ public final class MediaQualityManager {
* @param enabled {@code true} to enable, {@code false} to disable.
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setAutoSoundQualityEnabled(boolean enabled) {
try {
@@ -608,7 +619,6 @@ public final class MediaQualityManager {
/**
* Returns {@code true} if auto sound quality is enabled; {@code false} otherwise.
- * @hide
*/
public boolean isAutoSoundQualityEnabled() {
try {
@@ -620,7 +630,6 @@ public final class MediaQualityManager {
/**
* Registers a {@link AmbientBacklightCallback}.
- * @hide
*/
public void registerAmbientBacklightCallback(
@NonNull @CallbackExecutor Executor executor,
@@ -634,7 +643,6 @@ public final class MediaQualityManager {
/**
* Unregisters the existing {@link AmbientBacklightCallback}.
- * @hide
*/
public void unregisterAmbientBacklightCallback(
@NonNull final AmbientBacklightCallback callback) {
@@ -655,7 +663,6 @@ public final class MediaQualityManager {
* Set the ambient backlight settings.
*
* @param settings The settings to use for the backlight detector.
- * @hide
*/
public void setAmbientBacklightSettings(
@NonNull AmbientBacklightSettings settings) {
@@ -668,10 +675,20 @@ public final class MediaQualityManager {
}
/**
+ * Returns {@code true} if ambient backlight is enabled; {@code false} otherwise.
+ */
+ public boolean isAmbientBacklightEnabled() {
+ try {
+ return mService.isAmbientBacklightEnabled();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Enables or disables the ambient backlight detection.
*
* @param enabled {@code true} to enable, {@code false} to disable.
- * @hide
*/
public void setAmbientBacklightEnabled(boolean enabled) {
try {
@@ -882,7 +899,6 @@ public final class MediaQualityManager {
/**
* Callback used to monitor status of sound profiles.
- * @hide
*/
public abstract static class SoundProfileCallback {
/**
@@ -890,7 +906,6 @@ public final class MediaQualityManager {
*
* @param profileId the ID of the profile.
* @param profile the newly added profile.
- * @hide
*/
public void onSoundProfileAdded(
@NonNull String profileId, @NonNull SoundProfile profile) {
@@ -901,7 +916,6 @@ public final class MediaQualityManager {
*
* @param profileId the ID of the profile.
* @param profile the profile with updated info.
- * @hide
*/
public void onSoundProfileUpdated(
@NonNull String profileId, @NonNull SoundProfile profile) {
@@ -912,7 +926,6 @@ public final class MediaQualityManager {
*
* @param profileId the ID of the profile.
* @param profile the removed profile.
- * @hide
*/
public void onSoundProfileRemoved(
@NonNull String profileId, @NonNull SoundProfile profile) {
@@ -922,7 +935,6 @@ public final class MediaQualityManager {
* This is invoked when an issue has occurred.
*
* @param errorCode the error code
- * @hide
*/
public void onError(@SoundProfile.ErrorCode int errorCode) {
}
@@ -934,7 +946,6 @@ public final class MediaQualityManager {
* @param profileId the ID of the profile used by the media content. {@code null} if there
* is no associated profile
* @param updatedCaps the updated capabilities.
- * @hide
*/
public void onParamCapabilitiesChanged(
@Nullable String profileId, @NonNull List<ParamCapability> updatedCaps) {
@@ -943,7 +954,6 @@ public final class MediaQualityManager {
/**
* Callback used to monitor status of ambient backlight.
- * @hide
*/
public abstract static class AmbientBacklightCallback {
/**
diff --git a/media/java/android/media/quality/PictureProfileHandle.java b/media/java/android/media/quality/PictureProfileHandle.java
index 2b1cda4eb742..714fd36d664a 100644
--- a/media/java/android/media/quality/PictureProfileHandle.java
+++ b/media/java/android/media/quality/PictureProfileHandle.java
@@ -17,46 +17,58 @@
package android.media.quality;
import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
-// TODO(b/337330263): Expose as public API after API review
/**
- * A type-safe handle to a picture profile, which represents a collection of parameters used to
- * configure picture processing hardware to enhance the quality of graphic buffers.
+ * A type-safe handle to a picture profile used to apply picture processing to a SurfaceControl.
+ *
+ * A picture profile represents a collection of parameters used to configure picture processing
+ * to enhance the quality of graphic buffers.
+ *
* @hide
*/
-@FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+@SystemApi
+@FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
public final class PictureProfileHandle implements Parcelable {
+ public static final @NonNull PictureProfileHandle NONE = new PictureProfileHandle(0);
+
private final long mId;
- @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+ /** @hide */
public PictureProfileHandle(long id) {
mId = id;
}
- @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+ /** @hide */
+ @SystemApi
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
public long getId() {
return mId;
}
- @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+ /** @hide */
+ @SystemApi
@Override
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeLong(mId);
}
- @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
+ /** @hide */
+ @SystemApi
@Override
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
public int describeContents() {
return 0;
}
- @FlaggedApi(android.media.tv.flags.Flags.FLAG_MEDIA_QUALITY_FW)
- @NonNull
- public static final Creator<PictureProfileHandle> CREATOR =
+ /** @hide */
+ @SystemApi
+ @FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
+ public static final @NonNull Creator<PictureProfileHandle> CREATOR =
new Creator<PictureProfileHandle>() {
@Override
public PictureProfileHandle createFromParcel(Parcel in) {
diff --git a/media/java/android/media/quality/SoundProfile.java b/media/java/android/media/quality/SoundProfile.java
index de93afe4316f..c7fb4dd8486f 100644
--- a/media/java/android/media/quality/SoundProfile.java
+++ b/media/java/android/media/quality/SoundProfile.java
@@ -18,6 +18,7 @@ package android.media.quality;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
+import android.annotation.SystemApi;
import android.media.tv.TvInputInfo;
import android.media.tv.flags.Flags;
import android.os.Parcel;
@@ -33,10 +34,9 @@ import java.lang.annotation.RetentionPolicy;
/**
* Profile for sound quality.
- * @hide
*/
@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
-public class SoundProfile implements Parcelable {
+public final class SoundProfile implements Parcelable {
@Nullable
private String mId;
private final int mType;
@@ -113,7 +113,7 @@ public class SoundProfile implements Parcelable {
*/
public static final int ERROR_NOT_ALLOWLISTED = 4;
- protected SoundProfile(@NonNull Parcel in) {
+ private SoundProfile(@NonNull Parcel in) {
mId = in.readString();
mType = in.readInt();
mName = in.readString();
@@ -251,9 +251,8 @@ public class SoundProfile implements Parcelable {
/**
* A builder for {@link SoundProfile}
- * @hide
*/
- public static class Builder {
+ public static final class Builder {
@Nullable
private String mId;
private int mType = TYPE_APPLICATION;
@@ -300,6 +299,7 @@ public class SoundProfile implements Parcelable {
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
@NonNull
public Builder setProfileType(@ProfileType int value) {
@@ -314,6 +314,7 @@ public class SoundProfile implements Parcelable {
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
@NonNull
public Builder setInputId(@NonNull String value) {
@@ -328,6 +329,7 @@ public class SoundProfile implements Parcelable {
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
@NonNull
public Builder setPackageName(@NonNull String value) {
diff --git a/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl b/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl
deleted file mode 100644
index ff78aa4be39c..000000000000
--- a/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.IFavoriteNetworkListener;
-import android.os.Bundle;
-
-/**
- * Country: Norway
- * Broadcast Type: BROADCAST_TYPE_DVB_T
- * (Operator: RiksTV)
- *
- * @hide
- */
-interface IFavoriteNetwork {
- // Get the favorite network information,If there are no conflicts, the array of Bundle is empty.
- Bundle[] getFavoriteNetworks();
- // Select and set one of two or more favorite networks detected by the service scan.
- int setFavoriteNetwork(in Bundle favoriteNetworkSettings);
- // Set the listener to be invoked when two or more favorite networks are detected.
- int setListener(in IFavoriteNetworkListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl b/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl
deleted file mode 100644
index cdf6e23f4b47..000000000000
--- a/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-/**
- * @hide
- */
-interface IHDPlusInfo {
- // Specifying a HDPlusInfo and start a network scan.
- int setHDPlusInfo(String isBlindScanContinue, String isHDMode);
-}
diff --git a/media/java/android/media/tv/extension/scan/ILcnConflict.aidl b/media/java/android/media/tv/extension/scan/ILcnConflict.aidl
deleted file mode 100644
index 5dff39eb5920..000000000000
--- a/media/java/android/media/tv/extension/scan/ILcnConflict.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.ILcnConflictListener;
-import android.os.Bundle;
-
-/**
- * Country: Italy, France
- * Broadcast Type: BROADCAST_TYPE_DVB_T
- *
- * @hide
- */
-interface ILcnConflict {
- // Get the LCN conflict groups information, If there are no conflicts, the array of Bundle is empty.
- Bundle[] getLcnConflictGroups();
- // Resolve LCN conflicts caused by service scans.
- int resolveLcnConflict(in Bundle[] lcnConflictSettings);
- // Set the listener to be invoked the LCN conflict event.
- int setListener(in ILcnConflictListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl b/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl
deleted file mode 100644
index f9a9d345a575..000000000000
--- a/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.ILcnV2ChannelListListener;
-import android.os.Bundle;
-
-/**
- * Country: (NorDig etc.)
- * Broadcast Type: BROADCAST_TYPE_DVB_T, BROADCAST_TYPE_DVB_C
- *
- * @hide
- */
-interface ILcnV2ChannelList {
- // Get the LCN V2 channel list information. If there are no conflicts, the array of Bundle is empty.
- Bundle[] getLcnV2ChannelLists();
- // Select and set one of two or more LCN V2 channel list detected by the service scan.
- int setLcnV2ChannelList(in Bundle lcnV2ChannelListSettings);
- // Set the listener to be invoked when two or more LCN V2 channel list are detected.
- int setListener(in ILcnV2ChannelListListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl b/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl
deleted file mode 100644
index 770f8668983e..000000000000
--- a/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.IOperatorDetectionListener;
-import android.os.Bundle;
-
-/**
- * Country: Any
- * Broadcast Type: BROADCAST_TYPE_DVB_S
- * (Operator: M7)
- *
- * @hide
- */
-interface IOperatorDetection {
- // Set the operator selected info for scanning.
- int setOperatorDetection(in Bundle operatorSelected);
- // Set the listener to be invoked when one or more operator detection has been detected by
- // operator detection searches.
- int setListener(in IOperatorDetectionListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl b/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl
deleted file mode 100644
index fe755f873110..000000000000
--- a/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.IRegionChannelListListener;
-
-/**
- * @hide
- */
-interface IRegionChannelList {
- // Set the region channel list for scanning.
- int setRegionChannelList(String regionChannelList);
- // Set the listener to be invoked when one or more region channel list has been detected by
- // region channel list searches.
- int setListener(in IRegionChannelListListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl b/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl
deleted file mode 100644
index 06b0eb5537a2..000000000000
--- a/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-/**
- * @hide
- */
-oneway interface IRegionChannelListListener {
- void onDetectRegionChannelList(in String[] detectRegionChannelList);
-}
diff --git a/media/java/android/media/tv/extension/scan/IScanInterface.aidl b/media/java/android/media/tv/extension/scan/IScanInterface.aidl
deleted file mode 100644
index b44d1d243150..000000000000
--- a/media/java/android/media/tv/extension/scan/IScanInterface.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.IScanListener;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-interface IScanInterface {
- IBinder createSession(int broadcastType, String countryCode, String operator,
- in IScanListener listener);
- Bundle getParameters(int broadcastType, String countryCode, String operator,
- in Bundle params);
-}
diff --git a/media/java/android/media/tv/extension/scan/IScanListener.aidl b/media/java/android/media/tv/extension/scan/IScanListener.aidl
deleted file mode 100644
index 2c4807f97c58..000000000000
--- a/media/java/android/media/tv/extension/scan/IScanListener.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.os.Bundle;
-
-/**
- * @hide
- */
-oneway interface IScanListener {
- // notify events during scan.
- void onEvent(in Bundle eventArgs);
- // notify the scan progress.
- void onScanProgress(String scanProgress, in Bundle scanProgressInfo);
- // notify the scan completion.
- void onScanCompleted(int scanResult);
- // notify that the temporaily held channel list is stored.
- void onStoreCompleted(int storeResult);
-}
diff --git a/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl b/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl
deleted file mode 100644
index b8074fc4a9bd..000000000000
--- a/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-/**
- * For satellite search function.
- * @hide
- */
-interface IScanSatSearch {
- // Set currecnt LNB as customized LNB, default LNB is universal LNB
- int setCustomizedLnb(String customizedLnb);
-}
diff --git a/media/java/android/media/tv/extension/scan/IScanSession.aidl b/media/java/android/media/tv/extension/scan/IScanSession.aidl
deleted file mode 100644
index d42eca1342b5..000000000000
--- a/media/java/android/media/tv/extension/scan/IScanSession.aidl
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.os.Bundle;
-
-/**
- * @hide
- */
-interface IScanSession {
- // Start a service scan.
- int startScan(int broadcastType, String countryCode, String operator, in int[] frequency,
- String scanType, String languageCode);
- // Reset the scan information held in TIS.
- int resetScan();
- // Cancel scan.
- int cancelScan();
-
- // Get available interface for created ScanExtension interface.
- String[] getAvailableExtensionInterfaceNames();
- // Get extension interface for Scan.
- IBinder getExtensionInterface(String name);
-
- // Clear the results of the service scan from the service database.
- int clearServiceList(in Bundle optionalClearParams);
- // Store the results of the service scan from the service database.
- int storeServiceList();
- // Get a service information specified by the service information ID.
- Bundle getServiceInfo(String serviceInfoId, in String[] keys);
- // Get a service information ID list.
- String[] getServiceInfoIdList();
- // Get a list of service info by the filter.
- Bundle getServiceInfoList(in Bundle filterInfo, in String[] keys);
- // Update the service information.
- int updateServiceInfo(in Bundle serviceInfo);
- // Updates the service information for the specified service information ID in array list.
- int updateServiceInfoByList(in Bundle[] serviceInfo);
-
- /* DVBI specific functions */
- // Get all of the serviceLists, parsed from Local TV storage, Broadcast, USB file discovery.
- Bundle getServiceLists();
- // Users choose one serviceList from the serviceLists, and install the services.
- int setServiceList(int serviceListRecId);
- // Get all of the packageData, parsed from the selected serviceList XML.
- Bundle getPackageData();
- // Choose the package using package id and install the corresponding services.
- int setPackage(String packageId);
- // Get all of the countryRegionData, parsed from the selected serviceList XML.
- Bundle getCountryRegionData();
- // Choose the countryRegion using countryRegion id, and install the corresponding services.
- int setCountryRegion(String regionId);
- // Get all of the regionData, parsed from the selected serviceList XML.
- Bundle getRegionData();
- // Choose the region using the regionData id, and install the corresponding services.
- int setRegion(String regionId);
-
- // Get unique session token for the scan.
- String getSessionToken();
- // Release scan resource, the register listener will be released.
- int release();
-}
diff --git a/media/java/android/media/tv/extension/scan/ITargetRegion.aidl b/media/java/android/media/tv/extension/scan/ITargetRegion.aidl
deleted file mode 100644
index 417e12243b82..000000000000
--- a/media/java/android/media/tv/extension/scan/ITargetRegion.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.ITargetRegionListener;
-
-import android.os.Bundle;
-
-/**
- * Country: U.K.
- * Broadcast Type: BROADCAST_TYPE_DVB_T
- *
- * @hide
- */
-interface ITargetRegion {
- // Get the target regions information. If there are no conflicts, the array of Bundle is empty.
- Bundle[] getTargetRegions();
- // Select and set one of two or more target region detected by the service scan.
- int setTargetRegion(in Bundle targetRegionSettings);
- // Set the listener to be invoked when two or more regions are detected.
- int setListener(in ITargetRegionListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl b/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl
deleted file mode 100644
index 9d6aa8e8ea31..000000000000
--- a/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.os.Bundle;
-
-/**
- * @hide
- */
-oneway interface ITargetRegionListener {
- void onDetectTargetRegion(in Bundle detectTargetRegions);
-}
diff --git a/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl b/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl
deleted file mode 100644
index f25952c1cbdc..000000000000
--- a/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-import android.media.tv.extension.scan.ITkgsInfoListener;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-interface ITkgsInfo {
- int setPrefServiceList(String prefServiceList);
- int setTkgsInfoListener(in ITkgsInfoListener listener);
-}
diff --git a/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl b/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl
deleted file mode 100644
index e3dcf2d4c5ad..000000000000
--- a/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.extension.scan;
-
-/**
- * @hide
- */
-oneway interface ITkgsInfoListener {
- void onServiceList(in String[] serviceList);
- void onTableVersionUpdate(int tableVersion);
- void onUserMessage(String strMessage);
-}
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
index 898a8bf02edb..4de71235df8c 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -63,7 +63,7 @@ public class FrontendStatus {
FRONTEND_STATUS_TYPE_DVBT_CELL_IDS, FRONTEND_STATUS_TYPE_ATSC3_ALL_PLP_INFO,
FRONTEND_STATUS_TYPE_IPTV_CONTENT_URL, FRONTEND_STATUS_TYPE_IPTV_PACKETS_LOST,
FRONTEND_STATUS_TYPE_IPTV_PACKETS_RECEIVED, FRONTEND_STATUS_TYPE_IPTV_WORST_JITTER_MS,
- FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS, FRONTEND_STATUS_TYPE_STANDARD_EXT})
+ FRONTEND_STATUS_TYPE_IPTV_AVERAGE_JITTER_MS, FRONTEND_STATUS_TYPE_STANDARD_EXTENSION})
@Retention(RetentionPolicy.SOURCE)
public @interface FrontendStatusType {}
@@ -317,7 +317,7 @@ public class FrontendStatus {
* Standard extension.
*/
@FlaggedApi(Flags.FLAG_TUNER_W_APIS)
- public static final int FRONTEND_STATUS_TYPE_STANDARD_EXT =
+ public static final int FRONTEND_STATUS_TYPE_STANDARD_EXTENSION =
android.hardware.tv.tuner.FrontendStatusType.STANDARD_EXT;
/** @hide */
@@ -567,7 +567,7 @@ public class FrontendStatus {
private Long mIptvPacketsReceived;
private Integer mIptvWorstJitterMs;
private Integer mIptvAverageJitterMs;
- private StandardExt mStandardExt;
+ private StandardExtension mStandardExtension;
// Constructed and fields set by JNI code.
private FrontendStatus() {
@@ -1298,12 +1298,12 @@ public class FrontendStatus {
*/
@NonNull
@FlaggedApi(Flags.FLAG_TUNER_W_APIS)
- public StandardExt getStandardExt() {
+ public StandardExtension getStandardExtension() {
TunerVersionChecker.checkHigherOrEqualVersionTo(
- TunerVersionChecker.TUNER_VERSION_4_0, "StandardExt status");
- if (mStandardExt == null) {
- throw new IllegalStateException("StandardExt status is empty");
+ TunerVersionChecker.TUNER_VERSION_4_0, "StandardExtension status");
+ if (mStandardExtension == null) {
+ throw new IllegalStateException("StandardExtension status is empty");
}
- return mStandardExt;
+ return mStandardExtension;
}
}
diff --git a/media/java/android/media/tv/tuner/frontend/StandardExt.java b/media/java/android/media/tv/tuner/frontend/StandardExtension.java
index 490727278b46..8bff3dd99cdb 100644
--- a/media/java/android/media/tv/tuner/frontend/StandardExt.java
+++ b/media/java/android/media/tv/tuner/frontend/StandardExtension.java
@@ -29,16 +29,16 @@ import android.media.tv.flags.Flags;
*/
@SystemApi
@FlaggedApi(Flags.FLAG_TUNER_W_APIS)
-public final class StandardExt {
- private final int mDvbsStandardExt;
- private final int mDvbtStandardExt;
+public final class StandardExtension {
+ private final int mDvbsStandardExtension;
+ private final int mDvbtStandardExtension;
/**
* Private constructor called by JNI only.
*/
- private StandardExt(int dvbsStandardExt, int dvbtStandardExt) {
- mDvbsStandardExt = dvbsStandardExt;
- mDvbtStandardExt = dvbtStandardExt;
+ private StandardExtension(int dvbsStandardExtension, int dvbtStandardExtension) {
+ mDvbsStandardExtension = dvbsStandardExtension;
+ mDvbtStandardExtension = dvbtStandardExtension;
}
/**
@@ -50,11 +50,11 @@ public final class StandardExt {
* @see android.media.tv.tuner.frontend.DvbsFrontendSettings
*/
@DvbsFrontendSettings.Standard
- public int getDvbsStandardExt() {
- if (mDvbsStandardExt == FrontendDvbsStandard.UNDEFINED) {
+ public int getDvbsStandardExtension() {
+ if (mDvbsStandardExtension == FrontendDvbsStandard.UNDEFINED) {
throw new IllegalStateException("No DVB-S standard transition");
}
- return mDvbsStandardExt;
+ return mDvbsStandardExtension;
}
/**
@@ -66,10 +66,10 @@ public final class StandardExt {
* @see android.media.tv.tuner.frontend.DvbtFrontendSettings
*/
@DvbtFrontendSettings.Standard
- public int getDvbtStandardExt() {
- if (mDvbtStandardExt == FrontendDvbtStandard.UNDEFINED) {
+ public int getDvbtStandardExtension() {
+ if (mDvbtStandardExtension == FrontendDvbtStandard.UNDEFINED) {
throw new IllegalStateException("No DVB-T standard transition");
}
- return mDvbtStandardExt;
+ return mDvbtStandardExtension;
}
}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 80ca4f239a26..2fe069af638a 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -2940,10 +2940,10 @@ jobject JTuner::getFrontendStatus(jintArray types) {
break;
}
case FrontendStatus::Tag::standardExt: {
- jfieldID field = env->GetFieldID(clazz, "mStandardExt",
- "Landroid/media/tv/tuner/frontend/StandardExt;");
+ jfieldID field = env->GetFieldID(clazz, "mStandardExtension",
+ "Landroid/media/tv/tuner/frontend/StandardExtension;");
ScopedLocalRef standardExtClazz(env,
- env->FindClass("android/media/tv/tuner/frontend/StandardExt"));
+ env->FindClass("android/media/tv/tuner/frontend/StandardExtension"));
jmethodID initStandardExt = env->GetMethodID(standardExtClazz.get(), "<init>",
"(II)V");
diff --git a/native/android/dynamic_instrumentation_manager.cpp b/native/android/dynamic_instrumentation_manager.cpp
index d9bacb116f96..532213611cf1 100644
--- a/native/android/dynamic_instrumentation_manager.cpp
+++ b/native/android/dynamic_instrumentation_manager.cpp
@@ -65,7 +65,7 @@ ADynamicInstrumentationManager_TargetProcess* ADynamicInstrumentationManager_Tar
}
void ADynamicInstrumentationManager_TargetProcess_destroy(
- ADynamicInstrumentationManager_TargetProcess* instance) {
+ const ADynamicInstrumentationManager_TargetProcess* instance) {
delete instance;
}
@@ -96,7 +96,7 @@ ADynamicInstrumentationManager_MethodDescriptor_create(const char* fullyQualifie
}
void ADynamicInstrumentationManager_MethodDescriptor_destroy(
- ADynamicInstrumentationManager_MethodDescriptor* instance) {
+ const ADynamicInstrumentationManager_MethodDescriptor* instance) {
delete instance;
}
@@ -112,29 +112,29 @@ ADynamicInstrumentationManager_ExecutableMethodFileOffsets_create() {
}
const char* ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerPath(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
return instance->containerPath.c_str();
}
uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerOffset(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
return instance->containerOffset;
}
uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getMethodOffset(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
return instance->methodOffset;
}
void ADynamicInstrumentationManager_ExecutableMethodFileOffsets_destroy(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* instance) {
delete instance;
}
int32_t ADynamicInstrumentationManager_getExecutableMethodFileOffsets(
const ADynamicInstrumentationManager_TargetProcess* targetProcess,
const ADynamicInstrumentationManager_MethodDescriptor* methodDescriptor,
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets** out) {
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets** out) {
android::os::instrumentation::TargetProcess targetProcessParcel;
targetProcessParcel.uid = targetProcess->uid;
targetProcessParcel.pid = targetProcess->pid;
diff --git a/native/android/include_platform/android/dynamic_instrumentation_manager.h b/native/android/include_platform/android/dynamic_instrumentation_manager.h
index 6c46288954bf..ab9f37034a22 100644
--- a/native/android/include_platform/android/dynamic_instrumentation_manager.h
+++ b/native/android/include_platform/android/dynamic_instrumentation_manager.h
@@ -51,7 +51,7 @@ ADynamicInstrumentationManager_TargetProcess* _Nonnull
* @param instance returned from ADynamicInstrumentationManager_TargetProcess_create.
*/
void ADynamicInstrumentationManager_TargetProcess_destroy(
- ADynamicInstrumentationManager_TargetProcess* _Nonnull instance) __INTRODUCED_IN(36);
+ const ADynamicInstrumentationManager_TargetProcess* _Nonnull instance) __INTRODUCED_IN(36);
/**
* Initializes an ADynamicInstrumentationManager_MethodDescriptor. Caller must clean up when they
@@ -74,7 +74,8 @@ ADynamicInstrumentationManager_MethodDescriptor* _Nonnull
* @param instance returned from ADynamicInstrumentationManager_MethodDescriptor_create.
*/
void ADynamicInstrumentationManager_MethodDescriptor_destroy(
- ADynamicInstrumentationManager_MethodDescriptor* _Nonnull instance) __INTRODUCED_IN(36);
+ const ADynamicInstrumentationManager_MethodDescriptor* _Nonnull instance)
+ __INTRODUCED_IN(36);
/**
* Get the containerPath calculated by
@@ -83,7 +84,7 @@ void ADynamicInstrumentationManager_MethodDescriptor_destroy(
* @return The OS path of the containing file.
*/
const char* _Nullable ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerPath(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
__INTRODUCED_IN(36);
/**
* Get the containerOffset calculated by
@@ -92,7 +93,7 @@ const char* _Nullable ADynamicInstrumentationManager_ExecutableMethodFileOffsets
* @return The offset of the containing file within the process' memory.
*/
uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainerOffset(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
__INTRODUCED_IN(36);
/**
* Get the methodOffset calculated by ADynamicInstrumentationManager_getExecutableMethodFileOffsets.
@@ -100,7 +101,7 @@ uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getContainer
* @return The offset of the method within the containing file.
*/
uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getMethodOffset(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
__INTRODUCED_IN(36);
/**
* Clean up an ADynamicInstrumentationManager_ExecutableMethodFileOffsets.
@@ -108,7 +109,7 @@ uint64_t ADynamicInstrumentationManager_ExecutableMethodFileOffsets_getMethodOff
* @param instance returned from ADynamicInstrumentationManager_getExecutableMethodFileOffsets.
*/
void ADynamicInstrumentationManager_ExecutableMethodFileOffsets_destroy(
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull instance)
__INTRODUCED_IN(36);
/**
* Provides ART metadata about the described java method within the target process.
@@ -124,7 +125,7 @@ void ADynamicInstrumentationManager_ExecutableMethodFileOffsets_destroy(
int32_t ADynamicInstrumentationManager_getExecutableMethodFileOffsets(
const ADynamicInstrumentationManager_TargetProcess* _Nonnull targetProcess,
const ADynamicInstrumentationManager_MethodDescriptor* _Nonnull methodDescriptor,
- ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nonnull* _Nullable out)
+ const ADynamicInstrumentationManager_ExecutableMethodFileOffsets* _Nullable* _Nonnull out)
__INTRODUCED_IN(36);
__END_DECLS
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 2d1fbf9e7f66..9da7becba332 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -355,20 +355,29 @@ LIBANDROID {
APerformanceHint_getManager; # introduced=Tiramisu
APerformanceHint_createSession; # introduced=Tiramisu
APerformanceHint_getPreferredUpdateRateNanos; # introduced=Tiramisu
+ APerformanceHint_getMaxGraphicsPipelineThreadsCount; # introduced=36
APerformanceHint_updateTargetWorkDuration; # introduced=Tiramisu
APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu
APerformanceHint_closeSession; # introduced=Tiramisu
APerformanceHint_setThreads; # introduced=UpsideDownCake
APerformanceHint_setPreferPowerEfficiency; # introduced=VanillaIceCream
APerformanceHint_reportActualWorkDuration2; # introduced=VanillaIceCream
+ APerformanceHint_createSessionUsingConfig; # introduced=36
APerformanceHint_notifyWorkloadIncrease; # introduced=36
APerformanceHint_notifyWorkloadReset; # introduced=36
+ APerformanceHint_borrowSessionFromJava; # introduced=36
AWorkDuration_create; # introduced=VanillaIceCream
AWorkDuration_release; # introduced=VanillaIceCream
AWorkDuration_setWorkPeriodStartTimestampNanos; # introduced=VanillaIceCream
AWorkDuration_setActualTotalDurationNanos; # introduced=VanillaIceCream
AWorkDuration_setActualCpuDurationNanos; # introduced=VanillaIceCream
AWorkDuration_setActualGpuDurationNanos; # introduced=VanillaIceCream
+ ASessionCreationConfig_create; # introduced=36
+ ASessionCreationConfig_release; # introduced=36
+ ASessionCreationConfig_setTids; # introduced=36
+ ASessionCreationConfig_setTargetWorkDurationNanos; # introduced=36
+ ASessionCreationConfig_setPreferPowerEfficiency; # introduced=36
+ ASessionCreationConfig_setGraphicsPipeline; # introduced=36
local:
*;
};
@@ -378,11 +387,15 @@ LIBANDROID_PLATFORM {
AThermal_setIThermalServiceForTesting;
APerformanceHint_setIHintManagerForTesting;
APerformanceHint_sendHint;
+ APerformanceHint_setUseGraphicsPipelineForTesting;
APerformanceHint_getThreadIds;
APerformanceHint_createSessionInternal;
+ APerformanceHint_createSessionUsingConfigInternal;
APerformanceHint_setUseFMQForTesting;
APerformanceHint_getRateLimiterPropertiesForTesting;
APerformanceHint_setUseNewLoadHintBehaviorForTesting;
+ APerformanceHint_closeSessionFromJava;
+ APerformanceHint_createSessionFromJava;
extern "C++" {
ASurfaceControl_registerSurfaceStatsListener*;
ASurfaceControl_unregisterSurfaceStatsListener*;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index e2fa94dd39bb..c67e93c99e52 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -26,6 +26,7 @@
#include <aidl/android/hardware/power/WorkDurationFixedV1.h>
#include <aidl/android/os/IHintManager.h>
#include <aidl/android/os/IHintSession.h>
+#include <aidl/android/os/SessionCreationConfig.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
#include <android/binder_manager.h>
@@ -36,6 +37,7 @@
#include <cutils/trace.h>
#include <fmq/AidlMessageQueue.h>
#include <inttypes.h>
+#include <jni_wrappers.h>
#include <performance_hint_private.h>
#include <utils/SystemClock.h>
@@ -64,6 +66,13 @@ struct APerformanceHintSession;
constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
struct AWorkDuration : public hal::WorkDuration {};
+struct ASessionCreationConfig : public SessionCreationConfig {};
+
+bool kForceGraphicsPipeline = false;
+
+bool useGraphicsPipeline() {
+ return android::os::adpf_graphics_pipeline() || kForceGraphicsPipeline;
+}
// A pair of values that determine the behavior of the
// load hint rate limiter, to only allow "X hints every Y seconds"
@@ -137,10 +146,18 @@ public:
APerformanceHintSession* createSession(const int32_t* threadIds, size_t size,
int64_t initialTargetWorkDurationNanos,
- hal::SessionTag tag = hal::SessionTag::APP);
+ hal::SessionTag tag = hal::SessionTag::APP,
+ bool isJava = false);
+ APerformanceHintSession* getSessionFromJava(JNIEnv* _Nonnull env, jobject _Nonnull sessionObj);
+
+ APerformanceHintSession* createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
+ hal::SessionTag tag = hal::SessionTag::APP,
+ bool isJava = false);
int64_t getPreferredRateNanos() const;
+ int32_t getMaxGraphicsPipelineThreadsCount();
FMQWrapper& getFMQWrapper();
bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex);
+ void initJava(JNIEnv* _Nonnull env);
private:
// Necessary to create an empty binder object
@@ -158,16 +175,20 @@ private:
std::shared_ptr<IHintManager> mHintManager;
ndk::SpAIBinder mToken;
const int64_t mPreferredRateNanos;
+ std::optional<int32_t> mMaxGraphicsPipelineThreadsCount;
FMQWrapper mFMQWrapper;
double mHintBudget = kMaxLoadHintsPerInterval;
int64_t mLastBudgetReplenish = 0;
+ bool mJavaInitialized = false;
+ jclass mJavaSessionClazz;
+ jfieldID mJavaSessionNativePtr;
};
struct APerformanceHintSession {
public:
APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
std::shared_ptr<IHintSession> session, int64_t preferredRateNanos,
- int64_t targetDurationNanos,
+ int64_t targetDurationNanos, bool isJava,
std::optional<hal::SessionConfig> sessionConfig);
APerformanceHintSession() = delete;
~APerformanceHintSession();
@@ -181,6 +202,7 @@ public:
int getThreadIds(int32_t* const threadIds, size_t* size);
int setPreferPowerEfficiency(bool enabled);
int reportActualWorkDuration(AWorkDuration* workDuration);
+ bool isJava();
private:
friend struct APerformanceHintManager;
@@ -203,14 +225,18 @@ private:
std::vector<int64_t> mLastHintSentTimestamp GUARDED_BY(sHintMutex);
// Cached samples
std::vector<hal::WorkDuration> mActualWorkDurations GUARDED_BY(sHintMutex);
+ // Is this session backing an SDK wrapper object
+ const bool mIsJava;
std::string mSessionName;
static int64_t sIDCounter GUARDED_BY(sHintMutex);
// The most recent set of thread IDs
std::vector<int32_t> mLastThreadIDs GUARDED_BY(sHintMutex);
std::optional<hal::SessionConfig> mSessionConfig GUARDED_BY(sHintMutex);
// Tracing helpers
- void traceThreads(std::vector<int32_t>& tids) REQUIRES(sHintMutex);
+ void traceThreads(const std::vector<int32_t>& tids) REQUIRES(sHintMutex);
void tracePowerEfficient(bool powerEfficient);
+ void traceGraphicsPipeline(bool graphicsPipeline);
+ void traceModes(const std::vector<hal::SessionMode>& modesToEnable);
void traceActualDuration(int64_t actualDuration);
void traceBatchSize(size_t batchSize);
void traceTargetDuration(int64_t targetDuration);
@@ -299,28 +325,58 @@ bool APerformanceHintManager::canSendLoadHints(std::vector<hal::SessionHint>& hi
APerformanceHintSession* APerformanceHintManager::createSession(
const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos,
- hal::SessionTag tag) {
- std::vector<int32_t> tids(threadIds, threadIds + size);
- std::shared_ptr<IHintSession> session;
+ hal::SessionTag tag, bool isJava) {
ndk::ScopedAStatus ret;
hal::SessionConfig sessionConfig{.id = -1};
- ret = mHintManager->createHintSessionWithConfig(mToken, tids, initialTargetWorkDurationNanos,
- tag, &sessionConfig, &session);
+
+ SessionCreationConfig creationConfig{
+ .tids = std::vector<int32_t>(threadIds, threadIds + size),
+ .targetWorkDurationNanos = initialTargetWorkDurationNanos,
+ };
+
+ return APerformanceHintManager::createSessionUsingConfig(static_cast<ASessionCreationConfig*>(
+ &creationConfig),
+ tag, isJava);
+}
+
+APerformanceHintSession* APerformanceHintManager::createSessionUsingConfig(
+ ASessionCreationConfig* sessionCreationConfig, hal::SessionTag tag, bool isJava) {
+ std::shared_ptr<IHintSession> session;
+ hal::SessionConfig sessionConfig{.id = -1};
+ ndk::ScopedAStatus ret;
+
+ ret = mHintManager->createHintSessionWithConfig(mToken, tag,
+ *static_cast<SessionCreationConfig*>(
+ sessionCreationConfig),
+ &sessionConfig, &session);
if (!ret.isOk() || !session) {
ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
return nullptr;
}
auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
- initialTargetWorkDurationNanos,
+ sessionCreationConfig->targetWorkDurationNanos, isJava,
sessionConfig.id == -1
? std::nullopt
: std::make_optional<hal::SessionConfig>(
std::move(sessionConfig)));
std::scoped_lock lock(sHintMutex);
- out->traceThreads(tids);
- out->traceTargetDuration(initialTargetWorkDurationNanos);
- out->tracePowerEfficient(false);
+ out->traceThreads(sessionCreationConfig->tids);
+ out->traceTargetDuration(sessionCreationConfig->targetWorkDurationNanos);
+ out->traceModes(sessionCreationConfig->modesToEnable);
+
+ return out;
+}
+
+APerformanceHintSession* APerformanceHintManager::getSessionFromJava(JNIEnv* env,
+ jobject sessionObj) {
+ initJava(env);
+ LOG_ALWAYS_FATAL_IF(!env->IsInstanceOf(sessionObj, mJavaSessionClazz),
+ "Wrong java type passed to APerformanceHint_getSessionFromJava");
+ APerformanceHintSession* out = reinterpret_cast<APerformanceHintSession*>(
+ env->GetLongField(sessionObj, mJavaSessionNativePtr));
+ LOG_ALWAYS_FATAL_IF(out == nullptr, "Java-wrapped native hint session is nullptr");
+ LOG_ALWAYS_FATAL_IF(!out->isJava(), "Unmanaged native hint session returned from Java SDK");
return out;
}
@@ -328,17 +384,44 @@ int64_t APerformanceHintManager::getPreferredRateNanos() const {
return mPreferredRateNanos;
}
+int32_t APerformanceHintManager::getMaxGraphicsPipelineThreadsCount() {
+ if (!mMaxGraphicsPipelineThreadsCount.has_value()) {
+ int32_t threadsCount = -1;
+ ndk::ScopedAStatus ret = mHintManager->getMaxGraphicsPipelineThreadsCount(&threadsCount);
+ if (!ret.isOk()) {
+ ALOGE("%s: PerformanceHint cannot get max graphics pipeline threads count. %s",
+ __FUNCTION__, ret.getMessage());
+ return -1;
+ }
+ if (threadsCount <= 0) {
+ threadsCount = -1;
+ }
+ mMaxGraphicsPipelineThreadsCount.emplace(threadsCount);
+ }
+ return mMaxGraphicsPipelineThreadsCount.value();
+}
+
FMQWrapper& APerformanceHintManager::getFMQWrapper() {
return mFMQWrapper;
}
+void APerformanceHintManager::initJava(JNIEnv* _Nonnull env) {
+ if (mJavaInitialized) {
+ return;
+ }
+ jclass sessionClazz = FindClassOrDie(env, "android/os/PerformanceHintManager$Session");
+ mJavaSessionClazz = MakeGlobalRefOrDie(env, sessionClazz);
+ mJavaSessionNativePtr = GetFieldIDOrDie(env, mJavaSessionClazz, "mNativeSessionPtr", "J");
+ mJavaInitialized = true;
+}
+
// ===================================== APerformanceHintSession implementation
constexpr int kNumEnums = enum_size<hal::SessionHint>();
APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
std::shared_ptr<IHintSession> session,
int64_t preferredRateNanos,
- int64_t targetDurationNanos,
+ int64_t targetDurationNanos, bool isJava,
std::optional<hal::SessionConfig> sessionConfig)
: mHintManager(hintManager),
mHintSession(std::move(session)),
@@ -347,6 +430,7 @@ APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> h
mFirstTargetMetTimestamp(0),
mLastTargetMetTimestamp(0),
mLastHintSentTimestamp(std::vector<int64_t>(kNumEnums, 0)),
+ mIsJava(isJava),
mSessionConfig(sessionConfig) {
if (sessionConfig->id > INT32_MAX) {
ALOGE("Session ID too large, must fit 32-bit integer");
@@ -401,6 +485,10 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano
return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration));
}
+bool APerformanceHintSession::isJava() {
+ return mIsJava;
+}
+
int APerformanceHintSession::sendHints(std::vector<hal::SessionHint>& hints, int64_t now,
const char*) {
std::scoped_lock lock(sHintMutex);
@@ -749,7 +837,7 @@ bool FMQWrapper::setMode(std::optional<hal::SessionConfig>& config, hal::Session
// ===================================== Tracing helpers
-void APerformanceHintSession::traceThreads(std::vector<int32_t>& tids) {
+void APerformanceHintSession::traceThreads(const std::vector<int32_t>& tids) {
std::set<int32_t> tidSet{tids.begin(), tids.end()};
// Disable old TID tracing
@@ -775,6 +863,28 @@ void APerformanceHintSession::tracePowerEfficient(bool powerEfficient) {
ATrace_setCounter((mSessionName + " power efficiency mode").c_str(), powerEfficient);
}
+void APerformanceHintSession::traceGraphicsPipeline(bool graphicsPipeline) {
+ ATrace_setCounter((mSessionName + " graphics pipeline mode").c_str(), graphicsPipeline);
+}
+
+void APerformanceHintSession::traceModes(const std::vector<hal::SessionMode>& modesToEnable) {
+ // Iterate through all modes to trace, set to enable for all modes in modesToEnable,
+ // and set to disable for those are not.
+ for (hal::SessionMode mode :
+ {hal::SessionMode::POWER_EFFICIENCY, hal::SessionMode::GRAPHICS_PIPELINE}) {
+ bool isEnabled =
+ find(modesToEnable.begin(), modesToEnable.end(), mode) != modesToEnable.end();
+ switch (mode) {
+ case hal::SessionMode::POWER_EFFICIENCY:
+ tracePowerEfficient(isEnabled);
+ break;
+ case hal::SessionMode::GRAPHICS_PIPELINE:
+ traceGraphicsPipeline(isEnabled);
+ break;
+ }
+ }
+}
+
void APerformanceHintSession::traceActualDuration(int64_t actualDuration) {
ATrace_setCounter((mSessionName + " actual duration").c_str(), actualDuration);
}
@@ -817,6 +927,22 @@ APerformanceHintSession* APerformanceHint_createSession(APerformanceHintManager*
return manager->createSession(threadIds, size, initialTargetWorkDurationNanos);
}
+APerformanceHintSession* APerformanceHint_createSessionUsingConfig(
+ APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig) {
+ VALIDATE_PTR(manager);
+ VALIDATE_PTR(sessionCreationConfig);
+ return manager->createSessionUsingConfig(sessionCreationConfig);
+}
+
+APerformanceHintSession* APerformanceHint_createSessionUsingConfigInternal(
+ APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig,
+ SessionTag tag) {
+ VALIDATE_PTR(manager);
+ VALIDATE_PTR(sessionCreationConfig);
+ return manager->createSessionUsingConfig(sessionCreationConfig,
+ static_cast<hal::SessionTag>(tag));
+}
+
APerformanceHintSession* APerformanceHint_createSessionInternal(
APerformanceHintManager* manager, const int32_t* threadIds, size_t size,
int64_t initialTargetWorkDurationNanos, SessionTag tag) {
@@ -826,11 +952,32 @@ APerformanceHintSession* APerformanceHint_createSessionInternal(
static_cast<hal::SessionTag>(tag));
}
+APerformanceHintSession* APerformanceHint_createSessionFromJava(
+ APerformanceHintManager* manager, const int32_t* threadIds, size_t size,
+ int64_t initialTargetWorkDurationNanos) {
+ VALIDATE_PTR(manager)
+ VALIDATE_PTR(threadIds)
+ return manager->createSession(threadIds, size, initialTargetWorkDurationNanos,
+ hal::SessionTag::APP, true);
+}
+
+APerformanceHintSession* APerformanceHint_borrowSessionFromJava(JNIEnv* env,
+ jobject sessionObj) {
+ VALIDATE_PTR(env)
+ VALIDATE_PTR(sessionObj)
+ return APerformanceHintManager::getInstance()->getSessionFromJava(env, sessionObj);
+}
+
int64_t APerformanceHint_getPreferredUpdateRateNanos(APerformanceHintManager* manager) {
VALIDATE_PTR(manager)
return manager->getPreferredRateNanos();
}
+int APerformanceHint_getMaxGraphicsPipelineThreadsCount(APerformanceHintManager* manager) {
+ VALIDATE_PTR(manager);
+ return manager->getMaxGraphicsPipelineThreadsCount();
+}
+
int APerformanceHint_updateTargetWorkDuration(APerformanceHintSession* session,
int64_t targetDurationNanos) {
VALIDATE_PTR(session)
@@ -846,6 +993,16 @@ int APerformanceHint_reportActualWorkDuration(APerformanceHintSession* session,
void APerformanceHint_closeSession(APerformanceHintSession* session) {
VALIDATE_PTR(session)
+ if (session->isJava()) {
+ LOG_ALWAYS_FATAL("%s: Java-owned PerformanceHintSession cannot be closed in native",
+ __FUNCTION__);
+ return;
+ }
+ delete session;
+}
+
+void APerformanceHint_closeSessionFromJava(APerformanceHintSession* session) {
+ VALIDATE_PTR(session)
delete session;
}
@@ -954,6 +1111,81 @@ void APerformanceHint_setUseFMQForTesting(bool enabled) {
gForceFMQEnabled = enabled;
}
+ASessionCreationConfig* ASessionCreationConfig_create() {
+ return new ASessionCreationConfig();
+}
+
+void ASessionCreationConfig_release(ASessionCreationConfig* config) {
+ VALIDATE_PTR(config)
+
+ delete config;
+}
+
+int ASessionCreationConfig_setTids(ASessionCreationConfig* config, const pid_t* tids, size_t size) {
+ VALIDATE_PTR(config)
+ VALIDATE_PTR(tids)
+
+ if (!useGraphicsPipeline()) {
+ return ENOTSUP;
+ }
+
+ if (size <= 0) {
+ LOG_ALWAYS_FATAL_IF(size <= 0,
+ "%s: Invalid value. Thread id list size should be greater than zero.",
+ __FUNCTION__);
+ return EINVAL;
+ }
+ config->tids = std::vector<int32_t>(tids, tids + size);
+ return 0;
+}
+
+int ASessionCreationConfig_setTargetWorkDurationNanos(ASessionCreationConfig* config,
+ int64_t targetWorkDurationNanos) {
+ VALIDATE_PTR(config)
+ VALIDATE_INT(targetWorkDurationNanos, >= 0)
+
+ if (!useGraphicsPipeline()) {
+ return ENOTSUP;
+ }
+
+ config->targetWorkDurationNanos = targetWorkDurationNanos;
+ return 0;
+}
+
+int ASessionCreationConfig_setPreferPowerEfficiency(ASessionCreationConfig* config, bool enabled) {
+ VALIDATE_PTR(config)
+
+ if (!useGraphicsPipeline()) {
+ return ENOTSUP;
+ }
+
+ if (enabled) {
+ config->modesToEnable.push_back(hal::SessionMode::POWER_EFFICIENCY);
+ } else {
+ std::erase(config->modesToEnable, hal::SessionMode::POWER_EFFICIENCY);
+ }
+ return 0;
+}
+
+int ASessionCreationConfig_setGraphicsPipeline(ASessionCreationConfig* config, bool enabled) {
+ VALIDATE_PTR(config)
+
+ if (!useGraphicsPipeline()) {
+ return ENOTSUP;
+ }
+
+ if (enabled) {
+ config->modesToEnable.push_back(hal::SessionMode::GRAPHICS_PIPELINE);
+ } else {
+ std::erase(config->modesToEnable, hal::SessionMode::GRAPHICS_PIPELINE);
+ }
+ return 0;
+}
+
+void APerformanceHint_setUseGraphicsPipelineForTesting(bool enabled) {
+ kForceGraphicsPipeline = enabled;
+}
+
void APerformanceHint_getRateLimiterPropertiesForTesting(int32_t* maxLoadHintsPerInterval,
int64_t* loadHintInterval) {
*maxLoadHintsPerInterval = kMaxLoadHintsPerInterval;
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index f707a0e9b0b2..c5fb80840b84 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -18,9 +18,11 @@
#include <aidl/android/hardware/power/ChannelConfig.h>
#include <aidl/android/hardware/power/SessionConfig.h>
+#include <aidl/android/hardware/power/SessionMode.h>
#include <aidl/android/hardware/power/SessionTag.h>
#include <aidl/android/hardware/power/WorkDuration.h>
#include <aidl/android/os/IHintManager.h>
+#include <aidl/android/os/SessionCreationConfig.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <android/performance_hint.h>
@@ -36,6 +38,7 @@ using namespace std::chrono_literals;
namespace hal = aidl::android::hardware::power;
using aidl::android::os::IHintManager;
using aidl::android::os::IHintSession;
+using aidl::android::os::SessionCreationConfig;
using ndk::ScopedAStatus;
using ndk::SpAIBinder;
using HalChannelMessageContents = hal::ChannelMessage::ChannelMessageContents;
@@ -49,11 +52,13 @@ using namespace testing;
class MockIHintManager : public IHintManager {
public:
MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
- (const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
- hal::SessionTag tag, hal::SessionConfig* config,
+ (const SpAIBinder& token, hal::SessionTag tag,
+ const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
std::shared_ptr<IHintSession>* _aidl_return),
(override));
MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
+ MOCK_METHOD(ScopedAStatus, getMaxGraphicsPipelineThreadsCount, (int32_t* _aidl_return),
+ (override));
MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
(const std::shared_ptr<IHintSession>& hintSession,
const ::std::vector<int32_t>& tids),
@@ -105,6 +110,7 @@ public:
APerformanceHint_getRateLimiterPropertiesForTesting(&mMaxLoadHintsPerInterval,
&mLoadHintInterval);
APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
+ APerformanceHint_setUseGraphicsPipelineForTesting(true);
APerformanceHint_setUseNewLoadHintBehaviorForTesting(true);
}
@@ -118,21 +124,22 @@ public:
APerformanceHint_setUseFMQForTesting(mUsingFMQ);
ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
.WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
+ ON_CALL(*mMockIHintManager, getMaxGraphicsPipelineThreadsCount(_))
+ .WillByDefault(DoAll(SetArgPointee<0>(5), [] { return ScopedAStatus::ok(); }));
return APerformanceHint_getManager();
}
APerformanceHintSession* createSession(APerformanceHintManager* manager,
int64_t targetDuration = 56789L, bool isHwui = false) {
mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
- int64_t sessionId = 123;
+ const int64_t sessionId = 123;
std::vector<int32_t> tids;
tids.push_back(1);
tids.push_back(2);
- ON_CALL(*mMockIHintManager,
- createHintSessionWithConfig(_, Eq(tids), Eq(targetDuration), _, _, _))
- .WillByDefault(DoAll(SetArgPointee<4>(hal::SessionConfig({.id = sessionId})),
- SetArgPointee<5>(std::shared_ptr<IHintSession>(mMockSession)),
+ ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
+ .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
+ SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
[] { return ScopedAStatus::ok(); }));
ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
@@ -157,6 +164,43 @@ public:
return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
}
+ APerformanceHintSession* createSessionUsingConfig(APerformanceHintManager* manager,
+ SessionCreationConfig config,
+ bool isHwui = false) {
+ mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
+ const int64_t sessionId = 123;
+
+ ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
+ .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
+ SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
+ [] { return ScopedAStatus::ok(); }));
+
+ ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+ ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
+ ON_CALL(*mMockSession, setMode(_, true)).WillByDefault([] { return ScopedAStatus::ok(); });
+ ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
+ ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+ ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+ ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+
+ if (isHwui) {
+ return APerformanceHint_createSessionUsingConfigInternal(
+ manager, reinterpret_cast<ASessionCreationConfig*>(&config), SessionTag::HWUI);
+ }
+
+ return APerformanceHint_createSessionUsingConfig(manager,
+ reinterpret_cast<ASessionCreationConfig*>(
+ &config));
+ }
+
void setFMQEnabled(bool enabled) {
mUsingFMQ = enabled;
if (enabled) {
@@ -272,16 +316,26 @@ TEST_F(PerformanceHintTest, TestSession) {
}
TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
- EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _, _)).Times(1);
+ EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
APerformanceHintManager* manager = createManager();
APerformanceHintSession* session = createSession(manager);
ASSERT_TRUE(session);
APerformanceHint_closeSession(session);
}
+TEST_F(PerformanceHintTest, TestSessionCreationUsingConfig) {
+ EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
+ SessionCreationConfig config{.tids = std::vector<int32_t>(1, 2),
+ .targetWorkDurationNanos = 5678,
+ .modesToEnable = std::vector<hal::SessionMode>(0)};
+ APerformanceHintManager* manager = createManager();
+ APerformanceHintSession* session = createSessionUsingConfig(manager, config);
+ ASSERT_TRUE(session);
+ APerformanceHint_closeSession(session);
+}
+
TEST_F(PerformanceHintTest, TestHwuiSessionCreation) {
- EXPECT_CALL(*mMockIHintManager,
- createHintSessionWithConfig(_, _, _, hal::SessionTag::HWUI, _, _))
+ EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, hal::SessionTag::HWUI, _, _, _))
.Times(1);
APerformanceHintManager* manager = createManager();
APerformanceHintSession* session = createSession(manager, 56789L, true);
@@ -447,3 +501,16 @@ TEST_F(PerformanceHintTest, TestReportActualUsingFMQ) {
reinterpret_cast<AWorkDuration*>(&duration));
expectToReadFromFmq<HalChannelMessageContents::Tag::workDuration>(durationExpected);
}
+
+TEST_F(PerformanceHintTest, TestASessionCreationConfig) {
+ ASessionCreationConfig* config = ASessionCreationConfig_create();
+ ASSERT_NE(config, nullptr);
+
+ const int32_t testTids[2] = {1, 2};
+ const size_t size = 2;
+ EXPECT_EQ(ASessionCreationConfig_setTids(config, testTids, size), 0);
+ EXPECT_EQ(ASessionCreationConfig_setTargetWorkDurationNanos(config, 20), 0);
+ EXPECT_EQ(ASessionCreationConfig_setPreferPowerEfficiency(config, true), 0);
+ EXPECT_EQ(ASessionCreationConfig_setGraphicsPipeline(config, true), 0);
+ ASessionCreationConfig_release(config);
+}
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 008120429c40..7ae2eafaf461 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -81,11 +81,14 @@ package android.nfc {
method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported();
method public boolean isSecureNfcEnabled();
method public boolean isSecureNfcSupported();
+ method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAllowed();
+ method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAppPreferenceSupported();
method @FlaggedApi("android.nfc.enable_nfc_charging") public boolean isWlcEnabled();
method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity);
method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int);
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setObserveModeEnabled(boolean);
field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
+ field @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE = "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
@@ -225,6 +228,10 @@ package android.nfc.cardemulation {
field public static final String CATEGORY_PAYMENT = "payment";
field public static final String EXTRA_CATEGORY = "category";
field public static final String EXTRA_SERVICE_COMPONENT = "component";
+ field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; // 0x3
+ field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
@@ -236,8 +243,13 @@ package android.nfc.cardemulation {
}
@FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener {
+ method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public default void onNfcStateChanged(int);
method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean);
method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public default void onRemoteFieldChanged(boolean);
}
public abstract class HostApduService extends android.app.Service {
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index f587660cae5b..15814edcd86a 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -11,7 +11,6 @@ package android.nfc {
method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerNfcVendorNciCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
method @FlaggedApi("android.nfc.enable_nfc_charging") public void registerWlcStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.WlcStateListener);
@@ -97,6 +96,7 @@ package android.nfc {
method public void onDisableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onDisableStarted();
method public void onEeListenActivated(boolean);
+ method public void onEeUpdated();
method public void onEnableFinished(int);
method public void onEnableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onEnableStarted();
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index 31514a09adad..a08b55fe86b8 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -121,4 +121,5 @@ interface INfcAdapter
List<Entry> getRoutingTableEntryList();
void indicateDataMigration(boolean inProgress, String pkg);
int commitRouting();
+ boolean isTagIntentAllowed(in String pkg, in int Userid);
}
diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventListener.aidl
index 5162c26ac536..774d8f875192 100644
--- a/nfc/java/android/nfc/INfcEventListener.aidl
+++ b/nfc/java/android/nfc/INfcEventListener.aidl
@@ -8,4 +8,9 @@ import android.nfc.ComponentNameAndUser;
oneway interface INfcEventListener {
void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser);
void onObserveModeStateChanged(boolean isEnabled);
+ void onAidConflictOccurred(in String aid);
+ void onAidNotRouted(in String aid);
+ void onNfcStateChanged(in int nfcState);
+ void onRemoteFieldChanged(boolean isDetected);
+ void onInternalErrorReported(in int errorType);
} \ No newline at end of file
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index 1a21c0bae413..e5eac0b4d6fd 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -48,6 +48,7 @@ interface INfcOemExtensionCallback {
void onRfFieldActivated(boolean isActivated);
void onRfDiscoveryStarted(boolean isDiscoveryStarted);
void onEeListenActivated(boolean isActivated);
+ void onEeUpdated();
void onGetOemAppSearchIntent(in List<String> firstPackage, in ResultReceiver intentConsumer);
void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent);
void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category);
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index c5d8191b22e6..056844f38f3c 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -49,6 +49,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import java.io.IOException;
@@ -2505,22 +2506,22 @@ public final class NfcAdapter {
}
/**
- * Checks if the device supports Tag application preference.
+ * Checks if the device supports Tag Intent App Preference functionality.
+ *
+ * When supported, {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+ * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if
+ * {@link isTagIntentAllowed} returns {@code false}.
*
* @return {@code true} if the device supports Tag application preference, {@code false}
* otherwise
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable
- *
- * @hide
*/
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
public boolean isTagIntentAppPreferenceSupported() {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
return callServiceReturn(() -> sService.isTagIntentAppPreferenceSupported(), false);
-
}
/**
@@ -2895,4 +2896,42 @@ public final class NfcAdapter {
}
return mNfcOemExtension;
}
+
+ /**
+ * Activity action: Bring up the settings page that allows the user to enable or disable tag
+ * intent reception for apps.
+ *
+ * <p>This will direct user to the settings page shows a list that asks users whether
+ * they want to allow or disallow the package to start an activity when a tag is discovered.
+ *
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
+ public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE =
+ "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
+
+ /**
+ * Checks whether the user has disabled the calling app from receiving NFC tag intents.
+ *
+ * <p>This method checks whether the caller package name is either not present in the user
+ * disabled list or is explicitly allowed by the user.
+ *
+ * @return {@code true} if an app is either not present in the list or is added to the list
+ * with the flag set to {@code true}. Otherwise, it returns {@code false}.
+ * It also returns {@code true} if {@link isTagIntentAppPreferenceSupported} returns
+ * {@code false}.
+ *
+ * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
+ public boolean isTagIntentAllowed() {
+ if (!sHasNfcFeature) {
+ throw new UnsupportedOperationException();
+ }
+ if (!isTagIntentAppPreferenceSupported()) {
+ return true;
+ }
+ return callServiceReturn(() -> sService.isTagIntentAllowed(mContext.getPackageName(),
+ UserHandle.myUserId()), false);
+ }
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 326ca6449c53..9ed678fe6014 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -367,6 +367,15 @@ public final class NfcOemExtension {
void onEeListenActivated(boolean isActivated);
/**
+ * Notifies that some NFCEE (NFC Execution Environment) has been updated.
+ *
+ * <p> This indicates that some applet has been installed/updated/removed in
+ * one of the NFCEE's.
+ * </p>
+ */
+ void onEeUpdated();
+
+ /**
* Gets the intent to find the OEM package in the OEM App market. If the consumer returns
* {@code null} or a timeout occurs, the intent from the first available package will be
* used instead.
@@ -830,6 +839,12 @@ public final class NfcOemExtension {
}
@Override
+ public void onEeUpdated() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null, (Object input) -> cb.onEeUpdated(), ex));
+ }
+
+ @Override
public void onStateUpdated(int state) throws RemoteException {
mCallbackMap.forEach((cb, ex) ->
handleVoidCallback(state, cb::onStateUpdated, ex));
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 891752475824..24ff7ab9c2b6 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -947,7 +947,7 @@ public final class CardEmulation {
*
* @param service The ComponentName of the service
* @param status true to enable, false to disable
- * @return true if preferred service is successfully set or unset, otherwise return false.
+ * @return status code defined in {@link SetServiceEnabledStatusCode}
*
* @hide
*/
@@ -1144,6 +1144,40 @@ public final class CardEmulation {
};
}
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0;
+
+ /**
+ * This error is reported when the NFC command watchdog restarts the NFC stack.
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1;
+
+ /**
+ * This error is reported when the NFC controller does not respond or there's an NCI transport
+ * error.
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2;
+
+ /**
+ * This error is reported when the NFC stack times out while waiting for a response to a command
+ * sent to the NFC hardware.
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ @IntDef(prefix = "NFC_INTERNAL_ERROR_", value = {
+ NFC_INTERNAL_ERROR_UNKNOWN,
+ NFC_INTERNAL_ERROR_NFC_CRASH_RESTART,
+ NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR,
+ NFC_INTERNAL_ERROR_COMMAND_TIMEOUT,
+ })
+ public @interface NfcInternalErrorType {}
+
/** Listener for preferred service state changes. */
@FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
public interface NfcEventListener {
@@ -1166,6 +1200,57 @@ public final class CardEmulation {
*/
@FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
default void onObserveModeStateChanged(boolean isEnabled) {}
+
+ /**
+ * This method is called when an AID conflict is detected during an NFC transaction. This
+ * can happen when multiple services are registered for the same AID.
+ *
+ * @param aid The AID that is in conflict
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ default void onAidConflictOccurred(@NonNull String aid) {}
+
+ /**
+ * This method is called when an AID is not routed to any service during an NFC
+ * transaction. This can happen when no service is registered for the given AID.
+ *
+ * @param aid the AID that was not routed
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ default void onAidNotRouted(@NonNull String aid) {}
+
+ /**
+ * This method is called when the NFC state changes.
+ *
+ * @see NfcAdapter#getAdapterState()
+ *
+ * @param state The new NFC state
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ default void onNfcStateChanged(@NfcAdapter.AdapterState int state) {}
+ /**
+ * This method is called when the NFC controller is in card emulation mode and an NFC
+ * reader's field is either detected or lost.
+ *
+ * @param isDetected true if an NFC reader is detected, false if it is lost
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ default void onRemoteFieldChanged(boolean isDetected) {}
+
+ /**
+ * This method is called when an internal error is reported by the NFC stack.
+ *
+ * No action is required in response to these events as the NFC stack will automatically
+ * attempt to recover. These errors are reported for informational purposes only.
+ *
+ * Note that these errors can be reported when performing various internal NFC operations
+ * (such as during device shutdown) and cannot always be explicitly correlated with NFC
+ * transaction failures.
+ *
+ * @param errorType The type of the internal error
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ default void onInternalErrorReported(@NfcInternalErrorType int errorType) {}
}
private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>();
@@ -1185,25 +1270,61 @@ public final class CardEmulation {
mContext.getPackageName(),
componentNameAndUser.getComponentName()
.getPackageName());
- synchronized (mNfcEventListeners) {
- mNfcEventListeners.forEach(
- (listener, executor) -> {
- executor.execute(
- () -> listener.onPreferredServiceChanged(isPreferred));
- });
- }
+ callListeners(listener -> listener.onPreferredServiceChanged(isPreferred));
}
public void onObserveModeStateChanged(boolean isEnabled) {
if (!android.nfc.Flags.nfcEventListener()) {
return;
}
+ callListeners(listener -> listener.onObserveModeStateChanged(isEnabled));
+ }
+
+ public void onAidConflictOccurred(String aid) {
+ if (!android.nfc.Flags.nfcEventListener()) {
+ return;
+ }
+ callListeners(listener -> listener.onAidConflictOccurred(aid));
+ }
+
+ public void onAidNotRouted(String aid) {
+ if (!android.nfc.Flags.nfcEventListener()) {
+ return;
+ }
+ callListeners(listener -> listener.onAidNotRouted(aid));
+ }
+
+ public void onNfcStateChanged(int state) {
+ if (!android.nfc.Flags.nfcEventListener()) {
+ return;
+ }
+ callListeners(listener -> listener.onNfcStateChanged(state));
+ }
+
+ public void onRemoteFieldChanged(boolean isDetected) {
+ if (!android.nfc.Flags.nfcEventListener()) {
+ return;
+ }
+ callListeners(listener -> listener.onRemoteFieldChanged(isDetected));
+ }
+
+ public void onInternalErrorReported(@NfcInternalErrorType int errorType) {
+ if (!android.nfc.Flags.nfcEventListener()) {
+ return;
+ }
+ callListeners(listener -> listener.onInternalErrorReported(errorType));
+ }
+
+ interface ListenerCall {
+ void invoke(NfcEventListener listener);
+ }
+
+ private void callListeners(ListenerCall listenerCall) {
synchronized (mNfcEventListeners) {
mNfcEventListeners.forEach(
- (listener, executor) -> {
- executor.execute(
- () -> listener.onObserveModeStateChanged(isEnabled));
- });
+ (listener, executor) -> {
+ executor.execute(() -> listenerCall.invoke(listener));
+ });
}
}
};
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 8a37aa28cf9d..ee287aba709f 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -181,3 +181,11 @@ flag {
description: "Enable set service enabled for category other"
bug: "338157113"
}
+
+flag {
+ name: "nfc_check_tag_intent_preference"
+ is_exported: true
+ namespace: "nfc"
+ description: "App can check its tag intent preference status"
+ bug: "335916336"
+}
diff --git a/packages/BackupRestoreConfirmation/Android.bp b/packages/BackupRestoreConfirmation/Android.bp
index ad3f4c12dfb1..a7d16a1cb0d0 100644
--- a/packages/BackupRestoreConfirmation/Android.bp
+++ b/packages/BackupRestoreConfirmation/Android.bp
@@ -27,6 +27,7 @@ android_app {
name: "BackupRestoreConfirmation",
defaults: ["platform_app_defaults"],
srcs: ["src/**/*.java"],
+ static_libs: ["androidx.core_core"],
platform_apis: true,
certificate: "platform",
privileged: true,
diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml
index 44aa1b1b8747..fee46576d588 100644
--- a/packages/BackupRestoreConfirmation/AndroidManifest.xml
+++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml
@@ -27,7 +27,6 @@
android:permission="android.permission.CONFIRM_FULL_BACKUP" >
<activity android:name=".BackupRestoreConfirmation"
- android:theme="@style/OptOutEdgeToEdgeEnforcement"
android:title=""
android:windowSoftInputMode="stateAlwaysHidden"
android:excludeFromRecents="true"
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
index 6504435fada3..16e4706e6bb0 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
@@ -24,6 +24,7 @@
android:orientation="vertical" >
<ScrollView
+ android:id="@+id/scroll_view"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="match_parent"
@@ -84,11 +85,11 @@
android:layout_width="match_parent" />
<!-- button bar -->
- <LinearLayout android:orientation="horizontal"
- style="?android:attr/buttonBarStyle"
+ <LinearLayout android:id="@+id/button_bar"
+ android:orientation="horizontal"
+ style="?android:attr/buttonBarStyle"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="bottom">
+ android:layout_width="match_parent">
<Button android:id="@+id/button_deny"
style="?android:attr/buttonBarButtonStyle"
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
index 2ee74fe4519b..55efe4a44c19 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
@@ -23,11 +23,13 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <ScrollView
+ <ScrollView
+ android:id="@+id/scroll_view"
android:padding="16dp"
android:layout_height="0dp"
android:layout_weight="1"
- android:layout_width="match_parent">
+ android:layout_width="match_parent"
+ android:clipToPadding="false" >
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content"
@@ -82,8 +84,9 @@
android:layout_width="match_parent" />
<!-- button bar -->
- <LinearLayout android:orientation="horizontal"
- style="?android:attr/buttonBarStyle"
+ <LinearLayout android:id="@+id/button_bar"
+ android:orientation="horizontal"
+ style="?android:attr/buttonBarStyle"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="bottom">
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index 3c790f0e24ee..bc06bdbd29af 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -31,10 +31,17 @@ import android.text.Editable;
import android.text.TextWatcher;
import android.util.Slog;
import android.view.View;
+import android.view.ViewGroup.MarginLayoutParams;
import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
/**
* Confirm with the user that a requested full backup/restore operation is legitimate.
* Any attempt to perform a full backup/restore will launch this UI and wait for a
@@ -208,6 +215,8 @@ public class BackupRestoreConfirmation extends Activity {
setTitle(titleId);
setContentView(layoutId);
+ handleInsets();
+
// Same resource IDs for each layout variant (backup / restore)
mStatusView = findViewById(R.id.package_name);
mAllowButton = findViewById(R.id.button_allow);
@@ -254,6 +263,31 @@ public class BackupRestoreConfirmation extends Activity {
}
}
+ // Handle insets so that UI components are not covered by navigation and status bars
+ private void handleInsets() {
+ LinearLayout buttonBar = findViewById(R.id.button_bar);
+ ViewCompat.setOnApplyWindowInsetsListener(buttonBar, (v, windowInsets) -> {
+ Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
+ MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
+ mlp.leftMargin = insets.left;
+ mlp.bottomMargin = insets.bottom;
+ mlp.rightMargin = insets.right;
+ v.setLayoutParams(mlp);
+ return WindowInsetsCompat.CONSUMED;
+ });
+
+ ScrollView scrollView = findViewById(R.id.scroll_view);
+ ViewCompat.setOnApplyWindowInsetsListener(scrollView, (v, windowInsets) -> {
+ Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
+ MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
+ mlp.leftMargin = insets.left;
+ mlp.topMargin = insets.top;
+ mlp.rightMargin = insets.right;
+ v.setLayoutParams(mlp);
+ return WindowInsetsCompat.CONSUMED;
+ });
+ }
+
private void monitorEncryptionPassword() {
mAllowButton.setEnabled(false);
mEncPassword.addTextChangedListener(new TextWatcher() {
diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml
index 53a27332a2d1..fe746f24912b 100644
--- a/packages/CarrierDefaultApp/res/values-ar/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml
@@ -8,7 +8,7 @@
<string name="portal_notification_detail" msgid="2295729385924660881">"‏النقر للانتقال إلى موقع %s الإلكتروني"</string>
<string name="no_data_notification_detail" msgid="3112125343857014825">"‏يُرجى الاتصال بمقدم الخدمة %s"</string>
<string name="no_mobile_data_connection_title" msgid="7449525772416200578">"لا يوجد اتصال بيانات الجوال"</string>
- <string name="no_mobile_data_connection" msgid="544980465184147010">"‏إضافة بيانات أو خطة تجوال خلال %%s"</string>
+ <string name="no_mobile_data_connection" msgid="544980465184147010">"‏إضافة بيانات أو خطة تجوال خلال %s"</string>
<string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"حالة بيانات الجوّال"</string>
<string name="action_bar_label" msgid="4290345990334377177">"تسجيل الدخول إلى شبكة الجوّال"</string>
<string name="ssl_error_warning" msgid="3127935140338254180">"الشبكة التي تحاول الانضمام إليها بها مشاكل أمنية."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index 20d1300d89a9..d6225c2dd16e 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -16,7 +16,7 @@
<string name="ssl_error_continue" msgid="1138548463994095584">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"پرفارمینس بوسٹ"</string>
<string name="performance_boost_notification_title" msgid="3126203390685781861">"‏آپ کے کیریئر سے 5G کے اختیارات"</string>
- <string name="performance_boost_notification_detail" msgid="216569851036236346">"‏اپنی ایپ کے تجربے کے اختیارات دیکھنے کے لیے %%s کی ویب سائٹ ملاحظہ کریں"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"‏اپنی ایپ کے تجربے کے اختیارات دیکھنے کے لیے %s کی ویب سائٹ ملاحظہ کریں"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ابھی نہیں"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"نظم کریں"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"پرفارمینس بوسٹ خریدیں۔"</string>
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
index fbf51fd7cca7..fc482174414a 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -218,7 +218,7 @@ public class PackageWatchdog {
@GuardedBy("sPackageWatchdogLock")
private static PackageWatchdog sPackageWatchdog;
- private final Object mLock = new Object();
+ private static final Object sLock = new Object();
// System server context
private final Context mContext;
// Handler to run short running tasks
@@ -228,7 +228,7 @@ public class PackageWatchdog {
// Contains (observer-name -> observer-handle) that have ever been registered from
// previous boots. Observers with all packages expired are periodically pruned.
// It is saved to disk on system shutdown and repouplated on startup so it survives reboots.
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private final ArrayMap<String, ObserverInternal> mAllObservers = new ArrayMap<>();
// File containing the XML data of monitored packages /data/system/package-watchdog.xml
private final AtomicFile mPolicyFile;
@@ -244,26 +244,26 @@ public class PackageWatchdog {
private final Set<String> mPackagesExemptFromImpactLevelThreshold = new ArraySet<>();
// The set of packages that have been synced with the ExplicitHealthCheckController
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private boolean mIsPackagesReady;
// Flag to control whether explicit health checks are supported or not
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private boolean mIsHealthCheckEnabled = DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED;
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private int mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_DURATION_MS;
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private int mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
// SystemClock#uptimeMillis when we last executed #syncState
// 0 if no prune is scheduled.
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private long mUptimeAtLastStateSync;
// If true, sync explicit health check packages with the ExplicitHealthCheckController.
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private boolean mSyncRequired = false;
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private long mLastMitigation = -1000000;
@FunctionalInterface
@@ -303,7 +303,11 @@ public class PackageWatchdog {
sPackageWatchdog = this;
}
- /** Creates or gets singleton instance of PackageWatchdog. */
+ /**
+ * Creates or gets singleton instance of PackageWatchdog.
+ *
+ * @param context The system server context.
+ */
public static @NonNull PackageWatchdog getInstance(@NonNull Context context) {
synchronized (sPackageWatchdogLock) {
if (sPackageWatchdog == null) {
@@ -319,7 +323,7 @@ public class PackageWatchdog {
* @hide
*/
public void onPackagesReady() {
- synchronized (mLock) {
+ synchronized (sLock) {
mIsPackagesReady = true;
mHealthCheckController.setCallbacks(packageName -> onHealthCheckPassed(packageName),
packages -> onSupportedPackages(packages),
@@ -338,7 +342,7 @@ public class PackageWatchdog {
* @hide
*/
public void registerHealthObserver(PackageHealthObserver observer) {
- synchronized (mLock) {
+ synchronized (sLock) {
ObserverInternal internalObserver = mAllObservers.get(observer.getUniqueIdentifier());
if (internalObserver != null) {
internalObserver.registeredObserver = observer;
@@ -405,7 +409,7 @@ public class PackageWatchdog {
mLongTaskHandler.post(() -> {
syncState("observing new packages");
- synchronized (mLock) {
+ synchronized (sLock) {
ObserverInternal oldObserver = mAllObservers.get(observer.getUniqueIdentifier());
if (oldObserver == null) {
Slog.d(TAG, observer.getUniqueIdentifier() + " started monitoring health "
@@ -437,7 +441,7 @@ public class PackageWatchdog {
*/
public void unregisterHealthObserver(PackageHealthObserver observer) {
mLongTaskHandler.post(() -> {
- synchronized (mLock) {
+ synchronized (sLock) {
mAllObservers.remove(observer.getUniqueIdentifier());
}
syncState("unregistering observer: " + observer.getUniqueIdentifier());
@@ -458,7 +462,7 @@ public class PackageWatchdog {
Slog.w(TAG, "Could not resolve a list of failing packages");
return;
}
- synchronized (mLock) {
+ synchronized (sLock) {
final long now = mSystemClock.uptimeMillis();
if (Flags.recoverabilityDetection()) {
if (now >= mLastMitigation
@@ -469,7 +473,7 @@ public class PackageWatchdog {
}
}
mLongTaskHandler.post(() -> {
- synchronized (mLock) {
+ synchronized (sLock) {
if (mAllObservers.isEmpty()) {
return;
}
@@ -569,7 +573,7 @@ public class PackageWatchdog {
int currentObserverImpact,
int mitigationCount) {
if (allowMitigations(currentObserverImpact, versionedPackage)) {
- synchronized (mLock) {
+ synchronized (sLock) {
mLastMitigation = mSystemClock.uptimeMillis();
}
currentObserverToNotify.onExecuteHealthCheckMitigation(versionedPackage, failureReason,
@@ -599,7 +603,7 @@ public class PackageWatchdog {
*/
@SuppressWarnings("GuardedBy")
public void noteBoot() {
- synchronized (mLock) {
+ synchronized (sLock) {
// if boot count has reached threshold, start mitigation.
// We wait until threshold number of restarts only for the first time. Perform
// mitigations for every restart after that.
@@ -652,7 +656,7 @@ public class PackageWatchdog {
// This currently adds about 7ms extra to shutdown thread
/** @hide Writes the package information to file during shutdown. */
public void writeNow() {
- synchronized (mLock) {
+ synchronized (sLock) {
// Must only run synchronous tasks as this runs on the ShutdownThread and no other
// thread is guaranteed to run during shutdown.
if (!mAllObservers.isEmpty()) {
@@ -671,7 +675,7 @@ public class PackageWatchdog {
* passed and the health check service is stopped.
*/
private void setExplicitHealthCheckEnabled(boolean enabled) {
- synchronized (mLock) {
+ synchronized (sLock) {
mIsHealthCheckEnabled = enabled;
mHealthCheckController.setEnabled(enabled);
mSyncRequired = true;
@@ -841,7 +845,10 @@ public class PackageWatchdog {
/**
* Returns {@code true} if this observer wishes to observe the given package, {@code false}
- * otherwise
+ * otherwise.
+ * Any failing package can be passed on to the observer. Currently the packages that have
+ * ANRs and perform {@link android.service.watchdog.ExplicitHealthCheckService} are being
+ * passed to observers in these API.
*
* <p> A persistent observer may choose to start observing certain failing packages, even if
* it has not explicitly asked to watch the package with {@link #startObservingHealth}.
@@ -853,14 +860,14 @@ public class PackageWatchdog {
@VisibleForTesting
long getTriggerFailureCount() {
- synchronized (mLock) {
+ synchronized (sLock) {
return mTriggerFailureCount;
}
}
@VisibleForTesting
long getTriggerFailureDurationMs() {
- synchronized (mLock) {
+ synchronized (sLock) {
return mTriggerFailureDurationMs;
}
}
@@ -881,7 +888,7 @@ public class PackageWatchdog {
*/
private void syncRequests() {
boolean syncRequired = false;
- synchronized (mLock) {
+ synchronized (sLock) {
if (mIsPackagesReady) {
Set<String> packages = getPackagesPendingHealthChecksLocked();
if (mSyncRequired || !packages.equals(mRequestedHealthCheckPackages)
@@ -918,7 +925,7 @@ public class PackageWatchdog {
Slog.i(TAG, "Health check passed for package: " + packageName);
boolean isStateChanged = false;
- synchronized (mLock) {
+ synchronized (sLock) {
for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) {
ObserverInternal observer = mAllObservers.valueAt(observerIdx);
MonitoredPackage monitoredPackage = observer.getMonitoredPackage(packageName);
@@ -946,7 +953,7 @@ public class PackageWatchdog {
supportedPackageTimeouts.put(info.getPackageName(), info.getHealthCheckTimeoutMillis());
}
- synchronized (mLock) {
+ synchronized (sLock) {
Slog.d(TAG, "Received supported packages " + supportedPackages);
Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
while (oit.hasNext()) {
@@ -977,13 +984,13 @@ public class PackageWatchdog {
}
private void onSyncRequestNotified() {
- synchronized (mLock) {
+ synchronized (sLock) {
mSyncRequired = true;
syncRequestsAsync();
}
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private Set<String> getPackagesPendingHealthChecksLocked() {
Set<String> packages = new ArraySet<>();
Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
@@ -1009,7 +1016,7 @@ public class PackageWatchdog {
* health check service and schedules the next state sync.
*/
private void syncState(String reason) {
- synchronized (mLock) {
+ synchronized (sLock) {
Slog.i(TAG, "Syncing state, reason: " + reason);
pruneObserversLocked();
@@ -1025,7 +1032,7 @@ public class PackageWatchdog {
syncState("scheduled");
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private void scheduleNextSyncStateLocked() {
long durationMs = getNextStateSyncMillisLocked();
mShortTaskHandler.removeCallbacks(mSyncStateWithScheduledReason);
@@ -1043,7 +1050,7 @@ public class PackageWatchdog {
*
* @returns Long#MAX_VALUE if there are no observed packages.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private long getNextStateSyncMillisLocked() {
long shortestDurationMs = Long.MAX_VALUE;
for (int oIndex = 0; oIndex < mAllObservers.size(); oIndex++) {
@@ -1064,7 +1071,7 @@ public class PackageWatchdog {
* Removes {@code elapsedMs} milliseconds from all durations on monitored packages
* and updates other internal state.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private void pruneObserversLocked() {
long elapsedMs = mUptimeAtLastStateSync == 0
? 0 : mSystemClock.uptimeMillis() - mUptimeAtLastStateSync;
@@ -1092,7 +1099,7 @@ public class PackageWatchdog {
private void onHealthCheckFailed(ObserverInternal observer,
Set<MonitoredPackage> failedPackages) {
mLongTaskHandler.post(() -> {
- synchronized (mLock) {
+ synchronized (sLock) {
PackageHealthObserver registeredObserver = observer.registeredObserver;
if (registeredObserver != null) {
Iterator<MonitoredPackage> it = failedPackages.iterator();
@@ -1201,7 +1208,7 @@ public class PackageWatchdog {
*/
@VisibleForTesting
void updateConfigs() {
- synchronized (mLock) {
+ synchronized (sLock) {
mTriggerFailureCount = DeviceConfig.getInt(
DeviceConfig.NAMESPACE_ROLLBACK,
PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
@@ -1230,7 +1237,7 @@ public class PackageWatchdog {
*/
private boolean saveToFile() {
Slog.i(TAG, "Saving observer state to file");
- synchronized (mLock) {
+ synchronized (sLock) {
FileOutputStream stream;
try {
stream = mPolicyFile.startWrite();
@@ -1297,20 +1304,37 @@ public class PackageWatchdog {
/** Dump status of every observer in mAllObservers. */
public void dump(@NonNull PrintWriter pw) {
- if (Flags.synchronousRebootInRescueParty() && RescueParty.isRecoveryTriggeredReboot()) {
+ if (Flags.synchronousRebootInRescueParty() && isRecoveryTriggeredReboot()) {
dumpInternal(pw);
} else {
- synchronized (mLock) {
+ synchronized (sLock) {
dumpInternal(pw);
}
}
}
+ /**
+ * Check if we're currently attempting to reboot during mitigation. This method must return
+ * true if triggered reboot early during a boot loop, since the device will not be fully booted
+ * at this time.
+ */
+ public static boolean isRecoveryTriggeredReboot() {
+ return isFactoryResetPropertySet() || isRebootPropertySet();
+ }
+
+ private static boolean isFactoryResetPropertySet() {
+ return CrashRecoveryProperties.attemptingFactoryReset().orElse(false);
+ }
+
+ private static boolean isRebootPropertySet() {
+ return CrashRecoveryProperties.attemptingReboot().orElse(false);
+ }
+
private void dumpInternal(@NonNull PrintWriter pw) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.println("Package Watchdog status");
ipw.increaseIndent();
- synchronized (mLock) {
+ synchronized (sLock) {
for (String observerName : mAllObservers.keySet()) {
ipw.println("Observer name: " + observerName);
ipw.increaseIndent();
@@ -1324,7 +1348,7 @@ public class PackageWatchdog {
}
@VisibleForTesting
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
void registerObserverInternal(ObserverInternal observerInternal) {
mAllObservers.put(observerInternal.name, observerInternal);
}
@@ -1333,15 +1357,15 @@ public class PackageWatchdog {
* Represents an observer monitoring a set of packages along with the failure thresholds for
* each package.
*
- * <p> Note, the PackageWatchdog#mLock must always be held when reading or writing
+ * <p> Note, the PackageWatchdog#sLock must always be held when reading or writing
* instances of this class.
*/
static class ObserverInternal {
public final String name;
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private final ArrayMap<String, MonitoredPackage> mPackages = new ArrayMap<>();
@Nullable
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public PackageHealthObserver registeredObserver;
private int mMitigationCount;
@@ -1359,7 +1383,7 @@ public class PackageWatchdog {
* Writes important {@link MonitoredPackage} details for this observer to file.
* Does not persist any package failure thresholds.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public boolean writeLocked(XmlSerializer out) {
try {
out.startTag(null, TAG_OBSERVER);
@@ -1387,7 +1411,7 @@ public class PackageWatchdog {
mMitigationCount = mitigationCount;
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public void updatePackagesLocked(List<MonitoredPackage> packages) {
for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
MonitoredPackage p = packages.get(pIndex);
@@ -1410,7 +1434,7 @@ public class PackageWatchdog {
* health check passing, or an empty list if no package expired for which an explicit health
* check was still pending
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private Set<MonitoredPackage> prunePackagesLocked(long elapsedMs) {
Set<MonitoredPackage> failedPackages = new ArraySet<>();
Iterator<MonitoredPackage> it = mPackages.values().iterator();
@@ -1435,7 +1459,7 @@ public class PackageWatchdog {
* @returns {@code true} if failure threshold is exceeded, {@code false} otherwise
* @hide
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public boolean onPackageFailureLocked(String packageName) {
if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
&& registeredObserver.mayObservePackage(packageName)) {
@@ -1454,7 +1478,7 @@ public class PackageWatchdog {
*
* @return a mapping of package names to {@link MonitoredPackage} objects.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public ArrayMap<String, MonitoredPackage> getMonitoredPackages() {
return mPackages;
}
@@ -1467,7 +1491,7 @@ public class PackageWatchdog {
* @return the {@link MonitoredPackage} object associated with the package name if one
* exists, {@code null} otherwise.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
@Nullable
public MonitoredPackage getMonitoredPackage(String packageName) {
return mPackages.get(packageName);
@@ -1478,7 +1502,7 @@ public class PackageWatchdog {
*
* @param p: the {@link MonitoredPackage} to store.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public void putMonitoredPackage(MonitoredPackage p) {
mPackages.put(p.getName(), p);
}
@@ -1601,17 +1625,17 @@ public class PackageWatchdog {
* Represents a package and its health check state along with the time
* it should be monitored for.
*
- * <p> Note, the PackageWatchdog#mLock must always be held when reading or writing
+ * <p> Note, the PackageWatchdog#sLock must always be held when reading or writing
* instances of this class.
*/
class MonitoredPackage {
private final String mPackageName;
// Times when package failures happen sorted in ascending order
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private final LongArrayQueue mFailureHistory = new LongArrayQueue();
// Times when an observer was called to mitigate this package's failure. Sorted in
// ascending order.
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private final LongArrayQueue mMitigationCalls;
// One of STATE_[ACTIVE|INACTIVE|PASSED|FAILED]. Updated on construction and after
// methods that could change the health check state: handleElapsedTimeLocked and
@@ -1620,17 +1644,17 @@ public class PackageWatchdog {
// Whether an explicit health check has passed.
// This value in addition with mHealthCheckDurationMs determines the health check state
// of the package, see #getHealthCheckStateLocked
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private boolean mHasPassedHealthCheck;
// System uptime duration to monitor package.
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private long mDurationMs;
// System uptime duration to check the result of an explicit health check
// Initially, MAX_VALUE until we get a value from the health check service
// and request health checks.
// This value in addition with mHasPassedHealthCheck determines the health check state
// of the package, see #getHealthCheckStateLocked
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private long mHealthCheckDurationMs = Long.MAX_VALUE;
MonitoredPackage(String packageName, long durationMs,
@@ -1647,7 +1671,7 @@ public class PackageWatchdog {
/** Writes the salient fields to disk using {@code out}.
* @hide
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public void writeLocked(XmlSerializer out) throws IOException {
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATTR_NAME, getName());
@@ -1665,7 +1689,7 @@ public class PackageWatchdog {
*
* @return {@code true} if failure count exceeds a threshold, {@code false} otherwise
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public boolean onFailureLocked() {
// Sliding window algorithm: find out if there exists a window containing failures >=
// mTriggerFailureCount.
@@ -1685,7 +1709,7 @@ public class PackageWatchdog {
/**
* Notes the timestamp of a mitigation call into the observer.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public void noteMitigationCallLocked() {
mMitigationCalls.addLast(mSystemClock.uptimeMillis());
}
@@ -1696,7 +1720,7 @@ public class PackageWatchdog {
*
* @return the number of mitigation calls made in the de-escalation window.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public int getMitigationCountLocked() {
try {
final long now = mSystemClock.uptimeMillis();
@@ -1716,7 +1740,7 @@ public class PackageWatchdog {
*
* @return a LongArrayQueue of the mitigation calls relative to the current system uptime.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public LongArrayQueue normalizeMitigationCalls() {
LongArrayQueue normalized = new LongArrayQueue();
final long now = mSystemClock.uptimeMillis();
@@ -1731,7 +1755,7 @@ public class PackageWatchdog {
*
* @return the new health check state
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public int setHealthCheckActiveLocked(long initialHealthCheckDurationMs) {
if (initialHealthCheckDurationMs <= 0) {
Slog.wtf(TAG, "Cannot set non-positive health check duration "
@@ -1751,7 +1775,7 @@ public class PackageWatchdog {
*
* @return the new health check state
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public int handleElapsedTimeLocked(long elapsedMs) {
if (elapsedMs <= 0) {
Slog.w(TAG, "Cannot handle non-positive elapsed time for package " + getName());
@@ -1769,7 +1793,7 @@ public class PackageWatchdog {
}
/** Explicitly update the monitoring duration of the package. */
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public void updateHealthCheckDuration(long newDurationMs) {
mDurationMs = newDurationMs;
}
@@ -1780,7 +1804,7 @@ public class PackageWatchdog {
*
* @return the new {@link HealthCheckState health check state}
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
@HealthCheckState
public int tryPassHealthCheckLocked() {
if (mHealthCheckState != HealthCheckState.FAILED) {
@@ -1799,7 +1823,7 @@ public class PackageWatchdog {
/**
* Returns the current {@link HealthCheckState health check state}.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
@HealthCheckState
public int getHealthCheckStateLocked() {
return mHealthCheckState;
@@ -1810,7 +1834,7 @@ public class PackageWatchdog {
*
* @return the duration or {@link Long#MAX_VALUE} if the package should not be scheduled
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public long getShortestScheduleDurationMsLocked() {
// Consider health check duration only if #isPendingHealthChecksLocked is true
return Math.min(toPositive(mDurationMs),
@@ -1822,7 +1846,7 @@ public class PackageWatchdog {
* Returns {@code true} if the total duration left to monitor the package is less than or
* equal to 0 {@code false} otherwise.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public boolean isExpiredLocked() {
return mDurationMs <= 0;
}
@@ -1831,7 +1855,7 @@ public class PackageWatchdog {
* Returns {@code true} if the package, {@link #getName} is expecting health check results
* {@code false} otherwise.
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public boolean isPendingHealthChecksLocked() {
return mHealthCheckState == HealthCheckState.ACTIVE
|| mHealthCheckState == HealthCheckState.INACTIVE;
@@ -1843,7 +1867,7 @@ public class PackageWatchdog {
*
* @return the new {@link HealthCheckState health check state}
*/
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
@HealthCheckState
private int updateHealthCheckStateLocked() {
int oldState = mHealthCheckState;
@@ -1898,7 +1922,7 @@ public class PackageWatchdog {
}
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
@SuppressWarnings("GuardedBy")
void saveAllObserversBootMitigationCountToMetadata(String filePath) {
HashMap<String, Integer> bootMitigationCounts = new HashMap<>();
@@ -2001,7 +2025,7 @@ public class PackageWatchdog {
/** Increments the boot counter, and returns whether the device is bootlooping. */
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
public boolean incrementAndTest() {
if (Flags.recoverabilityDetection()) {
readAllObserversBootMitigationCountIfNecessary(METADATA_FILE);
@@ -2042,7 +2066,7 @@ public class PackageWatchdog {
}
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private boolean performedMitigationsDuringWindow() {
for (ObserverInternal observerInternal: mAllObservers.values()) {
if (observerInternal.getBootMitigationCount() > 0) {
@@ -2052,7 +2076,7 @@ public class PackageWatchdog {
return false;
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
private void resetAllObserversBootMitigationCount() {
for (int i = 0; i < mAllObservers.size(); i++) {
final ObserverInternal observer = mAllObservers.valueAt(i);
@@ -2061,7 +2085,7 @@ public class PackageWatchdog {
saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
}
- @GuardedBy("mLock")
+ @GuardedBy("sLock")
@SuppressWarnings("GuardedBy")
void readAllObserversBootMitigationCountIfNecessary(String filePath) {
File metadataFile = new File(filePath);
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 5147c52d4acc..ca0ca9c1bfd2 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -21,7 +21,7 @@
<string name="update" msgid="3932142540719227615">"Aktualizovat"</string>
<string name="done" msgid="6632441120016885253">"Hotovo"</string>
<string name="cancel" msgid="1018267193425558088">"Zrušit"</string>
- <string name="installing" msgid="4921993079741206516">"Instalace…"</string>
+ <string name="installing" msgid="4921993079741206516">"Probíhá instalace…"</string>
<string name="installing_app" msgid="1165095864863849422">"Instalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="install_done" msgid="5987363587661783896">"Aplikace je nainstalována."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Chcete tuto aplikaci nainstalovat?"</string>
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 003420829c8a..f97b75884a8a 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -65,6 +65,7 @@
android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"
android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
android:theme="@style/Theme.PrintActivity"
+ android:enableOnBackInvokedCallback="true"
android:exported="true">
<intent-filter>
<action android:name="android.print.PRINT_DIALOG" />
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index bd2b5ec8436e..4a3a6d248254 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -84,6 +84,7 @@ import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
+import android.window.OnBackInvokedDispatcher;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -323,6 +324,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
});
getLoaderManager().initLoader(LOADER_ID_ENABLED_PRINT_SERVICES, null, this);
+ getWindow().getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, this::onBackInvoked);
}
private void onConnectedToPrintSpooler(final IBinder documentAdapter) {
@@ -481,17 +484,21 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
if ((keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE)
&& event.isTracking() && !event.isCanceled()) {
- if (mPrintPreviewController != null && mPrintPreviewController.isOptionsOpened()
- && !hasErrors()) {
- mPrintPreviewController.closeOptions();
- } else {
- cancelPrint();
- }
+ onBackInvoked();
return true;
}
return super.onKeyUp(keyCode, event);
}
+ private void onBackInvoked() {
+ if (mPrintPreviewController != null && mPrintPreviewController.isOptionsOpened()
+ && !hasErrors()) {
+ mPrintPreviewController.closeOptions();
+ } else {
+ cancelPrint();
+ }
+ }
+
@Override
public void onRequestContentUpdate() {
if (canUpdateDocument()) {
diff --git a/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
new file mode 100644
index 000000000000..38cae307f5dc
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-af/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Kies \'n prent"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Neem \'n foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Verstekgebruikerikoon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
new file mode 100644
index 000000000000..917a2fdc6a61
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-am/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ምስል ይምረጡ"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ፎቶ ያንሱ"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ነባሪ የተጠቃሚ አዶ"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
new file mode 100644
index 000000000000..8e5231ba1e77
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ar/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"اختيار صورة"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"التقاط صورة"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"رمز المستخدم التلقائي"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
new file mode 100644
index 000000000000..c77b573b26c6
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-as/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"এখন ফট’ তোলক"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ডিফ’ল্ট ব্যৱহাৰকাৰীৰ চিহ্ন"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
new file mode 100644
index 000000000000..6871473a82a3
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-az/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Şəkil seçin"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Foto çəkin"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Defolt istifadəçi ikonası"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 000000000000..42fb478f5ca0
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Slikajte"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Podrazumevana ikona korisnika"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
new file mode 100644
index 000000000000..c2ef4db67c5d
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-be/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Выбраць відарыс"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Зрабіць фота"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Стандартны карыстальніцкі значок"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
new file mode 100644
index 000000000000..eeca7d8d5c9e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-bg/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Избиране на изображение"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Правене на снимка"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Икона за основния потребител"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
new file mode 100644
index 000000000000..6d4d29f47ac6
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-bn/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"একটি ছবি বেছে নিন"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ফটো তুলুন"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ডিফল্ট ব্যবহারকারীর আইকন"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
new file mode 100644
index 000000000000..def1b4525c40
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-bs/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Snimite fotografiju"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Zadana ikona korisnika"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
new file mode 100644
index 000000000000..1b613cafa4df
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ca/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Tria una imatge"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Fes una foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icona d\'usuari predeterminat"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
new file mode 100644
index 000000000000..ffe2f47df489
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-cs/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Zvolit obrázek"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Vyfotit"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Výchozí uživatelská ikona"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
new file mode 100644
index 000000000000..ab01eef4ab6e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-da/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Vælg et billede"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Tag et billede"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon for standardbruger"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
new file mode 100644
index 000000000000..4d6c651adabd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-de/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Bild auswählen"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Foto aufnehmen"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Standardmäßiges Nutzersymbol"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
new file mode 100644
index 000000000000..9e6813fff4d0
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-el/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Επιλέξτε μια εικόνα"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Λήψη φωτογραφίας"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Προεπιλεγμένο εικονίδιο χρήστη"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
new file mode 100644
index 000000000000..d0aae7917ffd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rAU/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml
new file mode 100644
index 000000000000..f9905d0eb796
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rCA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Choose a profile picture"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+ <string name="done" msgid="3587741621903511576">"Done"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
new file mode 100644
index 000000000000..d0aae7917ffd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rGB/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
new file mode 100644
index 000000000000..d0aae7917ffd
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-en-rIN/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Choose an image"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Take a photo"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Default user icon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
new file mode 100644
index 000000000000..296dcc8603e6
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-es-rUS/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Elegir una imagen"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Tomar una foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ícono de usuario predeterminado"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
new file mode 100644
index 000000000000..5d4a8d280796
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-es/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Seleccionar una imagen"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Hacer una foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icono de usuario predeterminado"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
new file mode 100644
index 000000000000..ecd3a83ea2b2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-et/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Vali pilt"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Pildista"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Vaikekasutajaikoon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
new file mode 100644
index 000000000000..e29bc114b5ec
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-eu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Aukeratu irudi bat"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Atera argazki bat"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Erabiltzaile lehenetsiaren ikonoa"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
new file mode 100644
index 000000000000..25efac4ba93d
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fa/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"انتخاب تصویر"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"عکس گرفتن"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"نماد کاربر پیش‌فرض"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
new file mode 100644
index 000000000000..4d805ed242cb
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fi/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Valitse kuva"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Ota kuva"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Oletuskäyttäjäkuvake"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
new file mode 100644
index 000000000000..fb32c5b118fb
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fr-rCA/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Sélectionner une image"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Prendre une photo"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icône d\'utilisateur par défaut"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
new file mode 100644
index 000000000000..79620e96bcac
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-fr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Choisir une image"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Prendre une photo"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icône de l\'utilisateur par défaut"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
new file mode 100644
index 000000000000..bbfa18bf0080
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-gl/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Escoller unha imaxe"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar unha foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icona do usuario predeterminado"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
new file mode 100644
index 000000000000..247afe13d0fb
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-gu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"છબી પસંદ કરો"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ફોટો લો"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ડિફૉલ્ટ વપરાશકર્તાનું આઇકન"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
new file mode 100644
index 000000000000..3c515769630e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hi/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"इमेज चुनें"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"फ़ोटो खींचें"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"उपयोगकर्ता के लिए डिफ़ॉल्ट आइकॉन"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
new file mode 100644
index 000000000000..e9a56bdc839e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Odaberite sliku"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Snimi fotografiju"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikona zadanog korisnika"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
new file mode 100644
index 000000000000..f3d53cd57d53
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Kép kiválasztása"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Fotó készítése"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Alapértelmezett felhasználó ikonja"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml
new file mode 100644
index 000000000000..d897cd264c8d
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-hy/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Ընտրել պատկեր"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Լուսանկարել"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Ընտրեք պրոֆիլի նկար"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Օգտատիրոջ կանխադրված պատկերակ"</string>
+ <string name="done" msgid="3587741621903511576">"Պատրաստ է"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
new file mode 100644
index 000000000000..bfa0d935c6e7
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-in/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Pilih gambar"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Ambil foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon pengguna default"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
new file mode 100644
index 000000000000..d49652480db5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-is/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Velja mynd"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Taka mynd"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Tákn sjálfgefins notanda"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
new file mode 100644
index 000000000000..3ba0a01cbed2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-it/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Scegli un\'immagine"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Scatta una foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icona dell\'utente predefinito"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
new file mode 100644
index 000000000000..903989d999e0
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-iw/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"לבחירת תמונה"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"צילום תמונה"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"סמל המשתמש שמוגדר כברירת מחדל"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml
new file mode 100644
index 000000000000..15a4cdc974a1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ja/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"画像を選択"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"写真を撮る"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"プロフィール写真の選択"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"デフォルト ユーザー アイコン"</string>
+ <string name="done" msgid="3587741621903511576">"完了"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
new file mode 100644
index 000000000000..817180bb6493
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ka/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"სურათის არჩევა"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ფოტოს გადაღება"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"მომხმარებლის ნაგულისხმევი ხატულა"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
new file mode 100644
index 000000000000..ec01801bace9
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-kk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Кескін таңдау"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Суретке түсіру"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Әдепкі пайдаланушы белгішесі"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
new file mode 100644
index 000000000000..7a311224646e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-km/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ជ្រើសរើស​រូបភាព"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ថតរូប"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"រូបអ្នកប្រើប្រាស់លំនាំដើម"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml
new file mode 100644
index 000000000000..67f889980bd8
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-kn/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ಚಿತ್ರವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ಫೋಟೋವನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ಪ್ರೊಫೈಲ್‌ ಚಿತ್ರವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ಡೀಫಾಲ್ಟ್ ಬಳಕೆದಾರರ ಐಕಾನ್"</string>
+ <string name="done" msgid="3587741621903511576">"ಮುಗಿದಿದೆ"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
new file mode 100644
index 000000000000..45bfb532e6e1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ko/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"이미지 선택"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"사진 찍기"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"기본 사용자 아이콘"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
new file mode 100644
index 000000000000..b3d39de49bda
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ky/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Сүрөт тандоо"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Сүрөткө тартуу"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Демейки колдонуучунун сүрөтчөсү"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
new file mode 100644
index 000000000000..3ba6709d04a4
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-lo/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ເລືອກຮູບ"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ຖ່າຍຮູບ"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ໄອຄອນຜູ້ໃຊ້ເລີ່ມຕົ້ນ"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
new file mode 100644
index 000000000000..b0c0c39495f5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-lt/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Pasirinkti vaizdą"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Fotografuoti"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Numatytojo naudotojo piktograma"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
new file mode 100644
index 000000000000..e664c80b5e7c
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-lv/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Izvēlēties attēlu"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Uzņemt fotoattēlu"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Noklusējuma lietotāja ikona"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
new file mode 100644
index 000000000000..bb0e2476bdc2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-mk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Изберете слика"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Фотографирај"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Икона за стандарден корисник"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
new file mode 100644
index 000000000000..674b4f5d8fb5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ml/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ഡിഫോൾട്ട് ഉപയോക്തൃ ഐക്കൺ"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
new file mode 100644
index 000000000000..61553b54d745
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-mn/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Зураг сонгох"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Зураг авах"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Өгөгдмөл хэрэглэгчийн дүрс тэмдэг"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml
new file mode 100644
index 000000000000..acc2c460a891
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-mr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"इमेज निवडा"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"फोटो काढा"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"प्रोफाइल फोटो निवडा"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"डीफॉल्ट वापरकर्ता आयकन"</string>
+ <string name="done" msgid="3587741621903511576">"पूर्ण झाले"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
new file mode 100644
index 000000000000..25996969e61e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ms/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Pilih imej"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Ambil foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon pengguna lalai"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
new file mode 100644
index 000000000000..f9f697b3c200
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-my/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ပုံရွေးရန်"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ဓာတ်ပုံရိုက်ရန်"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"မူရင်းအသုံးပြုသူ သင်္ကေတ"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
new file mode 100644
index 000000000000..c1b7631fa8b2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-nb/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Velg et bilde"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Ta et bilde"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Standard brukerikon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
new file mode 100644
index 000000000000..a8c02b97cac8
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ne/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"कुनै फोटो छनौट गर्नुहोस्"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"फोटो खिच्नुहोस्"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"प्रयोगकर्ताको डिफल्ट आइकन"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
new file mode 100644
index 000000000000..47352bc12100
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-nl/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Een afbeelding kiezen"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Een foto maken"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Standaard gebruikersicoon"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
new file mode 100644
index 000000000000..132b97a6f46c
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-or/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ଗୋଟିଏ ଛବି ବାଛନ୍ତୁ"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ଡିଫଲ୍ଟ ୟୁଜର ଆଇକନ"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml
new file mode 100644
index 000000000000..a336226b5182
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ਚਿੱਤਰ ਚੁਣੋ"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ਕੋਈ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਚੁਣੋ"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਰਤੋਂਕਾਰ ਪ੍ਰਤੀਕ"</string>
+ <string name="done" msgid="3587741621903511576">"ਹੋ ਗਿਆ"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
new file mode 100644
index 000000000000..7db79047047b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pl/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Wybierz obraz"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Zrób zdjęcie"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikona domyślnego użytkownika"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
new file mode 100644
index 000000000000..ae3e6e508c8b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt-rBR/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ícone de usuário padrão"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml
new file mode 100644
index 000000000000..18f36c39bfa1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt-rPT/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Escolha uma imagem do perfil"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ícone do utilizador predefinido"</string>
+ <string name="done" msgid="3587741621903511576">"Concluído"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
new file mode 100644
index 000000000000..ae3e6e508c8b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-pt/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Escolher uma imagem"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Tirar uma foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ícone de usuário padrão"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
new file mode 100644
index 000000000000..ce662d41a113
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ro/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Alege o imagine"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Fă o fotografie"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Pictograma prestabilită a utilizatorului"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
new file mode 100644
index 000000000000..47f8a839beb4
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ru/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Выбрать фото"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Сделать снимок"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Значок пользователя по умолчанию"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
new file mode 100644
index 000000000000..aaba44266bb1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-si/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"රූපයක් තෝරන්න"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ඡායාරූපයක් ගන්න"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"පෙරනිමි පරිශීලක නිරූපකය"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
new file mode 100644
index 000000000000..3f801a36843d
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Vybrať obrázok"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Odfotiť"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Predvolená ikona používateľa"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml
new file mode 100644
index 000000000000..7d0bf10cc564
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Izbira slike"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Fotografiranje"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Izbira profilne slike"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Privzeta ikona uporabnika"</string>
+ <string name="done" msgid="3587741621903511576">"Končano"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
new file mode 100644
index 000000000000..0b8a58d0d5d5
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sq/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Zgjidh një imazh"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Bëj një fotografi"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikona e parazgjedhur e përdoruesit"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
new file mode 100644
index 000000000000..1014df4f3b95
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Одаберите слику"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Сликајте"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Подразумевана икона корисника"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
new file mode 100644
index 000000000000..82034092288a
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sv/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Välj en bild"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Ta ett foto"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Ikon för standardanvändare"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
new file mode 100644
index 000000000000..b0e8c44d5e8a
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-sw/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Chagua picha"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Piga picha"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Aikoni chaguomsingi ya mtumiaji"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml
new file mode 100644
index 000000000000..13c7b5b13a54
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ta/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"படத்தைத் தேர்வுசெய்க"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"படமெடு"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"சுயவிவரப் படத்தைத் தேர்வுசெய்யுங்கள்"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"இயல்புநிலைப் பயனர் ஐகான்"</string>
+ <string name="done" msgid="3587741621903511576">"முடிந்தது"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-te/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-te/strings.xml
new file mode 100644
index 000000000000..b7318486f10f
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-te/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"చిత్రాన్ని ఎంచుకోండి"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ఫోటోను తీయి"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"ప్రొఫైల్ ఫోటోను ఎంచుకోండి"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ఆటోమేటిక్ సెట్టింగ్ యూజర్ చిహ్నం"</string>
+ <string name="done" msgid="3587741621903511576">"పూర్తయింది"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
new file mode 100644
index 000000000000..31e753e04cc1
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-th/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"เลือกรูปภาพ"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ถ่ายรูป"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ไอคอนผู้ใช้เริ่มต้น"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml
new file mode 100644
index 000000000000..77b28cd5e7b6
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-tl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Pumili ng larawan"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Kumuha ng larawan"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Pumili ng larawan sa profile"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Icon ng default na user"</string>
+ <string name="done" msgid="3587741621903511576">"Tapos na"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
new file mode 100644
index 000000000000..26d96c22c7f2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-tr/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Resim seç"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Fotoğraf çek"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Varsayılan kullanıcı simgesi"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
new file mode 100644
index 000000000000..1fbe5fb1076a
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-uk/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Вибрати зображення"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Зробити фото"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Значок користувача за умовчанням"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml
new file mode 100644
index 000000000000..7972ee125c9e
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-ur/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"ایک تصویر منتخب کریں"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"ایک تصویر لیں"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"پروفائل کی تصویر منتخب کریں"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"ڈیفالٹ صارف کا آئیکن"</string>
+ <string name="done" msgid="3587741621903511576">"ہو گیا"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml
new file mode 100644
index 000000000000..208be10481ee
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-uz/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Rasm tanlash"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Suratga olish"</string>
+ <string name="avatar_picker_title" msgid="7478146965334560463">"Profil rasmini tanlash"</string>
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Foydalanuvchining standart belgisi"</string>
+ <string name="done" msgid="3587741621903511576">"Tayyor"</string>
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
new file mode 100644
index 000000000000..036c0065ebd7
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-vi/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Chọn hình ảnh"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Chụp ảnh"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Biểu tượng người dùng mặc định"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
new file mode 100644
index 000000000000..58488b35b0a6
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rCN/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"选择图片"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"拍照"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"默认用户图标"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
new file mode 100644
index 000000000000..e5f375205844
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rHK/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"選擇圖片"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"拍攝相片"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"預設使用者圖示"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000000..4a58180ba15f
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zh-rTW/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"選擇圖片"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"拍照"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"預設使用者圖示"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml b/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
new file mode 100644
index 000000000000..ad15f890cd05
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values-zu/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="user_image_choose_photo" msgid="5630717762469961028">"Khetha isithombe"</string>
+ <string name="user_image_take_photo" msgid="3147097821937166738">"Thatha isithombe"</string>
+ <!-- no translation found for avatar_picker_title (7478146965334560463) -->
+ <skip />
+ <string name="default_user_icon_description" msgid="6018582161341388812">"Isithonjana somsebenzisi sokuzenzakalelayo"</string>
+ <!-- no translation found for done (3587741621903511576) -->
+ <skip />
+</resources>
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
index 43d7dfa4a158..a3709c109111 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
@@ -133,8 +133,11 @@ interface PreferenceLifecycleProvider {
*/
abstract class PreferenceLifecycleContext(context: Context) : ContextWrapper(context) {
- /** Notifies that preference state is changed and update preference widget UI. */
- abstract fun notifyPreferenceChange(preference: PreferenceMetadata)
+ /** Returns the preference widget object associated with given key. */
+ abstract fun <T> findPreference(key: String): T?
+
+ /** Notifies that preference state of given key is changed and updates preference widget UI. */
+ abstract fun notifyPreferenceChange(key: String)
/**
* Starts activity for result, see [android.app.Activity.startActivityForResult].
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
index cfe6089169d3..62ac3ade62a4 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -57,8 +57,11 @@ class PreferenceScreenBindingHelper(
private val preferenceLifecycleContext =
object : PreferenceLifecycleContext(context) {
- override fun notifyPreferenceChange(preference: PreferenceMetadata) =
- notifyChange(preference.key, CHANGE_REASON_STATE)
+ override fun <T> findPreference(key: String) =
+ preferenceScreen.findPreference(key) as T?
+
+ override fun notifyPreferenceChange(key: String) =
+ notifyChange(key, CHANGE_REASON_STATE)
@Suppress("DEPRECATION")
override fun startActivityForResult(
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
index ca17836f6cf4..db7f687f23b5 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
@@ -19,5 +19,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="settingslib_category_personal" msgid="1142302328104700620">"व्यक्तिगत"</string>
<string name="settingslib_category_work" msgid="4867750733682444676">"कामसम्बन्धी"</string>
- <string name="settingslib_category_private" msgid="5039276873477591386">"निजी"</string>
+ <string name="settingslib_category_private" msgid="5039276873477591386">"निजी स्पेस"</string>
</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml
new file mode 100644
index 000000000000..2539aa040a60
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-en-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expand"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml
new file mode 100644
index 000000000000..2fc65f0cb149
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-hy/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Ծավալել"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Ծալել"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml
new file mode 100644
index 000000000000..4e7287c4eedd
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ja/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"開く"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"閉じる"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml
new file mode 100644
index 000000000000..3fc1fcc728a7
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-kn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ವಿಸ್ತೃತಗೊಳಿಸಿ"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ಕುಗ್ಗಿಸಿ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml
new file mode 100644
index 000000000000..db9d42280528
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-mr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"विस्तार करा"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"कोलॅप्स करा"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml
new file mode 100644
index 000000000000..48a756b81c9c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"ਵਿਸਤਾਰ ਕਰੋ"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"ਸਮੇਟੋ"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml
new file mode 100644
index 000000000000..58bd936a8bae
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-pt-rPT/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Expandir"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Reduzir"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml
new file mode 100644
index 000000000000..6fd67c59ff3d
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Razširi"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Strni"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml
new file mode 100644
index 000000000000..4a0fb4d96e03
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ta/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"விரிவாக்கும்"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"சுருக்கும்"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-te/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-te/strings.xml
new file mode 100644
index 000000000000..706e225560c1
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-te/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"విస్తరించండి"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"కుదించండి"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml
new file mode 100644
index 000000000000..ef5825ff1c3e
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"I-expand"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"I-collapse"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml
new file mode 100644
index 000000000000..2e020b4e0676
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-ur/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"پھیلائیں"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"سکیڑیں"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml b/packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml
new file mode 100644
index 000000000000..16e389b88405
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-uz/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="settingslib_expressive_text_expand" msgid="7520894876795775876">"Yoyish"</string>
+ <string name="settingslib_expressive_text_collapse" msgid="5625043934702341576">"Yopish"</string>
+</resources>
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/ModifierExt.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/ModifierExt.kt
index e883a4a55af9..25bb46c837f6 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/ModifierExt.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/ModifierExt.kt
@@ -25,3 +25,36 @@ fun Modifier.contentDescription(contentDescription: String?) =
if (contentDescription != null) this.semantics {
this.contentDescription = contentDescription
} else this
+
+/**
+ * Concatenates this modifier with another if `condition` is true.
+ *
+ * This method allows inline conditional addition of modifiers to a modifier chain. Instead of
+ * writing
+ *
+ * ```
+ * val aModifier = Modifier.a()
+ * val bModifier = if(condition) aModifier.b() else aModifier
+ * Composable(modifier = bModifier)
+ * ```
+ *
+ * You can instead write
+ *
+ * ```
+ * Composable(modifier = Modifier.a().thenIf(condition){
+ * Modifier.b()
+ * }
+ * ```
+ *
+ * This makes the modifier chain easier to read.
+ *
+ * Note that unlike the non-factory version, the conditional modifier is recreated each time, and
+ * may never be created at all.
+ *
+ * @param condition Whether or not to apply the modifiers.
+ * @param factory Creates the modifier to concatenate with the current one.
+ * @return a Modifier representing this modifier followed by other in sequence.
+ * @see Modifier.then
+ */
+inline fun Modifier.thenIf(condition: Boolean, crossinline factory: () -> Modifier): Modifier =
+ if (condition) this.then(factory()) else this
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/BaseLayout.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/BaseLayout.kt
index acb96be64a34..b1bb79d61b03 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/BaseLayout.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/BaseLayout.kt
@@ -36,12 +36,13 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.min
+import com.android.settingslib.spa.framework.compose.thenIf
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.framework.theme.SettingsOpacity.alphaForEnabled
import com.android.settingslib.spa.framework.theme.SettingsShape
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
+import com.android.settingslib.spa.widget.ui.LocalIsInCategory
import com.android.settingslib.spa.widget.ui.SettingsTitle
@Composable
@@ -57,18 +58,18 @@ internal fun BaseLayout(
paddingVertical: Dp = SettingsDimension.itemPaddingVertical,
widget: @Composable () -> Unit = {},
) {
+ val surfaceBright = MaterialTheme.colorScheme.surfaceBright
Row(
modifier =
modifier
.fillMaxWidth()
.semantics(mergeDescendants = true) {}
- .then(
- if (isSpaExpressiveEnabled)
- Modifier.heightIn(min = SettingsDimension.preferenceMinHeight)
- .clip(SettingsShape.CornerExtraSmall)
- .background(MaterialTheme.colorScheme.surfaceBright)
- else Modifier
- )
+ .thenIf(isSpaExpressiveEnabled) {
+ Modifier.heightIn(min = SettingsDimension.preferenceMinHeight)
+ }
+ .thenIf(isSpaExpressiveEnabled && LocalIsInCategory.current) {
+ Modifier.clip(SettingsShape.CornerExtraSmall).background(surfaceBright)
+ }
.padding(end = paddingEnd),
verticalAlignment = Alignment.CenterVertically,
) {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
index 28b2b4ab1662..96d2abb70391 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
@@ -31,6 +31,8 @@ import androidx.compose.material.icons.outlined.TouchApp
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -99,7 +101,7 @@ fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit)
verticalArrangement =
if (isSpaExpressiveEnabled) Arrangement.spacedBy(SettingsDimension.paddingTiny)
else Arrangement.Top,
- content = content,
+ content = { CompositionLocalProvider(LocalIsInCategory provides true) { content() } },
)
}
}
@@ -109,15 +111,14 @@ fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit)
*
* @param list The list of items to display.
* @param entry The entry for each list item according to its index in list.
- * @param key Optional. The key for each item in list to provide unique item identifiers, making
- * the list more efficient.
- * @param title Optional. Category title for each item or each group of items in the list. It
- * should be decided by the index.
+ * @param key Optional. The key for each item in list to provide unique item identifiers, making the
+ * list more efficient.
+ * @param title Optional. Category title for each item or each group of items in the list. It should
+ * be decided by the index.
* @param bottomPadding Optional. Bottom outside padding of the category.
* @param state Optional. State of LazyList.
* @param content Optional. Content to be shown at the top of the category.
*/
-
@Composable
fun LazyCategory(
list: List<Any>,
@@ -144,17 +145,19 @@ fun LazyCategory(
verticalArrangement = Arrangement.spacedBy(SettingsDimension.paddingTiny),
state = state,
) {
- item { content() }
+ item { CompositionLocalProvider(LocalIsInCategory provides true) { content() } }
items(count = list.size, key = key) {
title?.invoke(it)?.let { title -> CategoryTitle(title) }
- val entryPreference = entry(it)
- entryPreference()
+ CompositionLocalProvider(LocalIsInCategory provides true) { entry(it)() }
}
}
}
}
+/** LocalIsInCategory containing the if the current composable is in a category. */
+internal val LocalIsInCategory = compositionLocalOf { false }
+
@Preview
@Composable
private fun CategoryPreview() {
diff --git a/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml b/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml
index 618677389ce1..91275707ac02 100644
--- a/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml
+++ b/packages/SettingsLib/res/drawable/ic_bt_le_audio_sharing.xml
@@ -15,73 +15,12 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:autoMirrored="true"
- android:height="24dp"
- android:width="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:tint="?android:attr/colorControlNormal">
- <path
- android:fillColor="#000000"
- android:pathData="M16.984,24H7.279L12.131,15.508L16.984,24ZM10.481,22.144H13.781L12.131,19.257L10.481,22.144Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M12.131,14.295C13.471,14.295 14.558,13.209 14.558,11.869C14.558,10.529 13.471,9.442 12.131,9.442C10.791,9.442 9.705,10.529 9.705,11.869C9.705,13.209 10.791,14.295 12.131,14.295Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M4.573,21.368C4.052,20.943 3.967,20.179 4.379,19.657C4.804,19.136 5.568,19.051 6.09,19.463C6.611,19.876 6.696,20.64 6.284,21.174C6.041,21.465 5.689,21.623 5.338,21.623C5.071,21.623 4.804,21.538 4.573,21.368Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M17.991,21.162C17.579,20.628 17.663,19.876 18.185,19.451C18.707,19.039 19.471,19.124 19.896,19.646C20.308,20.167 20.223,20.931 19.702,21.344C19.471,21.526 19.204,21.611 18.949,21.611C18.586,21.611 18.234,21.453 17.991,21.162Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M1.213,17.145C0.91,16.551 1.165,15.823 1.771,15.532C2.378,15.241 3.093,15.495 3.397,16.09C3.688,16.697 3.433,17.424 2.827,17.715C2.657,17.8 2.475,17.837 2.305,17.837C1.844,17.837 1.419,17.582 1.213,17.145Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M21.449,17.691C20.842,17.4 20.588,16.684 20.879,16.077C21.17,15.471 21.898,15.216 22.504,15.507C23.099,15.798 23.354,16.526 23.062,17.133C22.856,17.557 22.419,17.812 21.971,17.812C21.789,17.812 21.619,17.776 21.449,17.691Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M0,11.892C0,11.225 0.546,10.679 1.213,10.679C1.88,10.679 2.426,11.212 2.426,11.892C2.426,12.559 1.88,13.105 1.213,13.105C0.546,13.105 0,12.559 0,11.892Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M21.837,11.869C21.837,11.857 21.837,11.845 21.837,11.833C21.824,11.153 22.37,10.62 23.05,10.607C23.717,10.607 24.251,11.153 24.263,11.821C24.263,11.833 24.263,11.845 24.263,11.845C24.263,11.857 24.263,11.869 24.263,11.869C24.263,12.536 23.717,13.082 23.05,13.082C22.382,13.082 21.837,12.536 21.837,11.869Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M1.759,8.242C1.152,7.963 0.898,7.235 1.189,6.628C1.48,6.022 2.196,5.767 2.802,6.058C3.409,6.349 3.664,7.077 3.372,7.684C3.166,8.108 2.729,8.363 2.281,8.363C2.099,8.363 1.929,8.327 1.759,8.242Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M20.866,7.622C20.563,7.028 20.818,6.3 21.424,6.009C22.019,5.706 22.747,5.96 23.038,6.567C23.038,6.567 23.038,6.567 23.05,6.567C23.341,7.161 23.087,7.889 22.48,8.181C22.31,8.265 22.128,8.302 21.958,8.302C21.509,8.302 21.073,8.059 20.866,7.622Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M4.355,4.104C3.931,3.582 4.016,2.818 4.537,2.406C5.071,1.981 5.823,2.066 6.248,2.588C6.672,3.109 6.588,3.874 6.066,4.298C5.835,4.48 5.569,4.565 5.302,4.565C4.95,4.565 4.598,4.407 4.355,4.104Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M18.161,4.262C17.627,3.838 17.542,3.073 17.955,2.552C18.379,2.03 19.132,1.945 19.666,2.358C20.187,2.77 20.272,3.534 19.86,4.068C19.617,4.359 19.265,4.517 18.913,4.517C18.646,4.517 18.379,4.432 18.161,4.262Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M8.492,1.497C8.334,0.854 8.747,0.199 9.402,0.041C10.057,-0.105 10.7,0.308 10.858,0.963C11.003,1.606 10.591,2.261 9.948,2.407C9.851,2.431 9.754,2.443 9.669,2.443C9.123,2.443 8.613,2.067 8.492,1.497Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M14.267,2.395C13.599,2.249 13.199,1.606 13.345,0.951C13.49,0.296 14.133,-0.116 14.788,0.029C15.443,0.175 15.856,0.83 15.71,1.485C15.589,2.043 15.08,2.431 14.534,2.431C14.437,2.431 14.352,2.419 14.267,2.395Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M7,17.037C6.527,16.564 6.527,15.8 7,15.326C7.473,14.841 8.237,14.841 8.71,15.314C9.196,15.787 9.196,16.552 8.723,17.025C8.48,17.267 8.177,17.389 7.861,17.389C7.546,17.389 7.242,17.267 7,17.037Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M15.565,17.012C15.092,16.539 15.092,15.762 15.565,15.289C16.038,14.816 16.814,14.816 17.288,15.289C17.761,15.762 17.761,16.539 17.288,17.012C17.045,17.243 16.742,17.364 16.426,17.364C16.111,17.364 15.807,17.243 15.565,17.012Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M4.853,11.917C4.853,11.237 5.386,10.691 6.054,10.691C6.721,10.691 7.279,11.225 7.279,11.892C7.279,12.56 6.745,13.106 6.078,13.118C5.398,13.118 4.853,12.584 4.853,11.917Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M16.984,11.868C16.984,11.856 16.984,11.844 16.984,11.832C16.984,11.832 16.984,11.82 16.984,11.807C16.972,11.14 17.506,10.582 18.185,10.582C18.852,10.57 19.398,11.116 19.41,11.783C19.41,11.795 19.41,11.82 19.41,11.832C19.41,11.844 19.41,11.856 19.41,11.868C19.41,12.535 18.865,13.081 18.197,13.081C17.53,13.081 16.984,12.535 16.984,11.868Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M6.952,8.471C6.478,7.997 6.478,7.233 6.952,6.76C6.952,6.76 6.952,6.76 6.939,6.76C7.413,6.275 8.189,6.275 8.662,6.748C9.135,7.221 9.147,7.985 8.674,8.458C8.432,8.701 8.116,8.822 7.813,8.822C7.497,8.822 7.194,8.701 6.952,8.471Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M15.529,8.399C15.043,7.938 15.043,7.161 15.504,6.688C15.977,6.203 16.742,6.203 17.227,6.664C17.7,7.137 17.712,7.901 17.239,8.387C17.009,8.629 16.693,8.751 16.378,8.751C16.075,8.751 15.759,8.629 15.529,8.399Z"/>
- <path
- android:fillColor="#000000"
- android:pathData="M10.87,5.815C10.858,5.148 11.392,4.59 12.071,4.59C12.738,4.578 13.284,5.124 13.284,5.791C13.296,6.458 12.762,7.016 12.083,7.016C11.416,7.016 10.87,6.483 10.87,5.815Z"/>
-</vector>
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M320,880L480,596L640,880L320,880ZM480,560Q447,560 423.5,536.5Q400,513 400,480Q400,447 423.5,423.5Q447,400 480,400Q513,400 536.5,423.5Q560,447 560,480Q560,513 536.5,536.5Q513,560 480,560ZM339,661Q322,661 310.5,649.5Q299,638 299,621Q299,604 310.5,592.5Q322,581 339,581Q356,581 367.5,592.5Q379,604 379,621Q379,638 367.5,649.5Q356,661 339,661ZM280,520Q263,520 251.5,508.5Q240,497 240,480Q240,463 251.5,451.5Q263,440 280,440Q297,440 308.5,451.5Q320,463 320,480Q320,497 308.5,508.5Q297,520 280,520ZM339,379Q322,379 310.5,367.5Q299,356 299,339Q299,322 310.5,310.5Q322,299 339,299Q356,299 367.5,310.5Q379,322 379,339Q379,356 367.5,367.5Q356,379 339,379ZM480,320Q463,320 451.5,308.5Q440,297 440,280Q440,263 451.5,251.5Q463,240 480,240Q497,240 508.5,251.5Q520,263 520,280Q520,297 508.5,308.5Q497,320 480,320ZM621,379Q604,379 592.5,367.5Q581,356 581,339Q581,322 592.5,310.5Q604,299 621,299Q638,299 649.5,310.5Q661,322 661,339Q661,356 649.5,367.5Q638,379 621,379ZM680,520Q663,520 651.5,508.5Q640,497 640,480Q640,463 651.5,451.5Q663,440 680,440Q697,440 708.5,451.5Q720,463 720,480Q720,497 708.5,508.5Q697,520 680,520ZM621,661Q604,661 592.5,649.5Q581,638 581,621Q581,604 592.5,592.5Q604,581 621,581Q638,581 649.5,592.5Q661,604 661,621Q661,638 649.5,649.5Q638,661 621,661ZM255,801Q238,801 226,788.5Q214,776 214,759Q214,742 226,730Q238,718 255,718Q272,718 284.5,730Q297,742 297,759Q297,776 284.5,788.5Q272,801 255,801ZM156,676Q139,676 127.5,664Q116,652 116,635Q116,618 127.5,606.5Q139,595 156,595Q173,595 185,606.5Q197,618 197,635Q197,652 185,664Q173,676 156,676ZM120,520Q103,520 91.5,508.5Q80,497 80,480Q80,463 91.5,451.5Q103,440 120,440Q137,440 148.5,451.5Q160,463 160,480Q160,497 148.5,508.5Q137,520 120,520ZM156,363Q139,363 127.5,351.5Q116,340 116,323Q116,306 127.5,294.5Q139,283 156,283Q173,283 184.5,294.5Q196,306 196,323Q196,340 184.5,351.5Q173,363 156,363ZM256,239Q239,239 227.5,227.5Q216,216 216,199Q216,182 227.5,170.5Q239,159 256,159Q273,159 284.5,170.5Q296,182 296,199Q296,216 284.5,227.5Q273,239 256,239ZM400,169Q383,169 371.5,157.5Q360,146 360,129Q360,112 371.5,100.5Q383,89 400,89Q417,89 428.5,100.5Q440,112 440,129Q440,146 428.5,157.5Q417,169 400,169ZM560,169Q543,169 531.5,157.5Q520,146 520,129Q520,112 531.5,100.5Q543,89 560,89Q577,89 588.5,100.5Q600,112 600,129Q600,146 588.5,157.5Q577,169 560,169ZM705,239Q688,239 676.5,227.5Q665,216 665,199Q665,182 676.5,170.5Q688,159 705,159Q722,159 733.5,170.5Q745,182 745,199Q745,216 733.5,227.5Q722,239 705,239ZM805,364Q788,364 776.5,352.5Q765,341 765,324Q765,307 776.5,295.5Q788,284 805,284Q822,284 833.5,295.5Q845,307 845,324Q845,341 833.5,352.5Q822,364 805,364ZM840,520Q823,520 811.5,508.5Q800,497 800,480Q800,463 811.5,451.5Q823,440 840,440Q857,440 868.5,451.5Q880,463 880,480Q880,497 868.5,508.5Q857,520 840,520ZM805,676Q788,676 776.5,664.5Q765,653 765,636Q765,619 776.5,607.5Q788,596 805,596Q822,596 833.5,607.5Q845,619 845,636Q845,653 833.5,664.5Q822,676 805,676ZM705,801Q688,801 676.5,789.5Q665,778 665,761Q665,744 676.5,732.5Q688,721 705,721Q722,721 733.5,732.5Q745,744 745,761Q745,778 733.5,789.5Q722,801 705,801Z" />
+</vector> \ No newline at end of file
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 6f6a357a4a95..322598574f26 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Plaaslike terminaal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktiveer terminaalprogram wat plaaslike skermtoegang bied"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-ontwikkelingomgewing"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Laat loop Linux-terminaal op Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimenteel) Laat Linux-terminale op Android loop"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"As jy deaktiveer, sal Linux se terminale data uitgevee word"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrolering"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Stel HDCP-kontrolering se gedrag"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Ontfouting"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Eksterne toestel"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Gekoppelde toestel"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Hierdie foon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AANVULLENDE"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan nie op hierdie toestel speel nie"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Gradeer rekening op om oor te skakel"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan nie aflaaie hier speel nie"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 4d7731c5dd45..34f37b47fae6 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"አካባቢያዊ ተርሚናል"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"የአካባቢያዊ ሼል መዳረሻ የሚያቀርብ የተርሚናል መተግበሪያ አንቃ"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"የLinux ግንባታ አከባቢ"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android ላይ Linux ተርሚናል ያሂዱ"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(የሙከራ) Android ላይ Linux ተርሚናል ያሂዱ"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ካሰናከሉ የLinux ተርሚናል ውሂብ ይሰርዛል"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"የHDCP ምልከታ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"የHDCP መመልከቻ ጠባይ አዘጋጅ"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ስህተት በማስወገድ ላይ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"የውጭ መሣሪያ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"የተገናኘ መሣሪያ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ይህ ስልክ"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"አናሎግ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ተጨማሪ"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"በዚህ መሣሪያ ላይ ማጫወት አልተቻለም"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ለመቀየር መለያ ያልቁ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ውርዶችን እዚህ ማጫወት አይቻልም"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 8b8131342b7d..2ea1486ace31 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"تطبيق طرفي محلي"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"تفعيل تطبيق طرفي يوفر إمكانية الدخول إلى واجهة النظام المحلية"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏بيئة تطوير نظام التشغيل Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏تشغيل محطة Linux الطرفية على Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(تجريبي) تشغيل تطبيق وحدة Linux الطرفية على Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏في حال إيقاف تطبيق وحدة Linux الطرفية، سيتم محو بياناتها"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏التحقق من HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تعيين سلوك التحقق من HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"تصحيح الأخطاء"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"جهاز خارجي"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"جهاز متّصل"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"هذا الهاتف"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"مصدر إخراج صوت تناظري"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"لا يمكن تشغيل الوسائط هنا"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"يجب ترقية الحساب للتبديل"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"المحتوى المنزَّل غير متوافق"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 02324de0276f..432d443a5045 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টাৰ্মিনেল"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শ্বেলৰ এক্সেছ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux বিকাশৰ পৰিৱেশ"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Androidত Linux টাৰ্মিনেল চলাওক"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(পৰীক্ষামূলক) Androidত Linux টাৰ্মিনেল চলাওক"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"আপুনি যদি অক্ষম কৰে, Linux টাৰ্মিনেলৰ ডেটা মচি পেলোৱা হ’ব"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পৰীক্ষণ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP পৰীক্ষণ আচৰণ ছেট কৰক"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"বাহ্যিক ডিভাইচ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"সংযোগ হৈ থকা ডিভাইচ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফ’নটো"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"এনালগ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"অক্স"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইচটো প্লে\' কৰিব নোৱাৰি"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"সলনি কৰিবলৈ একাউণ্ট আপগ্ৰে’ড কৰক"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ইয়াত ডাউনল’ডসমূহ প্লে’ কৰিব নোৱাৰি"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 25e85d53cdce..330532ec48b0 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Yerli terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Yerli örtük girişini təklif edən terminal tətbiqi aktiv edin"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux inkişaf mühiti"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-də Linux terminalını işə salın"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Təcrübi) Android-də Linux terminalını işlədin"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Deaktiv etsəniz, Linux terminal datası silinəcək"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP yoxlanışı"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP yoxlanışı qaydası ayalansın"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Sazlama"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Xarici cihaz"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Qoşulmuş cihaz"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoq"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oxutmaq olmur"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Keçirmək üçün hesabı güncəllə"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Burada endirmələri oxutmaq olmur"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4214a4016965..4dfd25302708 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući apl. terminala za pristup lokalnom komandnom okruženju"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux okruženje za programiranje"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Pokrenite Linux terminal na Android-u"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokrenite Linux terminal na Android-u"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako onemogućite, podaci Linux terminala se brišu"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provera"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Podešavanje ponašanja HDCP provere"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje grešaka"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Spoljni uređaj"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezani uređaj"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogni"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ne možete da pustite na ovom uređaju"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite nalog radi prebacivanja"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Preuzimanja ne mogu da se puštaju ovde"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 3e645b3f1ae0..de25460e4cbc 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Лакальны тэрмінал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Уключэнне прыкладання тэрмінала, якое прапануе доступ да лакальнай абалонкі"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Асяроддзе распрацоўкі Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Запусціць тэрмінал Linux на прыладзе Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"Запусціць тэрмінал Linux на прыладзе Android (эксперыментальная функцыя)"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Калі адключыць гэту функцыю, даныя тэрмінала Linux будуць сцёрты"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Праверка HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Усталяваць рэжым праверкі HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Адладка"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Знешняя прылада"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Падключаная прылада"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Гэты тэлефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналагавы"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не ўдаецца прайграць на гэтай прыладзе"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Для пераключэння перайдзіце на іншую версію ўліковага запісу"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Тут не ўдаецца прайграць спампоўкі"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8bdd17ebd861..47ce37cfc900 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Локален терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Актив. на прил. за терминал с достъп до локалния команден ред"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Среда на програмиране на Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Стартиране на терминала на Linux под Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Стартиране на терминала на Linux под Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако деактивир., данните в терминала на Linux ще бъдат изчистени"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка с HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Проверка с HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Отстраняване на грешки"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Външно устройство"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Свързано устройство"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Този телефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогов"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Възпроизвеждането не е възможно на това устройство"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Надстройте профила, за да превключите"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Изтеглянията не могат да се възпроизвеждат тук"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 834eb1eef1ce..3b77cfdae6b5 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টার্মিনাল"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শেল অ্যাক্সেসের প্রস্তাব করে এমন টার্মিনাল অ্যাপ্লিকেশন সক্ষম করুন"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ডেভেলপমেন্ট এনভায়র্নমেন্ট"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-এ Linux টার্মিনাল রান করান"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(পরীক্ষামূলক) Android-এ Linux টার্মিনাল চালান"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"আপনি বন্ধ করে দিলে, Linux টার্মিনাল ডেটা মুছে যাবে"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পরীক্ষণ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP চেক করার আচরণ সেট করুন"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ডিবাগিং"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"এক্সটার্নাল ডিভাইস"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"কানেক্ট থাকা ডিভাইস"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফোনটি"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"অ্যানালগ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইসে চালানো যাবে না"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"পাল্টাতে অ্যাকাউন্ট আপগ্রেড করুন"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"এতে ডাউনলোড করা কন্টেন্ট প্লে করা যাবে না"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 75fe8181489d..65eb6817f631 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxovo okruženje za razvoj"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Pokreni Linux terminal na Androidu"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokreni Linux terminal na Androidu"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako onemogućite ovo, podaci Linux terminala će se obrisati"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Postavke HDCP provjere"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje grešaka"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Vanjski uređaj"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezani uređaj"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogni"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nije moguće reproducirati na uređaju"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite račun da promijenite"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Nije moguće reproducirati preuzimanja ovdje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 2c41b1aee8ef..a7c3fafd48ef 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activa l\'aplicació de terminal que ofereix accés al shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorn de desenvolupament Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executa el terminal de Linux a Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executa el terminal de Linux a Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si desactives l\'app, les dades del terminal de Linux s\'esborraran"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprovació d\'HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Defineix comprovació HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuració"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositiu extern"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositiu connectat"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Aquest telèfon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analògic"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"No es pot reproduir en aquest dispositiu"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualitza el compte per canviar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Les baixades no es poden reproduir aquí"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index a4b491bfc1f0..832d320cd805 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Místní terminál"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivovat terminálovou aplikaci pro místní přístup k prostředí shell"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Vývojové prostředí Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Spustit na Androidu terminál Linux"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentální) Spustit terminál Linux na Androidu"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Při deaktivaci se vymažou data terminálu Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrola HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nastavit chování kontroly HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Ladění"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externí zařízení"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Připojené zařízení"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogové"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"V zařízení nelze přehrávat"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Účet je třeba upgradovat"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Stažený obsah zde nelze přehrát"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index f7402732299b..708d5df4c6b3 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivér terminalappen, der giver lokal shell-adgang"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-udviklingsmiljø"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Kør Linux-terminal i Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentelt) Kør Linux-terminal i Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Hvis du deaktiverer Linux-terminaldata, ryddes dataene."</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrol"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Angiv HDCP-kontroladfærd"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Fejlretning"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ekstern enhed"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Forbundet enhed"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke afspilles på denne enhed"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Opgrader kontoen for at skifte"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads kan ikke afspilles her"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index c8d8cb55de99..069201a63174 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokales Terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Terminal-App mit Zugriff auf lokale Shell aktivieren"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-Entwicklungsumgebung"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux-Terminal unter Android ausführen"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentell) Linux-Terminal unter Android ausführen"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Wenn du die Linux-Terminal App deaktivierst, werden die Daten darin gelöscht"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-Prüfung"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-Prüfverhalten festlegen"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -503,7 +504,7 @@
<string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Wird geladen"</string>
<string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – Vollständig geladen in <xliff:g id="TIME">%3$s</xliff:g>"</string>
<string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – Vollständig geladen in <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Vollständig geladen in <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Vollständig geladen um <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Vollständig geladen bis <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Unbekannt"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Wird aufgeladen"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externes Gerät"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Verbundenes Gerät"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Dieses Smartphone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Wiedergabe auf diesem Gerät nicht möglich"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Zum Umstellen Kontoupgrade durchführen"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads können hier nicht abgespielt werden"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index c773372790b4..8577a9a8acdf 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Τοπική τερματική εφαρμογή"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ενεργοπ.τερμ.εφαρμογής που προσφέρει πρόσβαση στο τοπικό κέλυφος"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Περιβάλλον ανάπτυξης Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Εκτέλεση τερματικού Linux σε Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Πειραματικό) Εκτέλεση τερματικού Linux σε Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Εάν απενεργοποιηθεί, τα δεδομένα τερματικού Linux θα διαγραφούν"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Έλεγχος HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ρύθμιση συμπεριφοράς ελέγχου HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Εντοπισμός σφαλμάτων"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Εξωτερική συσκευή"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Συνδεδεμένη συσκευή"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Αυτό το τηλέφ."</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Αναλογικός"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Δεν είναι δυνατή η αναπαραγωγή σε αυτήν τη συσκευή"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Αναβαθμίστε τον λογαριασμό για εναλλαγή"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Δεν είναι δυνατή η αναπαραγωγή των λήψεων εδώ"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8fe14350f3d9..f9d2f082b06c 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behaviour"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogue"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 0d560ea7c8b9..2cf98ef44c26 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behavior"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 8fe14350f3d9..f9d2f082b06c 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behaviour"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogue"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8fe14350f3d9..f9d2f082b06c 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux development environment"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Run Linux terminal on Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Run Linux terminal on Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"If you disable, Linux terminal data will be cleared"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Set HDCP checking behaviour"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External device"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Connected device"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogue"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 99dd4d9a56b9..a4834d887140 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicac. de terminal que ofrece acceso al shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorno de desarrollo de Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Ejecuta la terminal de Linux en Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Ejecuta la terminal de Linux en Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si lo inhabilitas, se borrarán los datos de la terminal de Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurar comportamiento de la comprobación HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
@@ -490,7 +491,7 @@
<string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> según el uso"</string>
<string name="power_discharge_by" msgid="4113180890060388350">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta la(s) <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es posible que la batería se agote para las <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir en este dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir las descargas aquí"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index cbbadd44d357..1792fd13a5f5 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicación de terminal que ofrece acceso a shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorno de desarrollo de Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Ejecuta un terminal de Linux en Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Ejecutar un terminal de Linux en Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si la inhabilitas, se borrarán los datos del terminal de Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación de HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Establecer comprobación HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"No se puede reproducir en este dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir descargas aquí"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 3c337933fbfb..5411d0bd30b5 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Kohalik terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Luba kohalikku turvalist juurdepääsu pakkuv terminalirakendus"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxi arenduskeskkond"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linuxi terminali käitamine Androidis"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Katseline) Linuxi terminal Androidis"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Keelamisel kustutatakse Linuxi terminali andmed"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrollimine"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP käitumise määramine"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Silumine"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Väline seade"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Ühendatud seade"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"See telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/SPDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Selles seadmes ei saa esitada"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Lülitamiseks täiendage kontot"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Siin ei saa allalaaditud faile esitada"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index c9947485e5f2..090d99d3b771 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Tokiko terminala"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Gaitu tokiko shell-sarbidea duen terminal-aplikazioa"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-eko garapen-ingurunea"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Exekutatu Linux-en terminala Android-en"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"Exekutatu Linux terminala Android-en (esperimentala)"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Desgaitzen baduzu, Linux-eko terminaleko datuak garbituko dira"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP egiaztapena"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ezarri HDCP egiaztapen-portaera"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Arazketa"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Kanpoko gailua"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Konektatutako gailua"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefono hau"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogikoa"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ezin da erreproduzitu gailu honetan"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Aldatzeko, bertsio-berritu kontua"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Deskargak ezin dira hemen erreproduzitu"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 75b805109824..c350175b788d 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ترمینال محلی"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"فعال کردن ترمینال برنامه‌ کاربردی که دسترسی به برنامه محلی را پیشنهاد می‌کند"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏محیط توسعه نرم‌افزار Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏اجرا کردن پایانه Linux در Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(آزمایشی) اجرا کردن «پایانه Linux» در Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏اگر پایانه Linux را غیرفعال کنید، داده‌های آن پاک خواهد شد"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏بررسی HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏تنظیم عملکرد بررسی HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"اشکال‌زدایی"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"دستگاه خارجی"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"دستگاه متصل"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"این تلفن"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"آنالوگ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"نمی‌توان در این دستگاه پخش کرد"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"برای تغییر، حساب را ارتقا دهید"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"نمی‌توان بارگیری‌ها را در اینجا پخش کرد"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 9cc33b013979..18a84b5f4ead 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Paikallinen pääte"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ota käyttöön päätesov. joka mahdollistaa paikall. liittymäkäytön"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-kehitysympäristö"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Käynnistä Linux-pääte Androidilla"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Kokeellinen) Käynnistä Linux-pääte Androidilla"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jos poistat tämän käytöstä, Linux-päätteen data tyhjennetään"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-tarkistus"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Aseta HDCP-tarkistus"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Vianetsintä"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ulkoinen laite"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Yhdistetty laite"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tämä puhelin"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoginen"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ei voi toistaa tällä laitteella"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Vaihda päivittämällä tili"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Latauksia ei voi toistaa täällä"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 28692d0afa55..066244a06620 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'appli Terminal permettant l\'accès au shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Environnement de développement Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Exécuter le terminal Linux sur Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Expérimental) Exécutez le terminal Linux sur Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"La désactivation effacera les données du terminal Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurer vérification HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Débogage"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Appareil externe"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Appareil connecté"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogique"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossible de faire jouer le contenu sur cet appareil"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à jour le compte pour passer à la version payante"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Lecture des téléchargements impossible ici"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 4e7abc938ccf..84c2f15b12e2 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Environnement de développement Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Exécuter le terminal Linux sur Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Version expérimentale) Exécuter le terminal Linux sur Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"La désactivation entraîne la suppression des données du terminal Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Config. vérification HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Débogage"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Appareil externe"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Appareil connecté"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogique"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossible de lire du contenu sur cet appareil"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à niveau le compte pour changer"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Impossible de lire les téléchargements ici"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index a4d3a0a4f751..d15b6e22e135 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activa a aplicación terminal que ofrece acceso ao shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Contorno de programación Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal de Linux en Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executa o terminal de Linux en Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desactivas a opción, borraranse os datos do terminal de Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Definir comprobación HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analóxica"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Non se pode reproducir contido neste dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Cambia a conta a un plan superior para facer a modificación"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Non se poden reproducir as descargas neste dispositivo"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 7a26463bc9bd..5fd187f06c3c 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"સ્થાનિક ટર્મિનલ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"સ્થાનિક શેલ અ‍ૅક્સેસની ઑફર કરતી ટર્મિનલ એપ્લિકેશનને સક્ષમ કરો"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ડેવલપમેન્ટ એન્વાયરમેન્ટ"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android પર Linux ટર્મિનલ ચલાવો"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(પ્રાયોગિક) Android પર Linux ટર્મિનલ ચલાવો"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Linux ટર્મિનલ ઍપને બંધ કરવાથી તેનો ડેટા સાફ કરવામાં આવશે"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP તપાસણી"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP તપાસણીની વર્તણૂક બદલો"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ડીબગિંગ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"બહારનું ડિવાઇસ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"કનેક્ટ કરેલું ડિવાઇસ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"આ ફોન"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"એનાલોગ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ઑગ્ઝિલરી"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"આ ડિવાઇસ પર ચલાવી શકતા નથી"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"સ્વિચ કરવા માટે એકાઉન્ટ અપગ્રેડ કરો"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ડાઉનલોડ કરેલું કન્ટેન્ટ અહીં ચલાવી શકતા નથી"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 83cb3989e909..fa0716e4ad22 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"स्थानीय टर्मिनल"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"लोकल शेल तक पहुंचने की सुविधा देने वाले टर्मिनल ऐप को चालू करें"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux डेवलपमेंट एनवायरमेंट"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android पर Linux का टर्मिनल ऐप्लिकेशन चलाएं"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(एक्सपेरिमेंट के तौर पर) Android पर Linux का टर्मिनल ऐप्लिकेशन चलाएं"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Linux टर्मिनल ऐप्लिकेशन को बंद करने पर, उसका डेटा मिट जाएगा"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जांच"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP जाँच व्‍यवहार सेट करें"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"डीबग करना"</string>
@@ -584,19 +585,16 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"अभी-अभी"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"यह फ़ोन"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यह टैबलेट"</string>
- <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"इस कंप्यूटर पर (इंटरनल)"</string>
+ <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"यह कंप्यूटर (इंटरनल)"</string>
<!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"डॉक स्पीकर"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाहरी डिवाइस"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"कनेक्ट किया गया डिवाइस"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"यह फ़ोन"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ऐनालॉग"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ऑक्स"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"इस डिवाइस पर मीडिया नहीं चलाया जा सकता"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"प्रीमियम खाते में स्विच करने के लिए, अपना खाता अपग्रेड करें"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड किए गए वीडियो यहां नहीं चलाए जा सकते"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index e78884d65538..8ad5c9d559d7 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući aplikaciju terminala koja nudi pristup lokalnoj ovojnici"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxovo razvojno okruženje"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Pokrenite Linux terminal na Androidu"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokreni Linux terminal na Androidu"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako to onemogućite, podaci Linux terminala će se izbrisati"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Postavke HDCP provjere"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Otklanjanje pogrešaka"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Vanjski uređaj"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezani uređaj"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogni"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ne može se reproducirati ovdje"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite i prebacite se"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ne može se tu reproducirati"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index ca18ac2e191f..18c6ea307651 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Helyi végpont"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Végalkalmazás engedélyezése a helyi rendszerhéj eléréséhez"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux fejlesztői környezet"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux-terminál futtatása Androidon"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Kísérleti) Linux-terminál futtatása Androidon"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Letiltás esetén törlődnek a Linux-terminál adatai"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-ellenőrzés"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-ellenőrzés beállítása"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Hibakeresés"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Külső eszköz"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Csatlakoztatott eszköz"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ez a telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analóg"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nem játszható le ezen az eszközön"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"A váltáshoz frissítse fiókját"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Itt nem játszhatók le a letöltések"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0749d6042b6b..593479a4c011 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Տեղային տերմինալ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Միացնել տերմինալային հավելվածը, որն առաջարկում է մուտք տեղային խեցի"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Լինուքսի մշակման միջավայր"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Գործարկել Լինուքս տերմինալը Android-ում"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"Գործարկել Լինուքս տերմինալը Android-ում (փորձնական)"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Եթե անջատեք, Լինուքս տերմինալի տվյալները կջնջվեն"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ստուգում"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-ի ստուգման կարգը"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Վրիպազերծում"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Արտաքին սարք"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Միացված սարք"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Այս հեռախոսը"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Անալոգային"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Հնարավոր չէ նվագարկել այս սարքում"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Փոխելու համար անցեք հաշվի պրեմիում տարբերակին"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ներբեռնումները չեն նվագարկվում այստեղ"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7d652c9db683..6522e22734b9 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal lokal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktifkan aplikasi terminal yang menawarkan akses kerangka lokal"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Lingkungan pengembangan Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Jalankan terminal Linux di Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimental) Jalankan terminal Linux di Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jika dinonaktifkan, data terminal Linux akan dihapus"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Pemeriksaan HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Setel perilaku pemeriksaan HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Proses debug"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Perangkat Eksternal"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Perangkat yang terhubung"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ponsel ini"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Tidak dapat memutar di perangkat ini"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade akun untuk beralih"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memutar hasil download di sini"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 67f4fe1b9562..4a10fb3e94d3 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Staðbundin skipanalína"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Virkja skipanalínuforrit sem leyfir staðbundinn skeljaraðgang"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Þróunarumhverfi Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Keyra Linux-útstöð í Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Á tilraunastigi) Keyrðu Linux-útstöð í Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ef þú slekkur á þessu verður gögnum í Linux-útstöð eytt"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-athugun"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Velja virkni HDCP-ath."</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Villuleit"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ytra tæki"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Tengt tæki"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Þessi sími"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Hliðrænt"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ekki er hægt að spila í þessu tæki"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppfærðu reikninginn til að skipta"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ekki er hægt að spila niðurhal hér"</string>
@@ -739,7 +737,7 @@
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Skipta um úttak"</string>
- <string name="back_navigation_animation" msgid="8105467568421689484">"Hreyfimyndir flýtiritunar við bendinguna „til baka“"</string>
+ <string name="back_navigation_animation" msgid="8105467568421689484">"Hreyfimyndir flýtiritunar við bendinguna „Til baka“"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Kveikja á hreyfimyndum í kerfinu til að sýna hreyfimyndir þegar bendingin „til baka“ er gerð."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Þessi stilling kveikir á hreyfimyndum í kerfinu til að sýna hreyfimyndir flýtiritunar með bendingum. Stillingin krefst þess að kveikt sé á enableOnBackInvokedCallback í upplýsingaskránni fyrir hvert forrit."</string>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 9f7f41b8b16f..21f78ddbdb72 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminale locale"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Abilita l\'app Terminale che offre l\'accesso alla shell locale"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente di sviluppo Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Esegui il terminale Linux su Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Sperimentale) Esegui il terminale Linux su Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se disattivi l\'opzione, i dati del terminale Linux verranno cancellati"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verifica HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Comportamento di verifica HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debug"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo esterno"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo connesso"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Questo smartphone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogico"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossibile riprodurre su questo dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Esegui l\'upgrade dell\'account per cambiare"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Qui non è possibile riprodurre i download"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 056aae170610..3b28bd2745e3 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"מסוף מקומי"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"הפעלה של אפליקציית מסוף המציעה גישה מקומית למעטפת"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏סביבת פיתוח של Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏הפעלת טרמינל Linux ב-Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(ניסיוני) הפעלת טרמינל Linux ב-Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏אם ההגדרה תושבת, הנתונים של טרמינל Linux יימחקו"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏בדיקת HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏הגדרת האופן של בדיקת HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ניפוי באגים"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"מכשיר חיצוני"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"המכשיר המחובר"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"הטלפון הזה"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"אנלוגי"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"לא ניתן להפעיל במכשיר"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"יש לשדרג חשבון כדי לעבור"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"לא ניתן להפעיל הורדות"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 833d1dcf4aef..a826810508e5 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ローカルターミナル"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ローカルシェルアクセスを提供するターミナルアプリを有効にします"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 開発環境"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android で Linux ターミナルを実行する"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(試験運用版)Android で Linux ターミナルを実行する"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"無効にすると、Linux ターミナルのデータが消去されます"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP チェック"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP チェック動作を設定"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"デバッグ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部デバイス"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"接続済みのデバイス"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"このデバイス"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"アナログ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"このデバイスでは再生できません"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"アカウントを更新して切り替えてください"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"再生不可: ダウンロードしたコンテンツ"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index acad174698fb..f321371a744e 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ადგილობრივი ტერმინალი"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ლოკალურ გარსზე წვდომის ტერმინალური აპლიკაციის ჩართვა"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-ის შემუშავების გარემო"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux ტერმინალის გაშვება Android-ზე"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ექსპერიმენტული) Linux ტერმინალის გაშვება Android-ზე"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"გათიშვის შემთხვევაში, წაიშლება Linux ტერმინალის მონაცემები"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP შემოწმება"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"დააყენე HDCP შემოწმების ქცევა"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"გამართვა"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"გარე მოწყობილობა"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"დაკავშირებული მოწყობილობა"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ეს ტელეფონი"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ანალოგური"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ამ მოწყობილობაზე დაკვრა შეუძლებელია"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"გადასართავად განაახლეთ ანგარიში"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"შეუძლებელია აქ ჩამოტვირ. თამაში"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index e2ce5b0e8ef3..85b86d4ef392 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Жергілікті терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Жергілікті шелл-код қол жетімділігін ұсынатын терминалды қолданбаны қосу"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux әзірлеуші ортасы"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-та Linux терминалын іске қосыңыз."</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Эксперименттік) Linux терминалын Android-та іске қосу"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Өшірсеңіз, Linux терминалының деректері өшіріледі."</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP тексерісі"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP (кең жолақты цифрлық контент қорғау) тексеру мүмкіндігін орнату"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Түзету"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Сыртқы құрылғы"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Жалғанған құрылғы"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Осы телефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогтік"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Осы құрылғыда ойнату мүмкін емес."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Ауысу үшін аккаунтты жаңартыңыз."</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Жүктеп алынғандарды осы жерде ойнату мүмкін емес."</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index c06aaeeb4bda..12d35cf78685 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ស្ថានីយ​មូលដ្ឋាន"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"បើក​កម្មវិធី​ស្ថានីយ​ដែល​ផ្ដល់​ការ​ចូល​សែល​មូលដ្ឋាន"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"មជ្ឈដ្ឋាន​អភិវឌ្ឍន៍ Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"ដំណើរការទែមីណាល់ Linux នៅលើ Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ពិសោធន៍) ដំណើរការទែមីណាល់ Linux នៅលើ Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ប្រសិនបើអ្នកបិទ ទិន្នន័យទែមីណាល់ Linux នឹងត្រូវបានសម្អាត"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"ពិនិត្យ HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"កំណត់​ឥរិយាបថ​ពិនិត្យ HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ការជួសជុល"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ឧបករណ៍ខាងក្រៅ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"​ឧបករណ៍ដែលបាន​ភ្ជាប់"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ទូរសព្ទនេះ"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"អាណាឡូក"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"មិនអាចចាក់នៅលើ​ឧបករណ៍នេះបានទេ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ដំឡើងកម្រិតគណនី ដើម្បីប្ដូរ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"មិនអាចចាក់ខ្លឹមសារដែលបានទាញយកនៅទីនេះបានទេ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 2c25501e60a7..d95846fba071 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿ"</string>
<string name="category_personal" msgid="6236798763159385225">"ವೈಯಕ್ತಿಕ"</string>
<string name="category_work" msgid="4014193632325996115">"ಕೆಲಸ"</string>
- <string name="category_private" msgid="4244892185452788977">"ಖಾಸಗಿ"</string>
+ <string name="category_private" msgid="4244892185452788977">"ಪ್ರೈವೆಟ್"</string>
<string name="category_clone" msgid="1554511758987195974">"ಕ್ಲೋನ್"</string>
<string name="development_settings_title" msgid="140296922921597393">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ಸ್ಥಳೀಯ ಟರ್ಮಿನಲ್"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ಸ್ಥಳೀಯ ಶೆಲ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುವ ಟರ್ಮಿನಲ್ ಆ್ಯಪ್‌ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ಡೆವಲಪ್‌ಮೆಂಟ್ ಎನ್ವಿರಾನ್‌ಮೆಂಟ್"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android ನಲ್ಲಿ Linux ಟರ್ಮಿನಲ್ ಅನ್ನು ರನ್ ಮಾಡಿ"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ಪ್ರಾಯೋಗಿಕ) Android ನಲ್ಲಿ Linux ಟರ್ಮಿನಲ್ ಅನ್ನು ರನ್ ಮಾಡಿ"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ನೀವು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದರೆ, Linux ಟರ್ಮಿನಲ್ ಡೇಟಾ ತೆರವುಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ಪರಿಶೀಲನಾ ನಡವಳಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ಬಾಹ್ಯ ಸಾಧನ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"ಕನೆಕ್ಟ್ ಮಾಡಿರುವ ಸಾಧನ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ಈ ಫೋನ್"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ಅನಲಾಗ್"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ಈ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ಬದಲಾಯಿಸಲು ಖಾತೆಯನ್ನು ಅಪ್‌ಗ್ರೇಡ್ ಮಾಡಿ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ಇಲ್ಲಿ ಡೌನ್‌ಲೋಡ್‌ಗಳನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f7dc6ae8603d..f82a6a6ec442 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"로컬 터미널"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"로컬 셸 액세스를 제공하는 터미널 앱 사용"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 개발 환경"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android에서 Linux 터미널 실행"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(실험용) Android에서 Linux 터미널 실행"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"사용 중지하면 Linux 터미널 데이터가 삭제됩니다."</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 확인"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP 확인 동작 설정"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"디버깅"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"외부 기기"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"연결된 기기"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"이 휴대전화"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"아날로그"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"이 기기에서 재생할 수 없음"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"계정을 업그레이드하여 전환하기"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"여기서 다운로드한 콘텐츠를 재생할 수 없습니다."</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 6105db0bf071..ff63c1922940 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"Профиль тандоо"</string>
<string name="category_personal" msgid="6236798763159385225">"Жеке"</string>
<string name="category_work" msgid="4014193632325996115">"Жумуш"</string>
- <string name="category_private" msgid="4244892185452788977">"Купуя"</string>
+ <string name="category_private" msgid="4244892185452788977">"Жеке профиль"</string>
<string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Иштеп чыгуучунун параметрлери"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Иштеп чыгуучунун параметрлерин иштетүү"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Жергиликтүү терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Жергиликтүү буйрук кабыгын сунуштаган терминалга уруксат берүү"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux иштеп чыгуу чөйрөсү"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android\'де Linux терминалын иштетүү"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Cынамык) Linux терминалын Android\'де иштетүү"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Эгер өчүрүп койсоңуз, Linux терминалынын маалыматы тазаланат"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP текшерүү"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP текшерүү тартиби"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Мүчүлүштүктөрдү аныктоо"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Тышкы түзмөк"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Туташкан түзмөк"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ушул телефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналог"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"КШМЧ"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Бул түзмөктө ойнотууга болбойт"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Премиум аккаунтка которулуу керек"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Жүктөлүп алынгандар ойнотулбайт"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index df3689e72249..36d2ccf041db 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal ໃນໂຕເຄື່ອງ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ເປີດນຳໃຊ້ແອັບຯ Terminal ທີ່ໃຫ້ການເຂົ້າເຖິງ shell ໃນໂຕເຄື່ອງໄດ້"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"ສະພາບແວດລ້ອມໃນການພັດທະນາ Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"ເອີ້ນໃຊ້ເທີມິນອນ Linux ຢູ່ Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ເປັນການທົດລອງ) ເອີ້ນໃຊ້ເທີມິນອນ Linux ຢູ່ Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ຫາກທ່ານປິດການນຳໃຊ້, ລະບົບຈະລຶບລ້າງຂໍ້ມູນເທີມິນອນ Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"ການກວດສອບ HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"ຕັ້ງວິທີການກວດສອບ HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ການດີບັກ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ອຸປະກອນພາຍນອກ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"ອຸປະກອນທີ່ເຊື່ອມຕໍ່"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ໂທລະສັບນີ້"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ໂມງເຂັມ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ຫຼິ້ນຢູ່ອຸປະກອນນີ້ບໍ່ໄດ້"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ອັບເກຣດບັນຊີເພື່ອສະຫຼັບ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ບໍ່ສາມາດຫຼິ້ນເນື້ອຫາທີ່ດາວໂຫຼດຢູ່ນີ້ໄດ້"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 4d9858733f86..5b20db3cd464 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Vietinis terminalas"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Įgal. terminalo progr., siūlančią prieigą prie viet. apvalkalo"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"„Linux“ kūrimo aplinka"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"„Linux“ terminalo paleidimas sistemoje „Android“"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentas) „Linux“ terminalo paleidimas sistemoje „Android“"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jei išjungsite, „Linux“ terminalo duomenys bus išvalyti"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP tikrinimas"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nust. HDCP tikrin. elgs."</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Derinimas"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Išorinis įrenginys"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Prijungtas įrenginys"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis telefonas"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoginis"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Negalima leisti šiame įrenginyje"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Jei norite perjungti, naujovinkite paskyrą"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Čia negalima paleisti atsisiuntimų"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 582982673441..620318a08f18 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -235,9 +235,9 @@
<item msgid="6946761421234586000">"400%"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Profila izvēlēšanās"</string>
- <string name="category_personal" msgid="6236798763159385225">"Privāts"</string>
+ <string name="category_personal" msgid="6236798763159385225">"Personīgais"</string>
<string name="category_work" msgid="4014193632325996115">"Darba"</string>
- <string name="category_private" msgid="4244892185452788977">"Privāti"</string>
+ <string name="category_private" msgid="4244892185452788977">"Privāts"</string>
<string name="category_clone" msgid="1554511758987195974">"Klons"</string>
<string name="development_settings_title" msgid="140296922921597393">"Izstrādātāju opcijas"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Izstrādātāju opciju iespējošana"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Vietējā beigu lietotne"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Iespējot beigu lietotni, kurā piedāvāta vietējā čaulas piekļuve"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux izstrādes vide"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Palaist Linux termināli Android ierīcē"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentāls) Palaist Linux termināli Android ierīcē"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ja atspējosiet, Linux termināļa dati tiks notīrīti"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP pārbaude"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP pārb. iestatīšana"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Atkļūdošana"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ārēja ierīce"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Pievienotā ierīce"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis tālrunis"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogā"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nevar atskaņot šajā ierīcē."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Lai pārslēgtu, jauniniet kontu"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Šeit nevar atskaņot lejupielādes"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 5d5d480ecd68..0331ece3c4dc 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -235,9 +235,9 @@
<item msgid="6946761421234586000">"400 %"</item>
</string-array>
<string name="choose_profile" msgid="343803890897657450">"Изберете профил"</string>
- <string name="category_personal" msgid="6236798763159385225">"Лично"</string>
+ <string name="category_personal" msgid="6236798763159385225">"Личен"</string>
<string name="category_work" msgid="4014193632325996115">"Работа"</string>
- <string name="category_private" msgid="4244892185452788977">"Приватно"</string>
+ <string name="category_private" msgid="4244892185452788977">"Приватен"</string>
<string name="category_clone" msgid="1554511758987195974">"Клон"</string>
<string name="development_settings_title" msgid="140296922921597393">"Програмерски опции"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Овозможете ги програмерските опции"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Локален терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Овозможи апликација на терминал што овозможува локален пристап кон школка."</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Програмерска околина на Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Извршување Linux-терминал на Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Вклучете го Linux-терминалот на Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако оневозможите, податоците за Linux-терминалот ќе се избришат"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка со HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Постави однесување на проверка на HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Отстранување грешки"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Надворешен уред"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Поврзан уред"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Овој телефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогно"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не може да се пушти на уредов"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Надградете ја сметката за да се префрлите"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Не може да се пуштаат преземања тука"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 71406232cb64..aaebe4cd6abf 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"പ്രാദേശിക ടെർമിനൽ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"പ്രാദേശിക ഷെൽ ആക്‌സസ് നൽകുന്ന ടെർമിനൽ അപ്ലിക്കേഷൻ പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ഡെവലപ്പ്മെന്റ് എൻവയോൺമെന്റ്"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android-ൽ Linux ടെർമിനൽ പ്രവർത്തിപ്പിക്കുക"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(പരീക്ഷണാത്മകം) Android-ൽ Linux ടെർമിനൽ റൺ ചെയ്യുക"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"പ്രവർത്തനരഹിതമാക്കുകയാണെങ്കിൽ, Linux ടെർമിനൽ ഡാറ്റ മായ്ക്കും"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP പരിശോധന"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ചെക്കിംഗ്‌രീതി സജ്ജമാക്കുക"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ഡീബഗ്ഗിംഗ്"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ബാഹ്യ ഉപകരണം"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"കണക്‌റ്റ് ചെയ്‌ത ഉപകരണം"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ഈ ഫോൺ"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"അനലോഗ്"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ഈ ഉപകരണത്തിൽ പ്ലേ ചെയ്യാൻ കഴിയില്ല"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"അക്കൗണ്ട് മാറാൻ അപ്‌ഗ്രേഡ് ചെയ്യുക"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ഡൗൺലോഡുകൾ പ്ലേ ചെയ്യാനാകില്ല"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index c9e0178ce54f..fb2b7291bb88 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Локал терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Локал суурьт хандалт хийх боломж олгодог терминалын апп-г идэвхжүүлэх"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-н хөгжүүлэлтийн орчин"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android дээр Linux терминалыг ажиллуулах"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Туршилтын) Android дээр Linux терминалыг ажиллуулах"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Хэрэв та идэвхгүй болговол Linux терминалын өгөгдлийг арилгана"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP шалгах"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP шалгах авирыг тохируулах"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Дебаг"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Гадаад төхөөрөмж"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Холбогдсон төхөөрөмж"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Энэ утас"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Aналог"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"НЭМЭЛТ"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Энэ төхөөрөмжид тоглуулах боломжгүй"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Сэлгэхийн тулд бүртгэлийг сайжруулна уу"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Татаж авсан файлыг энд тоглуулах боломжгүй"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a6596cdf7d0c..023a2e47e8f3 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"स्थानिक टर्मिनल"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"स्थानिक शेल प्रवेश देणारा टर्मिनल अ‍ॅप सुरू करा"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux विकास पर्यावरण"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android वर Linux टर्मिनल रन करा"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(प्रायोगिक) Android वर Linux टर्मिनल रन करा"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"तुम्ही Linux टर्मिनल बंद केल्यास, डेटा साफ केला जाईल"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP तपासणी"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP तपासणी वर्तन सेट करा"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"डीबग करणे"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाह्य डिव्हाइस"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"कनेक्ट केलेले डिव्हाइस"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"हा फोन"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"अ‍ॅनालॉग"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"या डिव्हाइसवर प्ले करू शकत नाही"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"स्विच करण्यासाठी खाते अपग्रेड करा"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"येथे डाउनलोड प्ले केले जाऊ शकत नाहीत"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index ebde3319a806..4212eb49f2cf 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal setempat"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Dayakan apl terminal yang menawarkan akses shell tempatan"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Persekitaran pembangunan Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Terminal Run Linux pada Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Percubaan) Jalankan terminal Linux pada Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jika dilumpuhkan, data terminal Linux akan dikosongkan"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Penyemakan HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ttpkn tngkh laku smk HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Menyahpepijat"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Peranti Luar"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Peranti yang disambungkan"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefon ini"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Tidak dapat dimainkan pada peranti ini"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Tingkatkan akaun untuk beralih"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memainkan muat turun di sini"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 1131007fe1bd..df13e6c5f33e 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"လိုကယ်တာမီနယ်"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"local shell အသုံးပြုခွင့်ကမ်းလှမ်းသော တာမင်နယ်အပလီကေးရှင်းဖွင့်ပါ"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ဆော့ဖ်ဝဲရေးမှု ပတ်ဝန်းကျင်"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android တွင် Linux တာမီနယ် လုပ်ဆောင်ရန်"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(စမ်းသပ်) Android တွင် Linux တာမီနယ်ကို လုပ်ဆောင်ရန်"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ပိတ်လိုက်ပါက Linux တာမီနယ်ဒေတာကို ရှင်းထုတ်ပါမည်"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP စစ်ဆေးမှု"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP စစ်ဆေးပုံကို သတ်မှတ်မည်"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"အမှားရှာဖွေဖယ်ရှားခြင်း"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ပြင်ပစက်"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"ချိတ်ဆက်ကိရိယာ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ဤဖုန်း"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ရိုးရိုး"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ဤစက်ပစ္စည်းတွင် ဖွင့်၍မရပါ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ပြောင်းရန် အကောင့်အဆင့်ကိုမြှင့်ပါ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ဤနေရာတွင် ဒေါင်းလုဒ်များ ဖွင့်မရပါ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 1a71ec07457e..812666350505 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktiver terminalappen som gir lokal kommandolistetilgang"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-utviklingsmiljø"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Kjør Linux-terminal på Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(På forsøksstadiet) Kjør Linux-terminal på Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Hvis du slår av dette, slettes Linux-terminaldataene"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontroll"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Angi HDPC-kontrolladferd"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Feilsøking"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Ekstern enhet"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Tilkoblet enhet"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefonen"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke spille på denne enheten"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Oppgrader kontoen for å bytte"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan ikke spille av nedlastinger her"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index dea9fcce87cf..a233622362b8 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -167,7 +167,7 @@
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"कम्प्युटर"</string>
<string name="bluetooth_talkback_headset" msgid="3406852564400882682">"हेडसेट"</string>
<string name="bluetooth_talkback_phone" msgid="868393783858123880">"फोन"</string>
- <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"छवि सम्बन्धी"</string>
+ <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"फोटो सम्बन्धी"</string>
<string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"हेडफोन"</string>
<string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"इनपुट सम्बन्धी बाह्य यन्त्र"</string>
<string name="bluetooth_talkback_hearing_aids" msgid="3983279945542595479">"हियरिङ डिभाइसहरू"</string>
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"प्रोफाइल रोज्नुहोस्"</string>
<string name="category_personal" msgid="6236798763159385225">"व्यक्तिगत"</string>
<string name="category_work" msgid="4014193632325996115">"काम"</string>
- <string name="category_private" msgid="4244892185452788977">"निजी"</string>
+ <string name="category_private" msgid="4244892185452788977">"निजी स्पेस"</string>
<string name="category_clone" msgid="1554511758987195974">"क्लोन"</string>
<string name="development_settings_title" msgid="140296922921597393">"विकासकर्ताका विकल्पहरू"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"विकासकर्ता विकल्प सक्रिया गर्नुहोस्"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"स्थानीय टर्मिनल"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"स्थानीय सेल पहुँच प्रदान गर्ने टर्मिनल एप सक्षम गर्नुहोस्"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux डेभलप्मेन्ट इन्भायरमेन्ट"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android मा Linux टर्मिनल एप प्रयोग गर्नुहोस्"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(परीक्षणको चरणमा रहेको) Android मा Linux टर्मिनल रन गर्नुहोस्"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"तपाईंले Linux टर्मिनल डिसएबल गर्नुभयो भने त्यसमा भएको डेटा मेटिने छ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जाँच"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP जाँच व्यवहार सेट गर्नुहोस्"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"डिबग गरिँदै छ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"बाह्य डिभाइस"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"कनेक्ट गरिएको डिभाइस"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"यो फोन"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"एनालग"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"यो डिभाइसमा मिडिया प्ले गर्न मिल्दैन"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"आफूले प्रयोग गर्न चाहेको खाता अपग्रेड गर्नुहोस्"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड गरिएका सामग्री यसमा प्ले गर्न मिल्दैन"</string>
@@ -713,7 +711,7 @@
<string name="data_connection_lte" msgid="7675461204366364124">"LTE"</string>
<string name="data_connection_lte_plus" msgid="6643158654804916653">"LTE+"</string>
<string name="data_connection_carrier_wifi" msgid="8932949159370130465">"W+"</string>
- <string name="cell_data_off_content_description" msgid="2280700839891636498">"मोबाइल डेटा निष्क्रिय छ"</string>
+ <string name="cell_data_off_content_description" msgid="2280700839891636498">"मोबाइल डेटा अफ छ"</string>
<string name="not_default_data_content_description" msgid="6517068332106592887">"डेटा प्रयोग गर्ने गरी सेट गरिएन"</string>
<string name="accessibility_no_phone" msgid="2687419663127582503">"फोन छैन्।"</string>
<string name="accessibility_phone_one_bar" msgid="5719721147018970063">"फोन एउटा पट्टि।"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index e3be50736a88..551097d9e442 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokale terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Terminal-app aanzetten die lokale shell-toegang biedt"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-ontwikkelomgeving"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Linux-terminal uitvoeren op Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimenteel) Linux-terminal uitvoeren op Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Als je dit uitzet, worden Linux-terminalgegevens gewist"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-controle"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-controlegedrag instellen"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Foutopsporing"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Extern apparaat"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Verbonden apparaat"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Deze telefoon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan niet afspelen op dit apparaat"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade het account om te schakelen"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan hier geen downloads afspelen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index ea6fdba27506..790acffe2b80 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ସ୍ଥାନୀୟ ଟର୍ମିନାଲ୍‌"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ସ୍ଥାନୀୟ ଶେଲ୍‌କୁ ଆକ‌ସେସ୍‌ ଦେଉଥିବା ଟର୍ମିନଲ୍‌ ଆପ୍‌କୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ଡେଭେଲପମେଣ୍ଟର ପରିବେଶ"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Androidରେ Linux ଟର୍ମିନାଲ ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ପରୀକ୍ଷାମୂଳକ) Androidରେ Linux ଟର୍ମିନାଲ ଚଲାନ୍ତୁ"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ଯଦି ଆପଣ ଅକ୍ଷମ କରନ୍ତି, ତେବେ Linux ଟର୍ମିନାଲ ଡାଟା ଖାଲି ହୋଇଯିବ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ଯାଞ୍ଚ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCPର ଯାଞ୍ଚ ଗତିବିଧି ସେଟ୍‍ କରନ୍ତୁ"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ଡିବଗ୍‌ କରୁଛି"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ଏକ୍ସଟର୍ନଲ ଡିଭାଇସ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"କନେକ୍ଟ କରାଯାଇଥିବା ଡିଭାଇସ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ଏହି ଫୋନ୍"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ଆନାଲଗ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ଅକ୍ସିଲାରି"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ଏହି ଡିଭାଇସରେ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ସ୍ୱିଚ କରିବା ପାଇଁ ଆକାଉଣ୍ଟକୁ ଅପଗ୍ରେଡ କରନ୍ତୁ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ଏଠାରେ ଡାଉନଲୋଡଗୁଡ଼ିକୁ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 853405167e01..c20e0d88ee3f 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"ਸਥਾਨਕ ਟਰਮੀਨਲ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ਟਰਮੀਨਲ ਐਪ ਨੂੰ ਚਾਲੂ ਕਰੋ ਜੋ ਸਥਾਨਕ ਸ਼ੈਲ ਪਹੁੰਚ ਪੇਸ਼ਕਸ਼ ਕਰਦਾ ਹੈ"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux ਵਿਕਾਸ ਵਾਤਾਵਰਨ"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android \'ਤੇ Linux ਦੀ ਟਰਮੀਨਲ ਐਪ ਚਲਾਓ"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ਪ੍ਰਯੋਗਮਈ) Android \'ਤੇ Linux ਟਰਮੀਨਲ ਚਲਾਓ"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ਜੇ ਤੁਸੀਂ ਬੰਦ ਕਰਦੇ ਹੋ, ਤਾਂ Linux ਟਰਮੀਨਲ ਡਾਟਾ ਕਲੀਅਰ ਹੋ ਜਾਵੇਗਾ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ਜਾਂਚ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ਜਾਂਚ ਵਿਵਹਾਰ ਸੈੱਟ ਕਰੋ"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ਡੀਬੱਗਿੰਗ"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ਬਾਹਰੀ ਡੀਵਾਈਸ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"ਕਨੈਕਟ ਕੀਤਾ ਡੀਵਾਈਸ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ਇਹ ਫ਼ੋਨ"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ਐਨਾਲੌਗ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"ਸਵਿੱਚ ਕਰਨ ਲਈ ਖਾਤੇ ਨੂੰ ਅੱਪਗ੍ਰੇਡ ਕਰੋ"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ਡਾਊਨਲੋਡਾਂ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index a9d4dcbf577a..f6ab8a7c19a4 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal lokalny"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Włącz terminal, który umożliwia dostęp do powłoki lokalnej"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Środowisko programistyczne Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Uruchom terminal Linux na Androidzie"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Wersja eksperymentalna) Uruchom terminal Linuxa na Androidzie"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Jeśli wyłączysz tę funkcję, dane terminala Linuxa będą usunięte"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Sprawdzanie HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Ustaw sprawdzanie HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Debugowanie"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Urządzenie zewnętrzne"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Połączone urządzenie"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ten telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogowe"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nie można odtworzyć na tym urządzeniu"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Aby przełączyć, potrzebujesz konta premium"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tutaj nie można odtworzyć pobranych plików"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index eac646ff4c10..dedc65c1369f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar o app terminal que oferece acesso ao shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente de desenvolvimento do Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal Linux no Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executar terminal Linux no Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desativar o app, os dados do terminal Linux serão removidos"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Config. a verificação HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuração"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Neste telefone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Faça upgrade da conta para trocar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível abrir os downloads aqui"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index d8d172d25192..f1ac88bdda40 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar aplicação terminal que oferece acesso local à shell"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente de programação Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal do Linux no Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executar terminal do Linux no Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desativar a app, os dados do terminal do Linux são limpos"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Definir o comportamento da verificação HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuração"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo associado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Atualize a conta para mudar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível reproduzir as transferências aqui"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index eac646ff4c10..dedc65c1369f 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar o app terminal que oferece acesso ao shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambiente de desenvolvimento do Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Executar terminal Linux no Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Executar terminal Linux no Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Se desativar o app, os dados do terminal Linux serão removidos"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Config. a verificação HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuração"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Neste telefone"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Faça upgrade da conta para trocar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível abrir os downloads aqui"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index d507b8526c8d..cafb7881a32a 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Aplicație terminal locală"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activează aplicația terminal care oferă acces la shell local"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Mediu de dezvoltare Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Rulează Linux terminal pe Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Rulează terminalul Linux pe Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Dacă dezactivezi, datele terminalului Linux vor fi șterse"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificare HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurează verif. HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depanare"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispozitiv extern"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispozitiv conectat"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Acest telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogic"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nu se poate reda pe acest dispozitiv"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Fă upgrade contului pentru a comuta"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Aici nu se pot reda descărcări"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 8d07c57fec56..951f3a0dd146 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Локальный терминальный доступ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Разрешить терминальный доступ к локальной оболочке"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Среда разработки Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Запустить терминал Linux в Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"Запустить терминал Linux в Android (экспериментальная функция)"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Если отключить эту функцию, данные терминала Linux будут удалены"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Порядок проверки HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Отладка"</string>
@@ -584,19 +585,16 @@
<string name="time_unit_just_now" msgid="3006134267292728099">"Только что"</string>
<string name="media_transfer_this_device_name" msgid="2357329267148436433">"Этот смартфон"</string>
<string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Этот планшет"</string>
- <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Встроенный динамик компьютера"</string>
+ <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"Встроенное"</string>
<!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
<skip />
<string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Колонка с док-станцией"</string>
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Внешнее устройство"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Подключенное устройство"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Этот смартфон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналоговый выход"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Невозможно воспроизвести на этом устройстве."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Для переключения требуется премиум-аккаунт"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Не удается воспроизвести скачанные файлы"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 6694bc552e11..8427064b99ef 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"පැතිකඩ තෝරන්න"</string>
<string name="category_personal" msgid="6236798763159385225">"පෞද්ගලික"</string>
<string name="category_work" msgid="4014193632325996115">"කාර්යාලය"</string>
- <string name="category_private" msgid="4244892185452788977">"පෞද්ගලික"</string>
+ <string name="category_private" msgid="4244892185452788977">"රහසිගත"</string>
<string name="category_clone" msgid="1554511758987195974">"ක්ලෝන කරන්න"</string>
<string name="development_settings_title" msgid="140296922921597393">"වර්ධක විකල්ප"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"සංවර්ධක විකල්ප සබල කිරීම"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"අභ්‍යන්තර අන්තය"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"දේශීය ෂෙල් ප්‍රවේශනය පිරිනමන ටර්මිනල් යෙදුම සබල කරන්න"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux සංවර්ධන පරිසරය"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android මත Linux ටර්මිනලය ධාවනය කරන්න"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(පර්යේෂණාත්මක) Android මත Linux ටර්මිනලය ධාවනය කරන්න"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ඔබ අබල කරන්නේ නම්, Linux ටර්මිනල් දත්ත හිස් වනු ඇත"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP පරික්ෂාව"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP පරික්ෂා හැසිරීම සකසන්න"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"නිදොස්කරණය"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"බාහිර උපාංගය"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"සම්බන්ධ කළ උපාංගය"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"මෙම දුරකථනය"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ප්‍රතිසමය"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"මෙම උපාංගය මත ධාවනය කළ නොහැක"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"මාරු වීමට ගිණුම උත්ශ්‍රේණි කරන්න"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"මෙහි බාගැනීම් වාදනය කළ නොහැක"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index fa525a20ca66..aca07e5a32c3 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Miestny terminál"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Povoliť terminálovú apl. na miestny prístup k prostrediu shell"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Vývojové prostredie Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Spúšťanie terminálu systému Linux v Androide"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentálne) Spúšťať terminál systému Linux v Androide"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ak túto možnosť vypnete, údaje terminálu systému Linux sa vymažú"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrola HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nastaviť spôsob kontroly HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Ladenie"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externé zariadenie"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Pripojené zariadenie"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefón"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógový"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"V tomto zariadení sa nedá prehrávať obsah"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Inovujte účet a prejdite naň"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tu sa nedajú prehrať stiahnuté súbory"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 9b426aa27e19..00d93a65d2f1 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogočanje terminalske aplikacije za dostop do lokalne lupine"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Razvojno okolje Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Zagon terminala Linux v Androidu"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Preizkusno) Zagon terminala Linux v Androidu"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Če to onemogočite, bodo podatki terminala Linux izbrisani."</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Preverjanje HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Nastavi preverjanje HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Odpravljanje napak"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Zunanja naprava"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Povezana naprava"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ta telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogno"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ni mogoče predvajati v tej napravi."</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Za preklop je potrebna nadgradnja računa"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Prenosov tu ni mogoče predvajati"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 73cc518dac0a..c907e22c7784 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminali lokal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivizo aplikacionin terminal që ofron qasje në guaskën lokale"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Ambienti i zhvillimit për Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Ekzekuto terminalin e Linux në Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentale) Ekzekuto terminalin e Linux në Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Nëse e çaktivizon, të dhënat e terminalit të Linux do të pastrohen"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrolli HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Cakto kontrollin e HDCP-së"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Korrigjimi i gabimeve"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Pajisja e jashtme"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Pajisja e lidhur"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ky telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoge"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Nuk mund të luhet në këtë pajisje"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Përmirëso llogarinë për të ndryshuar"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Shkarkimet nuk mund të luhen këtu"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index d8003d75bd4e..65000e468fea 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Локални терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Омогући апл. терминала за приступ локалном командном окружењу"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux окружење за програмирање"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Покрените Linux терминал на Android-у"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментално) Покрените Linux терминал на Android-у"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ако онемогућите, подаци Linux терминала се бришу"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP провера"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Подешавање понашања HDCP провере"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Отклањање грешака"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Спољни уређај"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Повезани уређај"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Овај телефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогни"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не можете да пустите на овом уређају"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Надоградите налог ради пребацивања"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Преузимања не могу да се пуштају овде"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f9bd295253a6..12c17290bf15 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivera en terminalapp som ger åtkomst till hyllor lokalt"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux-utvecklingsmiljö"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Kör Linux-terminalen på Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimentellt) Kör Linux-terminalen på Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Om du inaktiverar detta rensas data i Linux-terminalen"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontroll"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Konfigurera HDCP-kontroll"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Felsökning"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Extern enhet"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Ansluten enhet"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Den här telefonen"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan inte spelas på denna enhet"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppgradera kontot för att byta"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Det går inte att spela upp nedladdningar här"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index b86be31ec352..1bf5677668ca 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Kituo cha karibu"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Washa programu ya mwisho inayotoa ufikiaji mkuu wa karibu"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Mazingira ya usanidi wa Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Tumia temino ya Linux kwenye Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Ya majaribio) Tumia temino ya Linux kwenye Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ukizima, data ya kituo cha Linux itafutwa"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Inakagua HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Weka HDCP ya kukagua tabia"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Utatuzi"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Kifaa cha Nje"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Kifaa kilichounganishwa"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Simu hii"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogi"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Huwezi kucheza maudhui kwenye kifaa hiki"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Pata toleo jipya la akaunti ili ubadilishe"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Imeshindwa kucheza maudhui yaliyopakuliwa hapa"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 1fd78d3842eb..8ee8fa22c61f 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"அக முனையம்"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"அக ஷெல் அணுகலை வழங்கும் இறுதிப் ஆப்ஸை இயக்கு"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux டெவெலப்மெண்ட் சூழல்"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Androidல் Linux டெர்மினலை இயக்கும்"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(பரிசோதனை) Androidடில் Linux டெர்மினலை இயக்கலாம்"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"நீங்கள் முடக்கினால், Linux டெர்மினல் தரவு அழிக்கப்படும்"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP சரிபார்ப்பு"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP சரிபார்க்கும் செயல்பாடுகளை அமை"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"பிழைதிருத்தம்"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"வெளிப்புறச் சாதனம்"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"இணைக்கப்பட்டுள்ள சாதனம்"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"இந்த மொபைல்"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"அனலாக்"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"இந்தச் சாதனத்தில் பிளே செய்ய முடியவில்லை"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"மாற்ற, கணக்கை மேம்படுத்துங்கள்"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"பதிவிறக்கங்களை இங்கே பிளே செய்ய முடியாது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index fc45d2c8e149..46350d5bf30c 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"స్థానిక టెర్మినల్"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"స్థానిక షెల్ యాక్సెస్‌ను అందించే టెర్మినల్ యాప్‌ను ప్రారంభించండి"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux డెవలప్మెంట్ ఎన్విరాన్మెంట్"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Androidలో Linux టెర్మినల్‌ను రన్ చేయండి"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ప్రయోగాత్మకం) Linux టెర్మినల్‌ను Androidలో రన్ చేయండి"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"మీరు డిజేబుల్ చేస్తే, Linux టెర్మినల్ డేటా క్లియర్ అవుతుంది"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP చెకింగ్‌"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP తనిఖీ ప్రవర్తనను సెట్ చేయండి"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"డీబగ్గింగ్"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"ఎక్స్‌టర్నల్ పరికరం"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"కనెక్ట్ చేసిన పరికరం"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"ఈ ఫోన్"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"అనలాగ్"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"ఈ పరికరంలో ప్లే చేయడం సాధ్యపడదు"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"మారడానికి ఖాతాను అప్‌గ్రేడ్ చేయండి"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ఇక్కడ డౌన్‌లోడ్‌లను ప్లే చేయడం సాధ్యపడదు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index d525bc538ef8..460782af8457 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"เทอร์มินัลในตัวเครื่อง"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"เปิดใช้งานแอปเทอร์มินัลที่ให้การเข้าถึงเชลล์ในตัวเครื่อง"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"เรียกใช้เทอร์มินัล Linux บน Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ทดลอง) เรียกใช้เทอร์มินัล Linux ใน Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"หากปิดใช้ ระบบจะล้างข้อมูลเทอร์มินัล Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"การตรวจสอบ HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"ตั้งค่าการตรวจสอบ HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"การแก้ไขข้อบกพร่อง"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"อุปกรณ์ภายนอก"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"อุปกรณ์ที่เชื่อมต่อ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"โทรศัพท์เครื่องนี้"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"แอนะล็อก"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"เล่นในอุปกรณ์นี้ไม่ได้"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"อัปเกรดบัญชีเพื่อเปลี่ยน"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"เล่นเนื้อหาที่ดาวน์โหลดที่นี่ไม่ได้"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 1df74736d879..986b7771d9f5 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal na terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Paganahin ang terminal app na nag-aalok ng lokal na shell access"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Development environment ng Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Paganahin ang Linux terminal sa Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Pang-eksperimento) Patakbuhin ang terminal ng Linux sa Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Kung idi-disable mo, maki-clear ang data ng terminal ng Linux"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Pagsusuring HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP checking behavior"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Pagde-debug"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"External na Device"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Nakakonektang device"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Ang teleponong ito"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Hindi ma-play sa device na ito"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"I-upgrade ang account para lumipat"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Hindi mape-play ang mga download dito"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index d62269605e84..df47dacc7d7b 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Yerel terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Yerel kabuk erişimi sunan terminal uygulamasını etkinleştir"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux geliştirme ortamı"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android\'de Linux terminali çalıştırın"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Deneysel) Android\'de Linux terminali çalıştırın"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Devre dışı bırakırsanız Linux terminali verileri temizlenir"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP denetimi"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP denetimini ayarla"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Hata ayıklama"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Harici Cihaz"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Bağlı cihaz"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu cihazda oynatılamıyor"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Geçiş yapmak için hesabı yükseltin"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"İndirilenler burada oynatılamaz"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index eb10cb209c20..3ba99a2f443e 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Локальний термінал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Увімк. програму-термінал, що надає локальний доступ до оболонки"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Середовище Linux для розробки"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Запуск термінала Linux на Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Експериментальна функція) Запуск термінала Linux на Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Якщо вимкнути, дані термінала Linux буде видалено"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Перевірка HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Порядок перевірки HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Налагодження"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Зовнішній пристрій"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Підключений пристрій"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Цей телефон"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналоговий"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Не можна відтворювати тут"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Потрібний платний обліковий запис"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Завантаження не відтворюватимуться"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 8b2eb3fb0189..e5e29faae8f5 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -237,7 +237,7 @@
<string name="choose_profile" msgid="343803890897657450">"پروفائل منتخب کریں"</string>
<string name="category_personal" msgid="6236798763159385225">"ذاتی"</string>
<string name="category_work" msgid="4014193632325996115">"دفتر"</string>
- <string name="category_private" msgid="4244892185452788977">"نجی"</string>
+ <string name="category_private" msgid="4244892185452788977">"پرائیویٹ"</string>
<string name="category_clone" msgid="1554511758987195974">"کلون کریں"</string>
<string name="development_settings_title" msgid="140296922921597393">"ڈویلپر کے اختیارات"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"ڈویلپر کے اختیارات فعال کریں"</string>
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"مقامی ٹرمینل"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"مقامی شیل رسائی پیش کرنے والی ٹرمینل ایپ فعال کریں"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"‏‫Linux ڈیولپمنٹ ماحول"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"‏‫Android پر Linux ٹرمینل چلائیں"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"‏(تجرباتی) Android پر Linux ٹرمینل چلائیں"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"‏اگر آپ غیر فعال کرتے ہیں تو Linux ٹرمینل کا ڈیٹا صاف ہو جائے گا"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏HDCP چیکنگ"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"‏HDCP چیکنگ برتاؤ سیٹ کریں"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"ڈیبگ کرنا"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"بیرونی آلہ"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"منسلک آلہ"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"یہ فون"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"اینالاگ"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"اس آلے پر چلایا نہیں جا سکتا"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"سوئچ کرنے کے لیے اکاؤنٹ اپ گریڈ کریں"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ڈاؤن لوڈز کو یہاں چلایا نہیں جا سکتا"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 62a6303fd45b..2417d5556bee 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Mahalliy terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Mahalliy terminalga kirishga ruxsat beruvchi terminal ilovani faollashtirish"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux dasturlash muhiti"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Android orqali Linux terminalini ishga tushirish"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Tajribaviy) Linux terminalini Android tizimida ishga tushiring"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Agar faolsizlantirsangiz, Linux terminal maʼlumotlari tozalanadi"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP tekshiruvi"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCPni tekshirish tartibi"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Nosozliklarni tuzatish"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Tashqi qurilma"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Ulangan qurilma"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Shu telefon"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Bu qurilmada ijro etilmaydi"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Oʻtish uchun hisobingizni yangilang"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Yuklab olingan fayllar ijro etilmaydi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 1b90818fbaf9..0239a3f2c39d 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Dòng lệnh cục bộ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Bật ứng dụng dòng lệnh cung cấp quyền truy cập vỏ cục bộ"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Môi trường phát triển Linux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Chạy thiết bị đầu cuối Linux trên Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Thử nghiệm) Chạy cửa sổ dòng lệnh Linux trên Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Nếu bạn tắt, dữ liệu trên cửa sổ dòng lệnh Linux sẽ bị xoá"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kiểm tra HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Đặt hành vi kiểm tra HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Gỡ lỗi"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Thiết bị bên ngoài"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Thiết bị đã kết nối"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Điện thoại này"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Không phát được trên thiết bị này"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Nâng cấp tài khoản để chuyển đổi"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Không thể phát các tệp đã tải xuống tại đây"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 94915650223f..22bfda4fe6fc 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"本地终端"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"启用终端应用,以便在本地访问 Shell"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 开发环境"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"在 Android 上运行 Linux 终端"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(实验性)在 Android 上运行 Linux 终端"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"如果您停用它,Linux 终端数据会被清除"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 检查"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"设置 HDCP 检查行为"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"调试"</string>
@@ -490,7 +491,7 @@
<string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"根据您的使用情况,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by" msgid="4113180890060388350">"目前电量为 <xliff:g id="LEVEL">%2$s</xliff:g>,估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_discharge_by_only" msgid="92545648425937000">"估计能用到<xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_only_short" msgid="5883041507426914446">"可以用到 <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_only_short" msgid="5883041507426914446">"可用到 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"电池电量可能在<xliff:g id="TIME">%1$s</xliff:g> 前耗尽"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"剩余电池续航时间不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部设备"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"连接的设备"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"这部手机"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"模拟"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"辅助"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"无法在此设备上播放"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"升级账号后才能切换"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"无法在此设备上播放下载的内容"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index aa3ac06298c5..594273a327ce 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"本機終端機"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 開發環境"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"在 Android 上執行 Linux 終端機"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(實驗性質) 在 Android 上執行 Linux 終端機"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"停用將清除 Linux 終端機資料"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"設定 HDCP 檢查行為"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"除錯"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部裝置"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"已連接的裝置"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"這部手機"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"類比"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"無法在此裝置上播放"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"請升級要切換的帳戶"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"無法在此播放下載內容"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index b5eb87da6de3..483dbf30b31c 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"本機終端機"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linux 開發環境"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"在 Android 上執行 Linux 終端機"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(實驗功能) 在 Android 上執行 Linux 終端機"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"如果停用,系統會清除 Linux 終端機資料"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"設定 HDCP 檢查行為"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"偵錯"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"外部裝置"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"已連結的裝置"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"這支手機"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"類比"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"無法在這部裝置上播放"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"請升級要切換的帳戶"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"這裡無法播放下載內容"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 57e0b8d8afeb..2bb3f225565e 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -358,7 +358,8 @@
<string name="enable_terminal_title" msgid="3834790541986303654">"Itheminali yasendaweni"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Nika amandla uhlelo lokusebenza letheminali olunikeza ukufinyelela kwasendaweni kwe-shell"</string>
<string name="enable_linux_terminal_title" msgid="5076044866895670637">"Indawo yokuthuthukiswa yeLinux"</string>
- <string name="enable_linux_terminal_summary" msgid="5893216510985145320">"Sebenzisa itheminali yeLinux ku-Android"</string>
+ <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Ukuhlola) Qalisa itheminali yeLinux ku-Android"</string>
+ <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Uma ukhubazekile, idatha egciniwe yeLinux izosuswa"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Ihlola i-HDCP"</string>
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Hlela ukuhlola ukuziphatha kwe-HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Ilungisa inkinga"</string>
@@ -591,12 +592,9 @@
<string name="media_transfer_external_device_name" msgid="2588672258721846418">"Idivayisi Yangaphandle"</string>
<string name="media_transfer_default_device_name" msgid="4315604017399871828">"Idivayisi exhunyiwe"</string>
<string name="media_transfer_this_phone" msgid="7194341457812151531">"Le foni"</string>
- <!-- no translation found for media_transfer_digital_line_name (312091711951124301) -->
- <skip />
- <!-- no translation found for media_transfer_analog_line_name (1841163866716302104) -->
- <skip />
- <!-- no translation found for media_transfer_aux_line_name (894135835967856689) -->
- <skip />
+ <string name="media_transfer_digital_line_name" msgid="312091711951124301">"I-S/PDIF"</string>
+ <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"I-Analog"</string>
+ <string name="media_transfer_aux_line_name" msgid="894135835967856689">"I-AUX"</string>
<string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ayikwazi ukudlala kule divayisi"</string>
<string name="media_output_status_require_premium" msgid="8411255800047014822">"Thuthukisa i-akhawunti ukuze ushintshe"</string>
<string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Awukwazi ukudlala okudawunilodiwe lapha"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java
index c0117b952beb..30ce13bf3b00 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppIconCacheManager.java
@@ -22,6 +22,7 @@ import android.os.UserHandle;
import android.util.Log;
import android.util.LruCache;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
/**
@@ -33,7 +34,7 @@ public class AppIconCacheManager {
@VisibleForTesting
static final int MAX_CACHE_SIZE_IN_KB = getMaxCacheInKb();
private static final String DELIMITER = ":";
- private static AppIconCacheManager sAppIconCacheManager;
+ private static volatile AppIconCacheManager sAppIconCacheManager;
private final LruCache<String, Drawable> mDrawableCache;
private AppIconCacheManager() {
@@ -52,11 +53,18 @@ public class AppIconCacheManager {
/**
* Get an {@link AppIconCacheManager} instance.
*/
- public static synchronized AppIconCacheManager getInstance() {
- if (sAppIconCacheManager == null) {
- sAppIconCacheManager = new AppIconCacheManager();
+ public static @NonNull AppIconCacheManager getInstance() {
+ AppIconCacheManager result = sAppIconCacheManager;
+ if (result == null) {
+ synchronized (AppIconCacheManager.class) {
+ result = sAppIconCacheManager;
+ if (result == null) {
+ result = new AppIconCacheManager();
+ sAppIconCacheManager = result;
+ }
+ }
}
- return sAppIconCacheManager;
+ return result;
}
/**
@@ -118,7 +126,7 @@ public class AppIconCacheManager {
*
* @see android.content.ComponentCallbacks2#onTrimMemory(int)
*/
- public void trimMemory(int level) {
+ public static void trimMemory(int level) {
if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
// Time to clear everything
if (sAppIconCacheManager != null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index d0827b30efc9..4eb0567c67d9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -133,8 +133,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
* If an ACTION_UUID intent comes in within
* MAX_UUID_DELAY_FOR_AUTO_CONNECT milliseconds, we will try auto-connect
* again with the new UUIDs
+ * The value is reset if a manual disconnection happens.
*/
- private long mConnectAttempted;
+ private long mConnectAttempted = -1;
// Active device state
private boolean mIsActiveDeviceA2dp = false;
@@ -369,6 +370,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
public void disconnect() {
+ mConnectAttempted = -1;
synchronized (mProfileLock) {
if (getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
for (CachedBluetoothDevice member : getMemberDevice()) {
@@ -983,15 +985,19 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
if (BluetoothUtils.D) {
- Log.d(TAG, "onUuidChanged: Time since last connect="
- + (SystemClock.elapsedRealtime() - mConnectAttempted));
+ long lastConnectAttempted = mConnectAttempted == -1 ? 0 : mConnectAttempted;
+ Log.d(
+ TAG,
+ "onUuidChanged: Time since last connect/manual disconnect="
+ + (SystemClock.elapsedRealtime() - lastConnectAttempted));
}
/*
* If a connect was attempted earlier without any UUID, we will do the connect now.
* Otherwise, allow the connect on UUID change.
*/
- if ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
+ if (mConnectAttempted != -1
+ && (mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
Log.d(TAG, "onUuidChanged: triggering connectDevice");
connectDevice();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index dc52b4dafd9b..b52ed42d567f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -1217,12 +1217,13 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
}
}
}
+ Log.d(TAG, "updateFallbackActiveDeviceIfNeeded, earliest group id = " + targetGroupId);
return targetGroupId;
}
@Nullable
private CachedBluetoothDevice getMainDevice(@Nullable List<BluetoothDevice> devices) {
- if (devices == null || devices.size() == 1) return null;
+ if (devices == null || devices.isEmpty()) return null;
List<CachedBluetoothDevice> cachedDevices =
devices.stream()
.map(device -> mDeviceManager.findDevice(device))
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 3530e0f5f9de..8e7180c4dc8d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -78,6 +78,7 @@ public class SystemSettings {
Settings.System.SHOW_WEB_SUGGESTIONS,
Settings.System.SIP_CALL_OPTIONS,
Settings.System.SIP_RECEIVE_CALLS,
+ Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
Settings.System.POINTER_SPEED,
Settings.System.POINTER_FILL_STYLE,
Settings.System.POINTER_STROKE_STYLE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index c90ba8249d54..32d4580f67ec 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -464,5 +464,14 @@ public class GlobalSettingsValidators {
));
VALIDATORS.put(Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, ANY_STRING_VALIDATOR);
VALIDATORS.put(Global.HEARING_DEVICE_LOCAL_NOTIFICATION, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(
+ Global.Wearable.WEAR_SYSTEM_STATUS_TRAY_CONFIGURATION,
+ new DiscreteValueValidator(
+ new String[] {
+ String.valueOf(
+ Global.Wearable.STATUS_TRAY_CONFIGURATION_DEFAULT),
+ String.valueOf(
+ Global.Wearable.STATUS_TRAY_CONFIGURATION_SYSTEM_HIDDEN)
+ }));
}
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 509b88b257fe..cfc7743f0a8d 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -213,6 +213,8 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.SIP_ADDRESS_ONLY, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SIP_ASK_ME_EACH_TIME, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.POINTER_SPEED, new InclusiveFloatRangeValidator(-7, 7));
+ VALIDATORS.put(System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
+ NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(System.POINTER_FILL_STYLE,
new InclusiveIntegerRangeValidator(POINTER_ICON_VECTOR_STYLE_FILL_BEGIN,
POINTER_ICON_VECTOR_STYLE_FILL_END));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
index 0b7181606247..b0086c180cbd 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
+++ b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
@@ -1 +1,2 @@
-per-file WritableNamespacePrefixes.java = cbrubaker@google.com,tedbauer@google.com
+per-file WritableNamespacePrefixes.java = mpgroover@google.com,tedbauer@google.com
+per-file WritableNamespaces.java = mpgroover@google.com,tedbauer@google.com
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index fb0aaf8e5ae1..600c36e5dfc9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -3037,6 +3037,9 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.System.TOUCHPAD_TAP_DRAGGING,
SystemSettingsProto.Touchpad.TAP_DRAGGING);
+ dumpSetting(s, p,
+ Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION,
+ SystemSettingsProto.Touchpad.THREE_FINGER_TAP_CUSTOMIZATION);
p.end(touchpadToken);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 603a91195d04..03fea37deaf5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2434,28 +2434,40 @@ public class SettingsProvider extends ContentProvider {
context.checkCallingOrSelfPermission(
Manifest.permission.WRITE_DEVICE_CONFIG)
== PackageManager.PERMISSION_GRANTED;
- boolean isRoot = Binder.getCallingUid() == Process.ROOT_UID;
+ // Only the shell user and tests request the allowlist permission; this is used to force
+ // the WRITE_ALLOWLISTED_DEVICE_CONFIG path to log any flags that need to be allowlisted.
+ boolean isRestrictedShell = android.security.Flags.protectDeviceConfigFlags()
+ && hasAllowlistPermission;
- if (isRoot) {
- return;
- }
-
- if (hasWritePermission) {
+ if (!isRestrictedShell && hasWritePermission) {
assertCallingUserDenyList(flags);
} else if (hasAllowlistPermission) {
for (String flag : flags) {
boolean namespaceAllowed = false;
- for (String allowlistedPrefix : WritableNamespacePrefixes.ALLOWLIST) {
- if (flag.startsWith(allowlistedPrefix)) {
+ if (isRestrictedShell) {
+ int delimiterIndex = flag.indexOf("/");
+ String flagNamespace;
+ if (delimiterIndex != -1) {
+ flagNamespace = flag.substring(0, delimiterIndex);
+ } else {
+ flagNamespace = flag;
+ }
+ if (WritableNamespaces.ALLOWLIST.contains(flagNamespace)) {
namespaceAllowed = true;
- break;
+ }
+ } else {
+ for (String allowlistedPrefix : WritableNamespacePrefixes.ALLOWLIST) {
+ if (flag.startsWith(allowlistedPrefix)) {
+ namespaceAllowed = true;
+ break;
+ }
}
}
if (!namespaceAllowed && !DeviceConfig.getAdbWritableFlags().contains(flag)) {
- throw new SecurityException("Permission denial for flag '"
- + flag
- + "'; allowlist permission granted, but must add flag to the allowlist.");
+ Slog.wtf(LOG_TAG, "Permission denial for flag '" + flag
+ + "'; allowlist permission granted, but must add flag to the "
+ + "allowlist");
}
}
assertCallingUserDenyList(flags);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
new file mode 100644
index 000000000000..d835c5f5c179
--- /dev/null
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.settings;
+
+import android.util.ArraySet;
+
+import java.util.Arrays;
+import java.util.Set;
+
+/**
+ * Contains the list of namespaces in which any flag can be written by adb without root
+ * permissions.
+ * <p>
+ * A security review is required for any namespace that's added to this list. To add to
+ * the list, create a change and tag the OWNER. In the commit message, include a
+ * description of the flag's functionality, and a justification for why it needs to be
+ * allowlisted.
+ */
+final class WritableNamespaces {
+ public static final Set<String> ALLOWLIST =
+ new ArraySet<String>(Arrays.asList(
+ "exo"
+ ));
+}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 9de7faf04df6..a62b7fd3db81 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -635,7 +635,8 @@ public class SettingsBackupTest {
Settings.Global.Wearable.WEAR_MEDIA_SESSIONS_PACKAGE,
Settings.Global.Wearable.WEAR_POWER_ANOMALY_SERVICE_ENABLED,
Settings.Global.Wearable.CONNECTIVITY_KEEP_DATA_ON,
- Settings.Global.Wearable.PHONE_SWITCHING_REQUEST_SOURCE);
+ Settings.Global.Wearable.PHONE_SWITCHING_REQUEST_SOURCE,
+ Settings.Global.Wearable.WEAR_SYSTEM_STATUS_TRAY_CONFIGURATION);
private static final Set<String> BACKUP_DENY_LIST_SECURE_SETTINGS =
newHashSet(
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 526320debb1a..ac02af81420c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -179,6 +179,7 @@
<uses-permission android:name="android.permission.SET_ORIENTATION" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGE_UPDATES" />
+ <uses-permission android:name="android.permission.INSTALL_DEPENDENCY_SHARED_LIBRARIES" />
<uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP" />
<uses-permission android:name="android.permission.INSTALL_DPC_PACKAGES" />
<uses-permission android:name="com.android.permission.USE_INSTALLER_V2" />
@@ -242,6 +243,8 @@
<uses-permission android:name="android.permission.READ_LOWPAN_CREDENTIAL" />
<uses-permission android:name="android.permission.BLUETOOTH_STACK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.COPY_ACCOUNTS" />
+ <uses-permission android:name="android.permission.REMOVE_ACCOUNTS" />
<uses-permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN" />
<uses-permission android:name="android.permission.FRAME_STATS" />
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
@@ -746,6 +749,9 @@
<!-- Permission required for ATS test - CarDevicePolicyManagerTest -->
<uses-permission android:name="android.permission.LOCK_DEVICE" />
+ <!-- Permission required for AuthenticationPolicyManagerTest -->
+ <uses-permission android:name="android.permission.MANAGE_SECURE_LOCK_DEVICE" />
+
<!-- Permissions required for CTS test - CtsSafetyCenterTestCases -->
<uses-permission android:name="android.permission.SEND_SAFETY_CENTER_UPDATE" />
<uses-permission android:name="android.permission.READ_SAFETY_CENTER_STATUS" />
@@ -932,7 +938,6 @@
<!-- Permission required for CTS test - CtsPackageManagerTestCases-->
<uses-permission android:name="android.permission.DOMAIN_VERIFICATION_AGENT" />
- <uses-permission android:name="android.permission.VERIFICATION_AGENT" />
<!-- Permission required for Cts test - CtsInputTestCases -->
<uses-permission
@@ -951,15 +956,15 @@
<!-- Permission required for CTS test - CtsNfcTestCases -->
<uses-permission android:name="android.permission.NFC_SET_CONTROLLER_ALWAYS_ON" />
<!-- Permission required for CTS test - AdvancedProtectionManagerTest -->
- <uses-permission android:name="android.permission.SET_ADVANCED_PROTECTION_MODE"
+ <uses-permission android:name="android.permission.MANAGE_ADVANCED_PROTECTION_MODE"
android:featureFlag="android.security.aapm_api"/>
<uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE"
android:featureFlag="android.security.aapm_api"/>
- <!-- Permission required for CTS test - ForensicManagerTest -->
- <uses-permission android:name="android.permission.READ_FORENSIC_STATE"
+ <!-- Permission required for CTS test - IntrusionDetectionManagerTest -->
+ <uses-permission android:name="android.permission.READ_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
- <uses-permission android:name="android.permission.MANAGE_FORENSIC_STATE"
+ <uses-permission android:name="android.permission.MANAGE_INTRUSION_DETECTION_STATE"
android:featureFlag="android.security.afl_api"/>
@@ -969,7 +974,7 @@
<!-- Permission required for CTS test - CtsTelephonyTestCases -->
<uses-permission android:name="android.permission.READ_BASIC_PHONE_STATE" />
- <!-- Permission required for ExecutableMethodFileOffsetsTest -->
+ <!-- Permission required for CTS test - CtsDynamicInstrumentationManagerTest -->
<uses-permission android:name="android.permission.DYNAMIC_INSTRUMENTATION" />
<!-- Permissions required for CTS test - SettingsPreferenceServiceClientTest -->
diff --git a/packages/Shell/aconfig/wear.aconfig b/packages/Shell/aconfig/wear.aconfig
index e07bd963a4aa..d88fd46cb68d 100644
--- a/packages/Shell/aconfig/wear.aconfig
+++ b/packages/Shell/aconfig/wear.aconfig
@@ -5,5 +5,5 @@ flag {
name: "handle_bugreports_for_wear"
namespace: "wear_services"
description: "This flag enables Shell to propagate bugreport results to WearServices."
- bug: "378060870"
+ bug: "338029043"
} \ No newline at end of file
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 67666c3db81f..3541742e2bb7 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1780,6 +1780,16 @@ flag {
}
flag {
+ name: "notification_reentrant_dismiss"
+ namespace: "systemui"
+ description: "Posts to avoid a crashing reentrant pipeline run"
+ bug: "328328054"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "stoppable_fgs_system_app"
namespace: "systemui"
description: "System app with foreground service can opt in to be stoppable."
@@ -1798,3 +1808,31 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "gsf_bouncer"
+ namespace: "systemui"
+ description: "Applies GSF font styles to Bouncer surfaces."
+ bug: "379364381"
+}
+
+flag {
+ name: "gsf_quick_settings"
+ namespace: "systemui"
+ description: "Applies GSF font styles to Quick Settings surfaces."
+ bug: "379364381"
+}
+
+flag {
+ name: "glanceable_hub_shortcut_button"
+ namespace: "systemui"
+ description: "Adds a shortcut button to lockscreen to show glanceable hub."
+ bug: "378173531"
+}
+
+flag {
+ name: "spatial_model_launcher_pushback"
+ namespace: "systemui"
+ description: "Implement the depth push scaling effect on Launcher when users pull down shade."
+ bug: "370562309"
+}
diff --git a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java
index 2b5ff7c4b598..0f5e3679cc5f 100644
--- a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java
+++ b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java
@@ -44,6 +44,7 @@ import java.util.List;
/**
* An implementation of {@link IRemoteTransition} that accepts a {@link UIComponent} as the origin
* and automatically attaches it to the transition leash before the transition starts.
+ *
* @hide
*/
public class OriginRemoteTransition extends IRemoteTransition.Stub {
@@ -258,8 +259,7 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {
// The transition didn't start. Ensure we apply the start transaction and report
// finish afterwards.
mStartTransaction
- .addTransactionCommittedListener(
- mContext.getMainExecutor(), this::finishInternal)
+ .addTransactionCommittedListener(mHandler::post, this::finishInternal)
.apply();
return;
}
@@ -268,8 +268,7 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {
mPlayer.onEnd(finished);
// Detach the origin from the transition leash and report finish after it's done.
mOriginTransaction
- .detachFromTransitionLeash(
- mOrigin, mContext.getMainExecutor(), this::finishInternal)
+ .detachFromTransitionLeash(mOrigin, mHandler::post, this::finishInternal)
.commit();
}
@@ -329,7 +328,9 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {
/* baseBounds= */ maxBounds);
}
- /** An interface that represents an origin transitions.
+ /**
+ * An interface that represents an origin transitions.
+ *
* @hide
*/
public interface TransitionPlayer {
diff --git a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
index 4c047d589a66..9cef43c3deba 100644
--- a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
+++ b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
@@ -38,6 +38,7 @@ import java.util.concurrent.Executor;
* be changed to INVISIBLE in its view tree. This allows the {@link View} to transform in the
* full-screen size leash without being constrained by the view tree's boundary or inheriting its
* parent's alpha and transformation.
+ *
* @hide
*/
public class ViewUIComponent implements UIComponent {
@@ -98,9 +99,7 @@ public class ViewUIComponent implements UIComponent {
mView.getViewTreeObserver().addOnDrawListener(mOnDrawListener);
// Make the view invisible AFTER the surface is shown.
- t.addTransactionCommittedListener(
- mView.getContext().getMainExecutor(),
- () -> mView.setVisibility(View.INVISIBLE))
+ t.addTransactionCommittedListener(mView::post, () -> mView.setVisibility(View.INVISIBLE))
.apply();
}
@@ -118,7 +117,7 @@ public class ViewUIComponent implements UIComponent {
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.reparent(sc, null)
.addTransactionCommittedListener(
- mView.getContext().getMainExecutor(),
+ mView::post,
() -> {
s.release();
sc.release();
@@ -235,41 +234,40 @@ public class ViewUIComponent implements UIComponent {
mView.post(this::draw);
}
- /**
- * @hide
- */
+ /** @hide */
public static class Transaction implements UIComponent.Transaction<ViewUIComponent> {
private final List<Runnable> mChanges = new ArrayList<>();
@Override
public Transaction setAlpha(ViewUIComponent ui, float alpha) {
- mChanges.add(() -> ui.setAlpha(alpha));
+ mChanges.add(() -> ui.mView.post(() -> ui.setAlpha(alpha)));
return this;
}
@Override
public Transaction setVisible(ViewUIComponent ui, boolean visible) {
- mChanges.add(() -> ui.setVisible(visible));
+ mChanges.add(() -> ui.mView.post(() -> ui.setVisible(visible)));
return this;
}
@Override
public Transaction setBounds(ViewUIComponent ui, Rect bounds) {
- mChanges.add(() -> ui.setBounds(bounds));
+ mChanges.add(() -> ui.mView.post(() -> ui.setBounds(bounds)));
return this;
}
@Override
public Transaction attachToTransitionLeash(
ViewUIComponent ui, SurfaceControl transitionLeash, int w, int h) {
- mChanges.add(() -> ui.attachToTransitionLeash(transitionLeash, w, h));
+ mChanges.add(
+ () -> ui.mView.post(() -> ui.attachToTransitionLeash(transitionLeash, w, h)));
return this;
}
@Override
public Transaction detachFromTransitionLeash(
ViewUIComponent ui, Executor executor, Runnable onDone) {
- mChanges.add(() -> ui.detachFromTransitionLeash(executor, onDone));
+ mChanges.add(() -> ui.mView.post(() -> ui.detachFromTransitionLeash(executor, onDone)));
return this;
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
index addabcc0282a..a137891f2d01 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
@@ -34,66 +34,60 @@ private const val FONT_ITALIC_MIN = 0f
private const val FONT_ITALIC_ANIMATION_STEP = 0.1f
private const val FONT_ITALIC_DEFAULT_VALUE = 0f
-// Benchmarked via Perfetto, difference between 10 and 50 entries is about 0.3ms in
-// frame draw time on a Pixel 6.
-@VisibleForTesting const val DEFAULT_FONT_CACHE_MAX_ENTRIES = 10
+/** Caches for font interpolation */
+interface FontCache {
+ val animationFrameCount: Int
-/** Provide interpolation of two fonts by adjusting font variation settings. */
-class FontInterpolator(
- numberOfAnimationSteps: Int? = null,
-) {
- /**
- * Cache key for the interpolated font.
- *
- * This class is mutable for recycling.
- */
- private data class InterpKey(var l: Font?, var r: Font?, var progress: Float) {
- fun set(l: Font, r: Font, progress: Float) {
- this.l = l
- this.r = r
- this.progress = progress
- }
- }
+ fun get(key: InterpKey): Font?
- /**
- * Cache key for the font that has variable font.
- *
- * This class is mutable for recycling.
- */
- private data class VarFontKey(
- var sourceId: Int,
- var index: Int,
- val sortedAxes: MutableList<FontVariationAxis>
- ) {
- constructor(
- font: Font,
- axes: List<FontVariationAxis>
- ) : this(
- font.sourceIdentifier,
- font.ttcIndex,
- axes.toMutableList().apply { sortBy { it.tag } }
- )
-
- fun set(font: Font, axes: List<FontVariationAxis>) {
- sourceId = font.sourceIdentifier
- index = font.ttcIndex
- sortedAxes.clear()
- sortedAxes.addAll(axes)
- sortedAxes.sortBy { it.tag }
- }
- }
+ fun get(key: VarFontKey): Font?
+
+ fun put(key: InterpKey, font: Font)
+
+ fun put(key: VarFontKey, font: Font)
+}
+
+/** Cache key for the interpolated font. */
+data class InterpKey(val start: Font?, val end: Font?, val frame: Int)
+
+/** Cache key for the font that has variable font. */
+data class VarFontKey(val sourceId: Int, val index: Int, val sortedAxes: List<FontVariationAxis>) {
+ constructor(
+ font: Font,
+ axes: List<FontVariationAxis>,
+ ) : this(font.sourceIdentifier, font.ttcIndex, axes.sortedBy { it.tag })
+}
+class FontCacheImpl(override val animationFrameCount: Int = DEFAULT_FONT_CACHE_MAX_ENTRIES / 2) :
+ FontCache {
// Font interpolator has two level caches: one for input and one for font with different
// variation settings. No synchronization is needed since FontInterpolator is not designed to be
// thread-safe and can be used only on UI thread.
- val cacheMaxEntries = numberOfAnimationSteps?.let { it * 2 } ?: DEFAULT_FONT_CACHE_MAX_ENTRIES
+ val cacheMaxEntries = animationFrameCount * 2
private val interpCache = LruCache<InterpKey, Font>(cacheMaxEntries)
private val verFontCache = LruCache<VarFontKey, Font>(cacheMaxEntries)
- // Mutable keys for recycling.
- private val tmpInterpKey = InterpKey(null, null, 0f)
- private val tmpVarFontKey = VarFontKey(0, 0, mutableListOf())
+ override fun get(key: InterpKey): Font? = interpCache[key]
+ override fun get(key: VarFontKey): Font? = verFontCache[key]
+
+ override fun put(key: InterpKey, font: Font) {
+ interpCache.put(key, font)
+ }
+
+ override fun put(key: VarFontKey, font: Font) {
+ verFontCache.put(key, font)
+ }
+
+ companion object {
+ // Benchmarked via Perfetto, difference between 10 and 50 entries is about 0.3ms in frame
+ // draw time on a Pixel 6.
+ @VisibleForTesting const val DEFAULT_FONT_CACHE_MAX_ENTRIES = 10
+ }
+}
+
+/** Provide interpolation of two fonts by adjusting font variation settings. */
+class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
/** Linear interpolate the font variation settings. */
fun lerp(start: Font, end: Font, progress: Float): Font {
if (progress == 0f) {
@@ -111,13 +105,12 @@ class FontInterpolator(
// Check we already know the result. This is commonly happens since we draws the different
// text chunks with the same font.
- tmpInterpKey.set(start, end, progress)
- val cachedFont = interpCache[tmpInterpKey]
- if (cachedFont != null) {
+ val iKey = InterpKey(start, end, (progress * fontCache.animationFrameCount).toInt())
+ fontCache.get(iKey)?.let {
if (DEBUG) {
- Log.d(LOG_TAG, "[$progress] Interp. cache hit for $tmpInterpKey")
+ Log.d(LOG_TAG, "[$progress] Interp. cache hit for $iKey")
}
- return cachedFont
+ return it
}
// General axes interpolation takes O(N log N), this is came from sorting the axes. Usually
@@ -131,14 +124,14 @@ class FontInterpolator(
MathUtils.lerp(
startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
- progress
+ progress,
)
TAG_ITAL ->
adjustItalic(
MathUtils.lerp(
startValue ?: FONT_ITALIC_DEFAULT_VALUE,
endValue ?: FONT_ITALIC_DEFAULT_VALUE,
- progress
+ progress,
)
)
else -> {
@@ -152,32 +145,31 @@ class FontInterpolator(
// Check if we already make font for this axes. This is typically happens if the animation
// happens backward.
- tmpVarFontKey.set(start, newAxes)
- val axesCachedFont = verFontCache[tmpVarFontKey]
- if (axesCachedFont != null) {
- interpCache.put(InterpKey(start, end, progress), axesCachedFont)
+ val vKey = VarFontKey(start, newAxes)
+ fontCache.get(vKey)?.let {
+ fontCache.put(iKey, it)
if (DEBUG) {
- Log.d(LOG_TAG, "[$progress] Axis cache hit for $tmpVarFontKey")
+ Log.d(LOG_TAG, "[$progress] Axis cache hit for $vKey")
}
- return axesCachedFont
+ return it
}
// This is the first time to make the font for the axes. Build and store it to the cache.
// Font.Builder#build won't throw IOException since creating fonts from existing fonts will
// not do any IO work.
val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build()
- interpCache.put(InterpKey(start, end, progress), newFont)
- verFontCache.put(VarFontKey(start, newAxes), newFont)
+ fontCache.put(iKey, newFont)
+ fontCache.put(vKey, newFont)
// Cache misses are likely to create memory leaks, so this is logged at error level.
- Log.e(LOG_TAG, "[$progress] Cache MISS for $tmpInterpKey / $tmpVarFontKey")
+ Log.e(LOG_TAG, "[$progress] Cache MISS for $iKey / $vKey")
return newFont
}
private fun lerp(
start: Array<FontVariationAxis>,
end: Array<FontVariationAxis>,
- filter: (tag: String, left: Float?, right: Float?) -> Float
+ filter: (tag: String, left: Float?, right: Float?) -> Float,
): List<FontVariationAxis> {
// Safe to modify result of Font#getAxes since it returns cloned object.
start.sortBy { axis -> axis.tag }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 978943ae7f7c..eef26b67614b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -35,6 +35,8 @@ private const val TYPEFACE_CACHE_MAX_ENTRIES = 5
typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
interface TypefaceVariantCache {
+ val fontCache: FontCache
+ val animationFrameCount: Int
fun getTypefaceForVariant(fvar: String?): Typeface?
companion object {
@@ -57,8 +59,10 @@ interface TypefaceVariantCache {
class TypefaceVariantCacheImpl(
var baseTypeface: Typeface,
+ override val animationFrameCount: Int,
) : TypefaceVariantCache {
private val cache = LruCache<String, Typeface>(TYPEFACE_CACHE_MAX_ENTRIES)
+ override val fontCache = FontCacheImpl(animationFrameCount)
override fun getTypefaceForVariant(fvar: String?): Typeface? {
if (fvar == null) {
return baseTypeface
@@ -100,25 +104,17 @@ class TypefaceVariantCacheImpl(
*/
class TextAnimator(
layout: Layout,
- numberOfAnimationSteps: Int? = null, // Only do this number of discrete animation steps.
- private val invalidateCallback: () -> Unit,
+ private val typefaceCache: TypefaceVariantCache,
+ private val invalidateCallback: () -> Unit = {},
) {
- var typefaceCache: TypefaceVariantCache = TypefaceVariantCacheImpl(layout.paint.typeface)
- get() = field
- set(value) {
- field = value
- textInterpolator.typefaceCache = value
- }
-
// Following two members are for mutable for testing purposes.
- public var textInterpolator: TextInterpolator =
- TextInterpolator(layout, typefaceCache, numberOfAnimationSteps)
- public var animator: ValueAnimator =
+ public var textInterpolator = TextInterpolator(layout, typefaceCache)
+ public var animator =
ValueAnimator.ofFloat(1f).apply {
duration = DEFAULT_ANIMATION_DURATION
addUpdateListener {
textInterpolator.progress =
- calculateProgress(it.animatedValue as Float, numberOfAnimationSteps)
+ calculateProgress(it.animatedValue as Float, typefaceCache.animationFrameCount)
invalidateCallback()
}
addListener(
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index 02caeeddd774..9c0c0ffc8d41 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -28,11 +28,7 @@ import com.android.internal.graphics.ColorUtils
import java.lang.Math.max
/** Provide text style linear interpolation for plain text. */
-class TextInterpolator(
- layout: Layout,
- var typefaceCache: TypefaceVariantCache,
- numberOfAnimationSteps: Int? = null,
-) {
+class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache) {
/**
* Returns base paint used for interpolation.
*
@@ -66,7 +62,7 @@ class TextInterpolator(
val start: Int, // inclusive
val end: Int, // exclusive
var baseFont: Font,
- var targetFont: Font
+ var targetFont: Font,
) {
val length: Int
get() = end - start
@@ -79,14 +75,14 @@ class TextInterpolator(
val baseY: FloatArray, // same length as glyphIds
val targetX: FloatArray, // same length as glyphIds
val targetY: FloatArray, // same length as glyphIds
- val fontRuns: List<FontRun>
+ val fontRuns: List<FontRun>,
)
/** A class represents text layout of a single line. */
private class Line(val runs: List<Run>)
private var lines = listOf<Line>()
- private val fontInterpolator = FontInterpolator(numberOfAnimationSteps)
+ private val fontInterpolator = FontInterpolator(typefaceCache.fontCache)
// Recycling object for glyph drawing and tweaking.
private val tmpPaint = TextPaint()
@@ -343,12 +339,16 @@ class TextInterpolator(
private class MutablePositionedGlyph : TextAnimator.PositionedGlyph() {
override var runStart: Int = 0
public set
+
override var runLength: Int = 0
public set
+
override var glyphIndex: Int = 0
public set
+
override lateinit var font: Font
public set
+
override var glyphId: Int = 0
public set
}
@@ -401,7 +401,7 @@ class TextInterpolator(
0,
i - prevStart,
font,
- tmpPaintForGlyph
+ tmpPaintForGlyph,
)
prevStart = i
arrayIndex = 0
@@ -418,13 +418,13 @@ class TextInterpolator(
0,
run.end - prevStart,
font,
- tmpPaintForGlyph
+ tmpPaintForGlyph,
)
}
private fun updatePositionsAndFonts(
layoutResult: List<List<PositionedGlyphs>>,
- updateBase: Boolean
+ updateBase: Boolean,
) {
// Update target positions with newly calculated text layout.
check(layoutResult.size == lines.size) { "The new layout result has different line count." }
@@ -507,7 +507,7 @@ class TextInterpolator(
lineStart,
count,
layout.textDirectionHeuristic,
- paint
+ paint,
) { _, _, glyphs, _ ->
runs.add(glyphs)
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
index de4bdbc284c4..e2bc4095e1b5 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
@@ -114,16 +114,16 @@ class TransitionAnimator(
)
}
- internal fun assertReturnAnimations() {
+ fun assertReturnAnimations() {
check(returnAnimationsEnabled()) {
"isLaunching cannot be false when the returnAnimationFrameworkLibrary flag " +
"is disabled"
}
}
- internal fun returnAnimationsEnabled() = returnAnimationFrameworkLibrary()
+ fun returnAnimationsEnabled() = returnAnimationFrameworkLibrary()
- internal fun assertLongLivedReturnAnimations() {
+ fun assertLongLivedReturnAnimations() {
check(longLivedReturnAnimationsEnabled()) {
"Long-lived registrations cannot be used when the " +
"returnAnimationFrameworkLibrary or the " +
@@ -131,7 +131,7 @@ class TransitionAnimator(
}
}
- internal fun longLivedReturnAnimationsEnabled() =
+ fun longLivedReturnAnimationsEnabled() =
returnAnimationFrameworkLibrary() && returnAnimationFrameworkLongLived()
internal fun WindowAnimationState.toTransitionState() =
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
index 6c982a045084..9e872fc5d3c5 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
@@ -58,7 +58,12 @@ fun BackAnimationSpec.Companion.createFloatingSurfaceAnimationSpec(
val maxTranslationY = maxTranslationYByScale - maxMarginYPx
val minScaleReversed = 1f - minScale
- val direction = if (backEvent.swipeEdge == BackEvent.EDGE_LEFT) 1 else -1
+ val direction =
+ when (backEvent.swipeEdge) {
+ BackEvent.EDGE_LEFT -> 1
+ BackEvent.EDGE_RIGHT -> -1
+ else -> 0
+ }
val progressX = backEvent.progress
val ratioTranslateX = translateXEasing.getInterpolation(progressX)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
index 9390664d1283..597cbf24729b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
@@ -31,6 +31,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.biometrics.AuthController
+import com.android.systemui.customization.R as customR
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
@@ -147,7 +148,7 @@ constructor(
} else {
val scaleFactor = authController.scaleFactor
val bottomPaddingPx =
- context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom)
+ context.resources.getDimensionPixelSize(customR.dimen.lock_icon_margin_bottom)
val heightPx = windowViewBounds.bottom.toFloat()
Pair(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index 04c527176cce..cf0ba5196bad 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -30,8 +30,7 @@ import com.android.compose.nestedscroll.OnStopScope
import com.android.compose.nestedscroll.PriorityNestedScrollConnection
import com.android.compose.nestedscroll.ScrollController
import kotlin.math.absoluteValue
-
-internal typealias SuspendedValue<T> = suspend () -> T
+import kotlinx.coroutines.launch
internal interface DraggableHandler {
/**
@@ -50,6 +49,7 @@ internal interface DragController {
/**
* Drag the current scene by [delta] pixels.
*
+ * @param delta The distance to drag the scene in pixels.
* @return the consumed [delta]
*/
fun onDrag(delta: Float): Float
@@ -57,9 +57,18 @@ internal interface DragController {
/**
* Stop the current drag with the given [velocity].
*
+ * @param velocity The velocity of the drag when it stopped.
+ * @param canChangeContent Whether the content can be changed as a result of this drag.
* @return the consumed [velocity] when the animation complete
*/
- fun onStop(velocity: Float, canChangeContent: Boolean): SuspendedValue<Float>
+ suspend fun onStop(velocity: Float, canChangeContent: Boolean): Float
+
+ /**
+ * Cancels the current drag.
+ *
+ * @param canChangeContent Whether the content can be changed as a result of this drag.
+ */
+ fun onCancel(canChangeContent: Boolean)
}
internal class DraggableHandlerImpl(
@@ -350,7 +359,7 @@ private class DragControllerImpl(
val result = swipes.findUserActionResult(directionOffset = newOffset)
if (result == null) {
- onStop(velocity = delta, canChangeContent = true)
+ onCancel(canChangeContent = true)
return 0f
}
@@ -379,11 +388,11 @@ private class DragControllerImpl(
return consumedDelta
}
- override fun onStop(velocity: Float, canChangeContent: Boolean): SuspendedValue<Float> {
+ override suspend fun onStop(velocity: Float, canChangeContent: Boolean): Float {
return onStop(velocity, canChangeContent, swipeAnimation)
}
- private fun <T : ContentKey> onStop(
+ private suspend fun <T : ContentKey> onStop(
velocity: Float,
canChangeContent: Boolean,
@@ -392,24 +401,23 @@ private class DragControllerImpl(
// callbacks (like onAnimationCompleted()) might incorrectly finish a new transition that
// replaced this one.
swipeAnimation: SwipeAnimation<T>,
- ): SuspendedValue<Float> {
+ ): Float {
// The state was changed since the drag started; don't do anything.
if (!isDrivingTransition || swipeAnimation.isAnimatingOffset()) {
- return { 0f }
+ return 0f
}
val fromContent = swipeAnimation.fromContent
- val consumedVelocity: SuspendedValue<Float>
- if (canChangeContent) {
- // If we are halfway between two contents, we check what the target will be based on the
- // velocity and offset of the transition, then we launch the animation.
+ val targetContent =
+ if (canChangeContent) {
+ // If we are halfway between two contents, we check what the target will be based on
+ // the velocity and offset of the transition, then we launch the animation.
- val toContent = swipeAnimation.toContent
+ val toContent = swipeAnimation.toContent
- // Compute the destination content (and therefore offset) to settle in.
- val offset = swipeAnimation.dragOffset
- val distance = swipeAnimation.distance()
- val targetContent =
+ // Compute the destination content (and therefore offset) to settle in.
+ val offset = swipeAnimation.dragOffset
+ val distance = swipeAnimation.distance()
if (
distance != DistanceUnspecified &&
shouldCommitSwipe(
@@ -424,16 +432,15 @@ private class DragControllerImpl(
} else {
fromContent
}
- consumedVelocity = swipeAnimation.animateOffset(velocity, targetContent = targetContent)
- } else {
- // We are doing an overscroll preview animation between scenes.
- check(fromContent == swipeAnimation.currentContent) {
- "canChangeContent is false but currentContent != fromContent"
+ } else {
+ // We are doing an overscroll preview animation between scenes.
+ check(fromContent == swipeAnimation.currentContent) {
+ "canChangeContent is false but currentContent != fromContent"
+ }
+ fromContent
}
- consumedVelocity = swipeAnimation.animateOffset(velocity, targetContent = fromContent)
- }
- return consumedVelocity
+ return swipeAnimation.animateOffset(velocity, targetContent)
}
/**
@@ -478,6 +485,12 @@ private class DragControllerImpl(
isCloserToTarget()
}
}
+
+ override fun onCancel(canChangeContent: Boolean) {
+ swipeAnimation.contentTransition.coroutineScope.launch {
+ onStop(velocity = 0f, canChangeContent = canChangeContent)
+ }
+ }
}
/** The [Swipe] associated to a given fromScene, startedPosition and pointersDown. */
@@ -701,13 +714,14 @@ private fun scrollController(
}
override suspend fun OnStopScope.onStop(initialVelocity: Float): Float {
- return dragController
- .onStop(velocity = initialVelocity, canChangeContent = canChangeScene)
- .invoke()
+ return dragController.onStop(
+ velocity = initialVelocity,
+ canChangeContent = canChangeScene,
+ )
}
override fun onCancel() {
- dragController.onStop(velocity = 0f, canChangeContent = canChangeScene)
+ dragController.onCancel(canChangeScene)
}
/**
@@ -731,5 +745,9 @@ internal const val OffsetVisibilityThreshold = 0.5f
private object NoOpDragController : DragController {
override fun onDrag(delta: Float) = 0f
- override fun onStop(velocity: Float, canChangeContent: Boolean) = suspend { 0f }
+ override suspend fun onStop(velocity: Float, canChangeContent: Boolean) = 0f
+
+ override fun onCancel(canChangeContent: Boolean) {
+ /* do nothing */
+ }
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
index 160326792f81..59ac68bd0299 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
@@ -318,17 +318,13 @@ internal class MultiPointerDraggableNode(
velocityTracker.calculateVelocity(maxVelocity)
}
.toFloat(),
- onFling = {
- controller.onStop(it, canChangeContent = true).invoke()
- },
+ onFling = { controller.onStop(it, canChangeContent = true) },
)
},
onDragCancel = { controller ->
startFlingGesture(
initialVelocity = 0f,
- onFling = {
- controller.onStop(it, canChangeContent = true).invoke()
- },
+ onFling = { controller.onStop(it, canChangeContent = true) },
)
},
swipeDetector = swipeDetector,
@@ -519,8 +515,19 @@ internal class MultiPointerDraggableNode(
// we intercept an ongoing swipe transition (i.e. startDragImmediately() returned
// true).
if (overSlop == 0f) {
- val delta = (drag.position - consumablePointer.position).toFloat()
- check(delta != 0f) { "delta is equal to 0" }
+ // If the user drags in the opposite direction, the delta becomes zero because
+ // we return to the original point. Therefore, we should use the previous event
+ // to calculate the direction.
+ val delta = (drag.position - drag.previousPosition).toFloat()
+ check(delta != 0f) {
+ buildString {
+ append("delta is equal to 0 ")
+ append("touchSlop ${currentValueOf(LocalViewConfiguration).touchSlop} ")
+ append("consumablePointer.position ${consumablePointer.position} ")
+ append("drag.position ${drag.position} ")
+ append("drag.previousPosition ${drag.previousPosition}")
+ }
+ }
overSlop = delta.sign
}
drag
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index b3fd097946d0..4bccac1e3ba0 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -430,14 +430,6 @@ internal class MutableSceneTransitionLayoutStateImpl(
check(transitionStates.size == 1)
check(transitionStates[0] is TransitionState.Idle)
transitionStates = listOf(transition)
- } else if (currentState == transition.replacedTransition) {
- // Replace the transition.
- transitionStates =
- transitionStates.subList(0, transitionStates.lastIndex) + transition
-
- // Make sure it is removed from the finishedTransitions set if it was already
- // finished.
- finishedTransitions.remove(currentState)
} else {
// Append the new transition.
transitionStates = transitionStates + transition
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
index dbfeb5cd0168..ae235e5097af 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
@@ -28,6 +28,7 @@ import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
import kotlin.math.absoluteValue
import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.launch
internal fun createSwipeAnimation(
layoutState: MutableSceneTransitionLayoutStateImpl,
@@ -317,11 +318,11 @@ internal class SwipeAnimation<T : ContentKey>(
*
* @return the velocity consumed
*/
- fun animateOffset(
+ suspend fun animateOffset(
initialVelocity: Float,
targetContent: T,
spec: AnimationSpec<Float>? = null,
- ): SuspendedValue<Float> {
+ ): Float {
check(!isAnimatingOffset()) { "SwipeAnimation.animateOffset() can only be called once" }
val initialProgress = progress
@@ -379,7 +380,7 @@ internal class SwipeAnimation<T : ContentKey>(
if (skipAnimation) {
// Unblock the job.
offsetAnimationRunnable.complete(null)
- return { 0f }
+ return 0f
}
val isTargetGreater = targetOffset > animatable.value
@@ -440,7 +441,7 @@ internal class SwipeAnimation<T : ContentKey>(
}
}
- return { velocityConsumed.await() }
+ return velocityConsumed.await()
}
/** An exception thrown during the animation to stop it immediately. */
@@ -469,7 +470,9 @@ internal class SwipeAnimation<T : ContentKey>(
fun freezeAndAnimateToCurrentState() {
if (isAnimatingOffset()) return
- animateOffset(initialVelocity = 0f, targetContent = currentContent)
+ contentTransition.coroutineScope.launch {
+ animateOffset(initialVelocity = 0f, targetContent = currentContent)
+ }
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
index 2b33224022fc..c6912d5e4ad2 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt
@@ -145,7 +145,7 @@ internal suspend fun <T : ContentKey> animateProgress(
cancelSpec: AnimationSpec<Float>?,
animationScope: CoroutineScope? = null,
) {
- fun animateOffset(targetContent: T, spec: AnimationSpec<Float>?) {
+ suspend fun animateOffset(targetContent: T, spec: AnimationSpec<Float>?) {
if (state.transitionState != animation.contentTransition || animation.isAnimatingOffset()) {
return
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 10057b280d28..a1077cf95133 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -45,6 +45,8 @@ import com.android.compose.test.runMonotonicClockTest
import com.android.compose.test.transition
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import org.junit.Test
import org.junit.runner.RunWith
@@ -266,7 +268,7 @@ class DraggableHandlerTest {
) {
val velocityConsumed = onDragStoppedAnimateLater(velocity, canChangeScene)
onAnimationStart()
- onAnimationEnd(velocityConsumed.invoke())
+ onAnimationEnd(velocityConsumed.await())
}
suspend fun DragController.onDragStoppedAnimateNow(
@@ -285,8 +287,10 @@ class DraggableHandlerTest {
fun DragController.onDragStoppedAnimateLater(
velocity: Float,
canChangeScene: Boolean = true,
- ): SuspendedValue<Float> {
- return onStop(velocity, canChangeScene)
+ ): Deferred<Float> {
+ val velocityConsumed = testScope.async { onStop(velocity, canChangeScene) }
+ testScope.testScheduler.runCurrent()
+ return velocityConsumed
}
fun NestedScrollConnection.scroll(
@@ -1112,6 +1116,7 @@ class DraggableHandlerTest {
// Freeze the transition.
val transition = transitionState as Transition
transition.freezeAndAnimateToCurrentState()
+ runCurrent()
assertTransition(isUserInputOngoing = false)
advanceUntilIdle()
assertIdle(SceneC)
@@ -1279,14 +1284,13 @@ class DraggableHandlerTest {
// Release the finger.
dragController.onDragStoppedAnimateNow(
velocity = -velocityThreshold,
- onAnimationStart = { assertTransition(fromScene = SceneA, toScene = SceneB) },
+ onAnimationStart = {
+ // Given that we are at progress >= 100% and that the overscroll on scene B is doing
+ // nothing, we are already idle.
+ assertIdle(SceneB)
+ },
expectedConsumedVelocity = 0f,
)
-
- // Exhaust all coroutines *without advancing the clock*. Given that we are at progress >=
- // 100% and that the overscroll on scene B is doing nothing, we are already idle.
- runCurrent()
- assertIdle(SceneB)
}
@Test
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
index b87cc5c88335..3622369b8ff9 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
@@ -132,6 +132,9 @@ class InterruptionHandlerTest {
assertThat(state.currentTransitions)
.comparingElementsUsing(FromToCurrentTriple)
.containsExactly(
+ // Initial transition, A => B.
+ Triple(SceneA, SceneB, SceneB),
+
// Initial transition reversed, B back to A.
Triple(SceneA, SceneB, SceneA),
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
index 5ec74f8d2260..cb3e433ec4a5 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
@@ -72,9 +72,13 @@ class MultiPointerDraggableTest {
return delta
}
- override fun onStop(velocity: Float, canChangeContent: Boolean): SuspendedValue<Float> {
+ override suspend fun onStop(velocity: Float, canChangeContent: Boolean): Float {
onStop.invoke(velocity)
- return { velocity }
+ return velocity
+ }
+
+ override fun onCancel(canChangeContent: Boolean) {
+ error("MultiPointerDraggable never calls onCancel()")
}
}
@@ -593,7 +597,7 @@ class MultiPointerDraggableTest {
}
}
- fun continueDraggingDown() {
+ fun dragDown() {
rule.onRoot().performTouchInput { moveBy(Offset(0f, touchSlop)) }
}
@@ -603,11 +607,78 @@ class MultiPointerDraggableTest {
assertThat(started).isFalse()
swipeConsume = true
- continueDraggingDown()
+ // Drag in same direction
+ dragDown()
assertThat(capturedChange).isNotNull()
capturedChange = null
- continueDraggingDown()
+ dragDown()
+ assertThat(capturedChange).isNull()
+
+ assertThat(started).isTrue()
+ }
+
+ @Test
+ fun multiPointerSwipeDetectorInteractionZeroOffsetFromStartPosition() {
+ val size = 200f
+ val middle = Offset(size / 2f, size / 2f)
+
+ var started = false
+
+ var capturedChange: PointerInputChange? = null
+ var swipeConsume = false
+
+ var touchSlop = 0f
+ rule.setContent {
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ Box(
+ Modifier.size(with(LocalDensity.current) { Size(size, size).toDpSize() })
+ .nestedScrollDispatcher()
+ .multiPointerDraggable(
+ orientation = Orientation.Vertical,
+ startDragImmediately = { false },
+ swipeDetector =
+ object : SwipeDetector {
+ override fun detectSwipe(change: PointerInputChange): Boolean {
+ capturedChange = change
+ return swipeConsume
+ }
+ },
+ onDragStarted = { _, _ ->
+ started = true
+ SimpleDragController(
+ onDrag = { /* do nothing */ },
+ onStop = { /* do nothing */ },
+ )
+ },
+ dispatcher = defaultDispatcher,
+ )
+ ) {}
+ }
+
+ fun startDraggingDown() {
+ rule.onRoot().performTouchInput {
+ down(middle)
+ moveBy(Offset(0f, touchSlop))
+ }
+ }
+
+ fun dragUp() {
+ rule.onRoot().performTouchInput { moveBy(Offset(0f, -touchSlop)) }
+ }
+
+ startDraggingDown()
+ assertThat(capturedChange).isNotNull()
+ capturedChange = null
+ assertThat(started).isFalse()
+
+ swipeConsume = true
+ // Drag in the opposite direction
+ dragUp()
+ assertThat(capturedChange).isNotNull()
+ capturedChange = null
+
+ dragUp()
assertThat(capturedChange).isNull()
assertThat(started).isTrue()
diff --git a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/res/xml/network_security_config.xml b/packages/SystemUI/customization/res/values-land/dimens.xml
index 4bd9ca049f55..50f220c882bd 100644
--- a/libs/WindowManager/Shell/tests/e2e/mediaprojection/flicker-service/res/xml/network_security_config.xml
+++ b/packages/SystemUI/customization/res/values-land/dimens.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -15,8 +14,6 @@
~ limitations under the License.
-->
-<network-security-config>
- <domain-config cleartextTrafficPermitted="true">
- <domain includeSubdomains="true">localhost</domain>
- </domain-config>
-</network-security-config>
+<resources>
+ <dimen name="lock_icon_margin_bottom">24dp</dimen>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/customization/res/values-sw600dp-land/dimens.xml
index 18073adf9e7a..876028195ff3 100644
--- a/packages/SystemUI/customization/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/customization/res/values-sw600dp-land/dimens.xml
@@ -17,4 +17,5 @@
<resources>
<dimen name="keyguard_smartspace_top_offset">0dp</dimen>
<dimen name="status_view_margin_horizontal">8dp</dimen>
+ <dimen name="lock_icon_margin_bottom">60dp</dimen>
</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values/dimens.xml b/packages/SystemUI/customization/res/values/dimens.xml
index 041ae62670e5..21b4c7165226 100644
--- a/packages/SystemUI/customization/res/values/dimens.xml
+++ b/packages/SystemUI/customization/res/values/dimens.xml
@@ -40,4 +40,5 @@
<dimen name="date_weather_view_height">24dp</dimen>
<dimen name="enhanced_smartspace_height">104dp</dimen>
<dimen name="status_view_margin_horizontal">0dp</dimen>
+ <dimen name="lock_icon_margin_bottom">74dp</dimen>
</resources> \ No newline at end of file
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index 9877406eeac2..801a2d6170cc 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -34,6 +34,7 @@ import com.android.app.animation.Interpolators
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.animation.GlyphCallback
import com.android.systemui.animation.TextAnimator
+import com.android.systemui.animation.TypefaceVariantCacheImpl
import com.android.systemui.customization.R
import com.android.systemui.log.core.LogLevel
import com.android.systemui.log.core.LogcatOnlyMessageBuffer
@@ -98,7 +99,8 @@ constructor(
@VisibleForTesting
var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator = { layout, invalidateCb ->
- TextAnimator(layout, NUM_CLOCK_FONT_ANIMATION_STEPS, invalidateCb)
+ val cache = TypefaceVariantCacheImpl(layout.paint.typeface, NUM_CLOCK_FONT_ANIMATION_STEPS)
+ TextAnimator(layout, cache, invalidateCb)
}
// Used by screenshot tests to provide stability
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 9bb92bc13416..e8987257bb47 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -67,7 +67,10 @@ class DefaultClockProvider(
val buffers = messageBuffers ?: ClockMessageBuffers(LogUtil.DEFAULT_MESSAGE_BUFFER)
val fontAxes = ClockFontAxis.merge(FlexClockController.FONT_AXES, settings.axes)
val clockSettings = settings.copy(axes = fontAxes.map { it.toSetting() })
- val typefaceCache = TypefaceCache(buffers.infraMessageBuffer) { FLEX_TYPEFACE }
+ val typefaceCache =
+ TypefaceCache(buffers.infraMessageBuffer, NUM_CLOCK_FONT_ANIMATION_STEPS) {
+ FLEX_TYPEFACE
+ }
FlexClockController(
ClockContext(
ctx,
@@ -110,6 +113,8 @@ class DefaultClockProvider(
}
companion object {
+ const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
+
// TODO(b/364681643): Variations for retargetted DIGITAL_CLOCK_FLEX
val LEGACY_FLEX_LS_VARIATION =
listOf(
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt
index f5a9375122b5..9e3f6d9677df 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TypefaceCache.kt
@@ -17,13 +17,18 @@
package com.android.systemui.shared.clocks
import android.graphics.Typeface
+import com.android.systemui.animation.FontCacheImpl
import com.android.systemui.animation.TypefaceVariantCache
import com.android.systemui.log.core.Logger
import com.android.systemui.log.core.MessageBuffer
import java.lang.ref.ReferenceQueue
import java.lang.ref.WeakReference
-class TypefaceCache(messageBuffer: MessageBuffer, val typefaceFactory: (String) -> Typeface) {
+class TypefaceCache(
+ messageBuffer: MessageBuffer,
+ val animationFrameCount: Int,
+ val typefaceFactory: (String) -> Typeface,
+) {
private val logger = Logger(messageBuffer, this::class.simpleName!!)
private data class CacheKey(val res: String, val fvar: String?)
@@ -44,6 +49,7 @@ class TypefaceCache(messageBuffer: MessageBuffer, val typefaceFactory: (String)
// result, once a typeface is no longer being used, it is unlikely to be recreated immediately.
private val cache = mutableMapOf<CacheKey, WeakTypefaceRef>()
private val queue = ReferenceQueue<Typeface>()
+ private val fontCache = FontCacheImpl(animationFrameCount)
fun getTypeface(res: String): Typeface {
checkQueue()
@@ -62,6 +68,9 @@ class TypefaceCache(messageBuffer: MessageBuffer, val typefaceFactory: (String)
fun getVariantCache(res: String): TypefaceVariantCache {
val baseTypeface = getTypeface(res)
return object : TypefaceVariantCache {
+ override val fontCache = this@TypefaceCache.fontCache
+ override val animationFrameCount = this@TypefaceCache.animationFrameCount
+
override fun getTypefaceForVariant(fvar: String?): Typeface? {
checkQueue()
val key = CacheKey(res, fvar)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index 48761c081b9e..cef24e99084e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -39,7 +39,6 @@ import com.android.systemui.animation.TextAnimator
import com.android.systemui.customization.R
import com.android.systemui.log.core.Logger
import com.android.systemui.plugins.clocks.ClockFontAxisSetting
-import com.android.systemui.shared.clocks.ClockAnimation
import com.android.systemui.shared.clocks.ClockContext
import com.android.systemui.shared.clocks.DigitTranslateAnimator
import com.android.systemui.shared.clocks.DimensionParser
@@ -96,9 +95,7 @@ open class SimpleDigitalClockTextView(clockCtx: ClockContext, attrs: AttributeSe
@VisibleForTesting
var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator = { layout, invalidateCb ->
- TextAnimator(layout, ClockAnimation.NUM_CLOCK_FONT_ANIMATION_STEPS, invalidateCb).also {
- it.typefaceCache = typefaceCache
- }
+ TextAnimator(layout, typefaceCache, invalidateCb)
}
override var verticalAlignment: VerticalAlignment = VerticalAlignment.BASELINE
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
index b7b98d41da93..9f9245c39e5f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.accessibility.extradim
+import android.os.Handler
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -25,8 +26,10 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
@@ -43,21 +46,30 @@ class ExtraDimDialogManagerTest : SysuiTestCase() {
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var dialogProvider: Provider<ExtraDimDialogDelegate>
@Mock private lateinit var dialogTransitionAnimator: DialogTransitionAnimator
+ @Mock private lateinit var mainHandler: Handler
+ @Captor private lateinit var runnableCaptor: ArgumentCaptor<Runnable>
@Before
fun setUp() {
extraDimDialogManager =
- ExtraDimDialogManager(dialogProvider, activityStarter, dialogTransitionAnimator)
+ ExtraDimDialogManager(
+ dialogProvider,
+ activityStarter,
+ dialogTransitionAnimator,
+ mainHandler,
+ )
}
@Test
fun dismissKeyguardIfNeededAndShowDialog_executeRunnableDismissingKeyguard() {
extraDimDialogManager.dismissKeyguardIfNeededAndShowDialog()
+ verify(mainHandler).post(runnableCaptor.capture())
+ runnableCaptor.value.run()
verify(activityStarter)
.executeRunnableDismissingKeyguard(
any(),
/* cancelAction= */ eq(null),
- /* dismissShade= */ eq(false),
+ /* dismissShade= */ eq(true),
/* afterKeyguardGone= */ eq(true),
/* deferred= */ eq(false),
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
index 4809d0e4838f..d6db34949c2e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
@@ -48,6 +48,11 @@ class BackAnimationSpecTest : SysuiTestCase() {
)
assertBackTransformation(
backAnimationSpec = backAnimationSpec,
+ backInput = BackInput(progressX = 1f, progressY = 0f, edge = BackEvent.EDGE_NONE),
+ expected = BackTransformation(translateX = 0f, translateY = 0f, scale = minScale),
+ )
+ assertBackTransformation(
+ backAnimationSpec = backAnimationSpec,
backInput = BackInput(progressX = 1f, progressY = 1f, edge = BackEvent.EDGE_LEFT),
expected = BackTransformation(translateX = -maxX, translateY = -maxY, scale = minScale),
)
@@ -77,7 +82,7 @@ class BackAnimationSpecTest : SysuiTestCase() {
translateX = Float.NaN,
translateY = Float.NaN,
scale = 1f,
- scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+ scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
),
)
assertBackTransformation(
@@ -88,7 +93,7 @@ class BackAnimationSpecTest : SysuiTestCase() {
translateX = Float.NaN,
translateY = Float.NaN,
scale = minScale,
- scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+ scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
),
)
assertBackTransformation(
@@ -99,7 +104,7 @@ class BackAnimationSpecTest : SysuiTestCase() {
translateX = Float.NaN,
translateY = Float.NaN,
scale = minScale,
- scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+ scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
),
)
assertBackTransformation(
@@ -110,7 +115,18 @@ class BackAnimationSpecTest : SysuiTestCase() {
translateX = Float.NaN,
translateY = Float.NaN,
scale = minScale,
- scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER
+ scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
+ ),
+ )
+ assertBackTransformation(
+ backAnimationSpec = backAnimationSpec,
+ backInput = BackInput(progressX = 1f, progressY = 1f, edge = BackEvent.EDGE_NONE),
+ expected =
+ BackTransformation(
+ translateX = Float.NaN,
+ translateY = Float.NaN,
+ scale = minScale,
+ scalePivotPosition = ScalePivotPosition.BOTTOM_CENTER,
),
)
}
@@ -131,7 +147,7 @@ private fun assertBackTransformation(
/* swipeEdge = */ backInput.edge,
),
progressY = backInput.progressY,
- result = actual
+ result = actual,
)
val tolerance = 0f
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
index 13f2c7212e36..4e64c50a3253 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
@@ -17,22 +17,23 @@
package com.android.systemui.biometrics.domain.interactor
import android.graphics.Rect
-import android.hardware.fingerprint.FingerprintManager
import android.view.MotionEvent
import android.view.Surface
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
+import com.android.systemui.biometrics.authController
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,29 +45,25 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class UdfpsOverlayInteractorTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
- private lateinit var testScope: TestScope
+ private val kosmos = testKosmos()
- @Mock private lateinit var fingerprintManager: FingerprintManager
- @Mock private lateinit var authController: AuthController
+ private val testScope: TestScope = kosmos.testScope
+
+ private val authController: AuthController = kosmos.authController
@Captor private lateinit var authControllerCallback: ArgumentCaptor<AuthController.Callback>
@Mock private lateinit var udfpsOverlayParams: UdfpsOverlayParams
@Mock private lateinit var overlayBounds: Rect
- @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
private lateinit var underTest: UdfpsOverlayInteractor
- @Before
- fun setUp() {
- testScope = TestScope(StandardTestDispatcher())
- }
-
@Test
fun testShouldInterceptTouch() =
testScope.runTest {
@@ -107,15 +104,26 @@ class UdfpsOverlayInteractorTest : SysuiTestCase() {
assertThat(udfpsOverlayParams()).isEqualTo(firstParams)
}
+ @Test
+ fun testPaddingIsNeverNegative() =
+ testScope.runTest {
+ context.orCreateTestableResources.addOverride(R.dimen.pixel_pitch, 60.0f)
+ createUdfpsOverlayInteractor()
+ val padding by collectLastValue(underTest.iconPadding)
+ runCurrent()
+
+ verify(authController).addCallback(authControllerCallback.capture())
+
+ // Simulate the first empty udfps overlay params value.
+ authControllerCallback.value.onUdfpsLocationChanged(UdfpsOverlayParams())
+ runCurrent()
+
+ assertThat(padding).isEqualTo(0)
+ context.orCreateTestableResources.removeOverride(R.dimen.pixel_pitch)
+ }
+
private fun createUdfpsOverlayInteractor() {
- underTest =
- UdfpsOverlayInteractor(
- context,
- authController,
- selectedUserInteractor,
- fingerprintManager,
- testScope.backgroundScope
- )
+ underTest = kosmos.udfpsOverlayInteractor
testScope.runCurrent()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index 1e8651683ec1..e5f0d7c6bf37 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -19,13 +19,13 @@ package com.android.systemui.communal
import android.os.UserHandle
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
import android.provider.Settings
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.internal.logging.uiEventLogger
import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_COMMUNAL_SCENE_KTF_REFACTOR
+import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
@@ -38,6 +38,7 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dock.dockManager
import com.android.systemui.dock.fakeDockManager
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -47,6 +48,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.notificationShadeWindowController
import com.android.systemui.statusbar.phone.centralSurfaces
import com.android.systemui.statusbar.phone.centralSurfacesOptional
@@ -65,12 +68,29 @@ import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@EnableFlags(FLAG_COMMUNAL_HUB)
-class CommunalSceneStartableTest : SysuiTestCase() {
+class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ companion object {
+ private const val SCREEN_TIMEOUT = 1000
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
private val kosmos = testKosmos()
private lateinit var underTest: CommunalSceneStartable
@@ -95,7 +115,6 @@ class CommunalSceneStartableTest : SysuiTestCase() {
keyguardInteractor = keyguardInteractor,
systemSettings = fakeSettings,
notificationShadeWindowController = notificationShadeWindowController,
- featureFlagsClassic = kosmos.fakeFeatureFlagsClassic,
applicationScope = applicationCoroutineScope,
bgScope = applicationCoroutineScope,
mainDispatcher = testDispatcher,
@@ -114,7 +133,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun keyguardGoesAway_whenLaunchingEditMode_doNotForceBlankScene() =
with(kosmos) {
testScope.runTest {
@@ -135,7 +154,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun keyguardGoesAway_whenLaunchingWidget_doNotForceBlankScene() =
with(kosmos) {
testScope.runTest {
@@ -156,7 +175,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun keyguardGoesAway_whenNotLaunchingWidget_forceBlankScene() =
with(kosmos) {
testScope.runTest {
@@ -177,7 +196,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun keyguardGoesAway_whenInEditMode_doesNotChangeScene() =
with(kosmos) {
testScope.runTest {
@@ -198,6 +217,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
@Ignore("Ignored until custom animations are implemented in b/322787129")
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun deviceDocked_forceCommunalScene() =
with(kosmos) {
testScope.runTest {
@@ -215,7 +235,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun occluded_forceBlankScene() =
with(kosmos) {
testScope.runTest {
@@ -235,7 +255,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun occluded_doesNotForceBlankSceneIfLaunchingActivityOverLockscreen() =
with(kosmos) {
testScope.runTest {
@@ -255,7 +275,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun deviceDocked_doesNotForceCommunalIfTransitioningFromCommunal() =
with(kosmos) {
testScope.runTest {
@@ -273,7 +293,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun deviceAsleep_forceBlankSceneAfterTimeout() =
with(kosmos) {
testScope.runTest {
@@ -295,7 +315,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun deviceAsleep_wakesUpBeforeTimeout_noChangeInScene() =
with(kosmos) {
testScope.runTest {
@@ -325,6 +345,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
@Ignore("Ignored until custom animations are implemented in b/322787129")
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun dockingOnLockscreen_forcesCommunal() =
with(kosmos) {
testScope.runTest {
@@ -347,6 +368,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
@Ignore("Ignored until custom animations are implemented in b/322787129")
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun dockingOnLockscreen_doesNotForceCommunalIfDreamStarts() =
with(kosmos) {
testScope.runTest {
@@ -377,6 +399,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_whenDreaming_goesToBlank() =
with(kosmos) {
testScope.runTest {
@@ -394,6 +417,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_notDreaming_staysOnCommunal() =
with(kosmos) {
testScope.runTest {
@@ -409,6 +433,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_dreamStopped_staysOnCommunal() =
with(kosmos) {
testScope.runTest {
@@ -432,6 +457,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_dreamStartedHalfway_goesToCommunal() =
with(kosmos) {
testScope.runTest {
@@ -454,6 +480,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_dreamAfterInitialTimeout_goesToBlank() =
with(kosmos) {
testScope.runTest {
@@ -474,6 +501,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_userActivityTriggered_resetsTimeout() =
with(kosmos) {
testScope.runTest {
@@ -501,6 +529,7 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_SCENE_CONTAINER)
fun hubTimeout_screenTimeoutChanged() =
with(kosmos) {
testScope.runTest {
@@ -526,7 +555,163 @@ class CommunalSceneStartableTest : SysuiTestCase() {
}
@Test
- @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_whenDreaming_goesToBlank() =
+ with(kosmos) {
+ testScope.runTest {
+ // Device is dreaming and on communal.
+ updateDreaming(true)
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Scene times out back to blank after the screen timeout.
+ advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Dream)
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_notDreaming_staysOnCommunal() =
+ with(kosmos) {
+ testScope.runTest {
+ // Device is not dreaming and on communal.
+ updateDreaming(false)
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ // Scene stays as Communal
+ advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_dreamStopped_staysOnCommunal() =
+ with(kosmos) {
+ testScope.runTest {
+ // Device is dreaming and on communal.
+ updateDreaming(true)
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Wait a bit, but not long enough to timeout.
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Dream stops, timeout is cancelled and device stays on hub, because the regular
+ // screen timeout will take effect at this point.
+ updateDreaming(false)
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_dreamStartedHalfway_goesToCommunal() =
+ with(kosmos) {
+ testScope.runTest {
+ // Device is on communal, but not dreaming.
+ updateDreaming(false)
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Wait a bit, but not long enough to timeout, then start dreaming.
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+ updateDreaming(true)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Device times out after one screen timeout interval, dream doesn't reset timeout.
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Dream)
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_dreamAfterInitialTimeout_goesToBlank() =
+ with(kosmos) {
+ testScope.runTest {
+ // Device is on communal.
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ // Device stays on the hub after the timeout since we're not dreaming.
+ advanceTimeBy(SCREEN_TIMEOUT.milliseconds * 2)
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Start dreaming.
+ updateDreaming(true)
+
+ // Hub times out immediately.
+ assertThat(scene).isEqualTo(Scenes.Dream)
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_userActivityTriggered_resetsTimeout() =
+ with(kosmos) {
+ testScope.runTest {
+ // Device is dreaming and on communal.
+ updateDreaming(true)
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Wait a bit, but not long enough to timeout.
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+
+ // Send user interaction to reset timeout.
+ communalInteractor.signalUserInteraction()
+
+ // If user activity didn't reset timeout, we would have gone back to Blank by now.
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Timeout happens one interval after the user interaction.
+ advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Dream)
+ }
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ fun hubTimeout_withSceneContainer_screenTimeoutChanged() =
+ with(kosmos) {
+ testScope.runTest {
+ fakeSettings.putInt(Settings.System.SCREEN_OFF_TIMEOUT, SCREEN_TIMEOUT * 2)
+
+ // Device is dreaming and on communal.
+ updateDreaming(true)
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+
+ val scene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ // Scene times out back to blank after the screen timeout.
+ advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Communal)
+
+ advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
+ assertThat(scene).isEqualTo(Scenes.Dream)
+ assertThat(uiEventLoggerFake.logs.first().eventId)
+ .isEqualTo(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT.id)
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ }
+ }
+
+ @Test
+ @DisableFlags(FLAG_COMMUNAL_SCENE_KTF_REFACTOR, FLAG_SCENE_CONTAINER)
fun transitionFromDozingToGlanceableHub_forcesCommunal() =
with(kosmos) {
testScope.runTest {
@@ -558,8 +743,4 @@ class CommunalSceneStartableTest : SysuiTestCase() {
fakeKeyguardRepository.setDreaming(dreaming)
runCurrent()
}
-
- companion object {
- private const val SCREEN_TIMEOUT = 1000
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
index ed214749d6a7..3c90c9372c27 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
@@ -67,7 +67,6 @@ public class ComplicationCollectionLiveDataTest extends SysuiTestCase {
mFeatureFlags.set(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS, true);
mStateController = new DreamOverlayStateController(
mExecutor,
- /* overlayEnabled= */ true,
mFeatureFlags,
FakeLogBuffer.Factory.Companion.create(),
new FakeWeakReferenceFactory());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryTest.kt
new file mode 100644
index 000000000000..e17b66e90c2d
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryTest.kt
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.data.repository
+
+import android.content.pm.UserInfo
+import android.os.Build
+import android.os.UserHandle
+import android.os.UserManager
+import android.os.userManager
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.settings.fakeGlobalSettings
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.stub
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DevelopmentSettingRepositoryTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+
+ private val underTest = kosmos.developmentSettingRepository
+
+ @Test
+ fun nonAdminUser_unrestricted_neverDevelopmentEnabled() =
+ with(kosmos) {
+ testScope.runTest {
+ val userInfo = nonAdminUserInfo
+ val settingEnabled by
+ collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
+
+ setUserRestriction(userInfo.userHandle, restricted = false)
+
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(false)
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(true)
+ assertThat(settingEnabled).isFalse()
+ }
+ }
+
+ @Test
+ fun nonAdminUser_restricted_neverDevelopmentEnabled() =
+ with(kosmos) {
+ testScope.runTest {
+ val userInfo = nonAdminUserInfo
+ val settingEnabled by
+ collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
+
+ setUserRestriction(userInfo.userHandle, restricted = true)
+
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(false)
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(true)
+ assertThat(settingEnabled).isFalse()
+ }
+ }
+
+ @Test
+ fun adminUser_unrestricted_defaultValueOfSetting() =
+ with(kosmos) {
+ testScope.runTest {
+ val userInfo = adminUserInfo
+ val settingEnabled by
+ collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
+
+ setUserRestriction(userInfo.userHandle, restricted = false)
+
+ val defaultValue = Build.TYPE == "eng"
+
+ assertThat(settingEnabled).isEqualTo(defaultValue)
+ }
+ }
+
+ @Test
+ fun adminUser_unrestricted_enabledTracksSetting() =
+ with(kosmos) {
+ testScope.runTest {
+ val userInfo = adminUserInfo
+ val settingEnabled by
+ collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
+
+ setUserRestriction(userInfo.userHandle, restricted = false)
+
+ setSettingValue(false)
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(true)
+ assertThat(settingEnabled).isTrue()
+ }
+ }
+
+ @Test
+ fun adminUser_restricted_neverDevelopmentEnabled() =
+ with(kosmos) {
+ testScope.runTest {
+ val userInfo = adminUserInfo
+ val settingEnabled by
+ collectLastValue(underTest.isDevelopmentSettingEnabled(userInfo))
+
+ setUserRestriction(userInfo.userHandle, restricted = true)
+
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(false)
+ assertThat(settingEnabled).isFalse()
+
+ setSettingValue(true)
+ assertThat(settingEnabled).isFalse()
+ }
+ }
+
+ private companion object {
+ const val USER_RESTRICTION = UserManager.DISALLOW_DEBUGGING_FEATURES
+ const val SETTING_NAME = Settings.Global.DEVELOPMENT_SETTINGS_ENABLED
+
+ val adminUserInfo =
+ UserInfo(
+ /* id= */ 10,
+ /* name= */ "",
+ /* flags */ UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
+ )
+ val nonAdminUserInfo =
+ UserInfo(/* id= */ 11, /* name= */ "", /* flags */ UserInfo.FLAG_FULL)
+
+ fun Kosmos.setUserRestriction(userHandle: UserHandle, restricted: Boolean) {
+ userManager.stub {
+ on { hasUserRestrictionForUser(eq(USER_RESTRICTION), eq(userHandle)) } doReturn
+ restricted
+ }
+ }
+
+ fun Kosmos.setSettingValue(enabled: Boolean) {
+ fakeGlobalSettings.putInt(SETTING_NAME, if (enabled) 1 else 0)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorTest.kt
new file mode 100644
index 000000000000..f29dabe98664
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.domain.interactor
+
+import android.content.ClipData
+import android.content.ClipDescription
+import android.content.clipboardManager
+import android.content.pm.UserInfo
+import android.content.res.mainResources
+import android.os.Build
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.development.shared.model.BuildNumber
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.util.settings.fakeGlobalSettings
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.verify
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class BuildNumberInteractorTest : SysuiTestCase() {
+
+ private val kosmos =
+ testKosmos().apply {
+ fakeUserRepository.setUserInfos(listOf(adminUserInfo, nonAdminUserInfo))
+ }
+
+ private val expectedBuildNumber =
+ BuildNumber(
+ kosmos.mainResources.getString(
+ R.string.bugreport_status,
+ Build.VERSION.RELEASE_OR_CODENAME,
+ Build.ID,
+ )
+ )
+
+ private val clipLabel =
+ kosmos.mainResources.getString(
+ com.android.systemui.res.R.string.build_number_clip_data_label
+ )
+
+ private val underTest = kosmos.buildNumberInteractor
+
+ @Test
+ fun nonAdminUser_settingEnabled_buildNumberNull() =
+ with(kosmos) {
+ testScope.runTest {
+ val buildNumber by collectLastValue(underTest.buildNumber)
+
+ fakeUserRepository.setSelectedUserInfo(nonAdminUserInfo)
+ setSettingValue(true)
+
+ assertThat(buildNumber).isNull()
+ }
+ }
+
+ @Test
+ fun adminUser_buildNumberCorrect_onlyWhenSettingEnabled() =
+ with(kosmos) {
+ testScope.runTest {
+ val buildNumber by collectLastValue(underTest.buildNumber)
+
+ fakeUserRepository.setSelectedUserInfo(adminUserInfo)
+
+ setSettingValue(false)
+ assertThat(buildNumber).isNull()
+
+ setSettingValue(true)
+ assertThat(buildNumber).isEqualTo(expectedBuildNumber)
+ }
+ }
+
+ @Test
+ fun copyToClipboard() =
+ with(kosmos) {
+ testScope.runTest {
+ fakeUserRepository.setSelectedUserInfo(adminUserInfo)
+
+ underTest.copyBuildNumber()
+ runCurrent()
+
+ val argumentCaptor = argumentCaptor<ClipData>()
+
+ verify(clipboardManager).setPrimaryClip(argumentCaptor.capture())
+
+ with(argumentCaptor.firstValue) {
+ assertThat(description.label).isEqualTo(clipLabel)
+ assertThat(description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN))
+ .isTrue()
+ assertThat(itemCount).isEqualTo(1)
+ assertThat(getItemAt(0).text).isEqualTo(expectedBuildNumber.value)
+ }
+ }
+ }
+
+ private companion object {
+ const val SETTING_NAME = Settings.Global.DEVELOPMENT_SETTINGS_ENABLED
+
+ val adminUserInfo =
+ UserInfo(
+ /* id= */ 10,
+ /* name= */ "",
+ /* flags */ UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
+ )
+ val nonAdminUserInfo =
+ UserInfo(/* id= */ 11, /* name= */ "", /* flags */ UserInfo.FLAG_FULL)
+
+ fun Kosmos.setSettingValue(enabled: Boolean) {
+ fakeGlobalSettings.putInt(SETTING_NAME, if (enabled) 1 else 0)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
index f0d79bb83652..47cba0723804 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
@@ -568,6 +568,41 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() {
assertThat(isUnlocked).isFalse()
}
+ @Test
+ fun lockNow() =
+ testScope.runTest {
+ setLockAfterScreenTimeout(5000)
+ val isUnlocked by collectLastValue(underTest.deviceUnlockStatus.map { it.isUnlocked })
+ unlockDevice()
+ assertThat(isUnlocked).isTrue()
+
+ underTest.lockNow()
+ runCurrent()
+
+ assertThat(isUnlocked).isFalse()
+ }
+
+ @Test
+ fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep_fromSleepButton() =
+ testScope.runTest {
+ setLockAfterScreenTimeout(5000)
+ kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false
+ val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
+ kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ runCurrent()
+ assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+
+ kosmos.powerInteractor.setAsleepForTest(
+ sleepReason = PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON
+ )
+ runCurrent()
+
+ assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
+ }
+
private fun TestScope.unlockDevice() {
val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
index c39c3fe5f527..2d54337def13 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
@@ -36,6 +36,7 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.viewmodel.fakeDeviceEntryIconViewModelTransition
import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -43,6 +44,7 @@ import kotlin.test.Test
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
+import org.junit.After
import org.junit.Before
import org.junit.runner.RunWith
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
@@ -84,6 +86,12 @@ class UdfpsAccessibilityOverlayViewModelTest(flags: FlagsParameterization) : Sys
@Before
fun setup() {
underTest = kosmos.deviceEntryUdfpsAccessibilityOverlayViewModel
+ overrideResource(R.integer.udfps_padding_debounce_duration, 0)
+ }
+
+ @After
+ fun teardown() {
+ mContext.orCreateTestableResources.removeOverride(R.integer.udfps_padding_debounce_duration)
}
@Test
@@ -118,6 +126,7 @@ class UdfpsAccessibilityOverlayViewModelTest(flags: FlagsParameterization) : Sys
runCurrent()
assertThat(visible).isFalse()
}
+
fun fpNotRunning_overlayNotVisible() =
testScope.runTest {
val visible by collectLastValue(underTest.visible)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
new file mode 100644
index 000000000000..790df03e6401
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.pm.ServiceInfo
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.service.dreams.IDreamManager
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.core.FakeLogBuffer
+import com.android.systemui.shared.condition.Monitor
+import com.android.systemui.util.mockito.withArgCaptor
+import kotlin.test.Test
+import org.junit.Before
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidJUnit4::class)
+class DreamOverlayRegistrantTest : SysuiTestCase() {
+ private val context = mock<Context>()
+
+ private val packageManager = mock<PackageManager>()
+
+ private val dreamManager = mock<IDreamManager>()
+
+ private val componentName = mock<ComponentName>()
+
+ private val serviceInfo = mock<ServiceInfo>()
+
+ private val monitor = mock<Monitor>()
+
+ private val logBuffer = FakeLogBuffer.Factory.Companion.create()
+
+ private lateinit var underTest: DreamOverlayRegistrant
+
+ @Before
+ fun setup() {
+ underTest =
+ DreamOverlayRegistrant(
+ context,
+ componentName,
+ monitor,
+ packageManager,
+ dreamManager,
+ logBuffer,
+ )
+
+ whenever(packageManager.getComponentEnabledSetting(eq(componentName)))
+ .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)
+ whenever(
+ packageManager.getServiceInfo(
+ eq(componentName),
+ eq(PackageManager.GET_META_DATA or PackageManager.MATCH_DISABLED_COMPONENTS),
+ )
+ )
+ .thenReturn(serviceInfo)
+ whenever(
+ packageManager.setComponentEnabledSetting(
+ eq(componentName),
+ eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+ eq(PackageManager.DONT_KILL_APP),
+ )
+ )
+ .thenAnswer {
+ setComponentEnabledState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED, true)
+ }
+
+ serviceInfo.enabled = false
+ }
+
+ private fun start() {
+ underTest.start()
+ val subscription = withArgCaptor { verify(monitor).addSubscription(capture()) }
+ subscription.callback.onConditionsChanged(true)
+ }
+
+ private fun setComponentEnabledState(enabledState: Int, triggerUpdate: Boolean) {
+ whenever(packageManager.getComponentEnabledSetting(eq(componentName)))
+ .thenReturn(enabledState)
+
+ if (triggerUpdate) {
+ withArgCaptor { verify(context).registerReceiver(capture(), any()) }
+ .onReceive(context, Intent())
+ }
+ }
+
+ /** Verify overlay registered when enabled in manifest. */
+ @Test
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ fun testRegisteredWhenEnabledWithManifest() {
+ serviceInfo.enabled = true
+ start()
+
+ verify(dreamManager).registerDreamOverlayService(componentName)
+ }
+
+ /** Verify overlay registered for mobile hub with flag. */
+ @Test
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ fun testRegisteredForMobileHub() {
+ start()
+
+ verify(dreamManager).registerDreamOverlayService(componentName)
+ }
+
+ /**
+ * Make sure dream overlay not registered when not in manifest and not hub mode on mobile is not
+ * enabled.
+ */
+ @Test
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ fun testDisabledForMobileWithoutMobileHub() {
+ start()
+
+ verify(packageManager, never())
+ .setComponentEnabledSetting(
+ eq(componentName),
+ eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+ eq(PackageManager.DONT_KILL_APP),
+ )
+ verify(dreamManager, never()).registerDreamOverlayService(componentName)
+ }
+
+ /** Ensure service unregistered when component is disabled at runtime. */
+ @Test
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ fun testUnregisteredWhenComponentDisabled() {
+ start()
+ verify(dreamManager).registerDreamOverlayService(componentName)
+ clearInvocations(dreamManager)
+ setComponentEnabledState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, true)
+ verify(dreamManager).registerDreamOverlayService(Mockito.isNull())
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index a65e7ed48797..bbfc9607fed9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -1035,6 +1035,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.RESUMED)
}
+ @DisableFlags(FLAG_SCENE_CONTAINER)
@Test
fun testBouncerShown_setsLifecycleState() {
val client = client
@@ -1067,6 +1068,39 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.RESUMED)
}
+ @EnableFlags(FLAG_SCENE_CONTAINER)
+ @Test
+ fun testBouncerShown_withSceneContainer_setsLifecycleState() {
+ val client = client
+
+ // Inform the overlay service of dream starting.
+ client.startDream(
+ mWindowParams,
+ mDreamOverlayCallback,
+ DREAM_COMPONENT,
+ false /*isPreview*/,
+ false, /*shouldShowComplication*/
+ )
+ mMainExecutor.runAllReady()
+ assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.RESUMED)
+
+ // Bouncer shows.
+ kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "test")
+ testScope.runCurrent()
+ mMainExecutor.runAllReady()
+
+ // Lifecycle state goes from resumed back to started when the bouncer shows.
+ assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.STARTED)
+
+ // Bouncer closes.
+ kosmos.sceneInteractor.changeScene(Scenes.Dream, "test")
+ testScope.runCurrent()
+ mMainExecutor.runAllReady()
+
+ // Lifecycle state goes back to RESUMED.
+ assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.RESUMED)
+ }
+
@Test
@DisableFlags(FLAG_SCENE_CONTAINER)
fun testCommunalVisible_setsLifecycleState() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index b46f2aa61518..5a1d8bbb0bf1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -76,7 +76,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testStateChange_overlayActive() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
stateController.setOverlayActive(true);
mExecutor.runAllReady();
@@ -97,7 +97,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testCallback() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
// Add complication and verify callback is notified.
@@ -122,7 +122,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testNotifyOnCallbackAdd() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addComplication(mComplication);
mExecutor.runAllReady();
@@ -134,22 +134,8 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
}
@Test
- public void testNotifyOnCallbackAddOverlayDisabled() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(false);
-
- stateController.addComplication(mComplication);
- mExecutor.runAllReady();
-
- // Verify callback occurs on add when an overlay is already present.
- stateController.addCallback(mCallback);
- mExecutor.runAllReady();
- verify(mCallback, never()).onComplicationsChanged();
- }
-
-
- @Test
public void testComplicationFilteringWhenShouldShowComplications() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.setShouldShowComplications(true);
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
@@ -188,7 +174,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testComplicationFilteringWhenShouldHideComplications() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.setShouldShowComplications(true);
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
@@ -234,7 +220,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testComplicationWithNoTypeNotFiltered() {
final Complication complication = Mockito.mock(Complication.class);
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addComplication(complication);
mExecutor.runAllReady();
assertThat(stateController.getComplications(true).contains(complication))
@@ -244,7 +230,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testComplicationsNotShownForHomeControlPanelDream() {
final Complication complication = Mockito.mock(Complication.class);
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
// Add a complication and verify it's returned in getComplications.
stateController.addComplication(complication);
@@ -261,7 +247,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testComplicationsNotShownForLowLight() {
final Complication complication = Mockito.mock(Complication.class);
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
// Add a complication and verify it's returned in getComplications.
stateController.addComplication(complication);
@@ -277,7 +263,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testNotifyLowLightChanged() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -292,7 +278,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testNotifyLowLightExit() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -315,7 +301,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testNotifyEntryAnimationsFinishedChanged() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -330,7 +316,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testNotifyDreamOverlayStatusBarVisibleChanged() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -345,7 +331,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
@Test
public void testNotifyHasAssistantAttentionChanged() {
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -362,7 +348,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
public void testShouldShowComplicationsSetToFalse_stillShowsHomeControls_featureEnabled() {
when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true);
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.setShouldShowComplications(true);
final Complication homeControlsComplication = Mockito.mock(Complication.class);
@@ -404,7 +390,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
public void testHomeControlsDoNotShowIfNotAvailable_featureEnabled() {
when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true);
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.setShouldShowComplications(true);
final Complication homeControlsComplication = Mockito.mock(Complication.class);
@@ -435,7 +421,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
final DreamOverlayStateController.Callback callback2 = Mockito.mock(
DreamOverlayStateController.Callback.class);
- final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController();
stateController.addCallback(callback1);
stateController.addCallback(callback2);
mExecutor.runAllReady();
@@ -451,10 +437,9 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
assertThat(stateController.isOverlayActive()).isTrue();
}
- private DreamOverlayStateController getDreamOverlayStateController(boolean overlayEnabled) {
+ private DreamOverlayStateController getDreamOverlayStateController() {
return new DreamOverlayStateController(
mExecutor,
- overlayEnabled,
mFeatureFlags,
mLogBuffer,
mWeakReferenceFactory
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
index aacfaed1ab4a..82bcecef1f70 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
@@ -39,7 +39,6 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Overlays
-import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
import com.android.systemui.shade.data.repository.fakeShadeRepository
@@ -83,7 +82,6 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
shadeMode = ShadeMode.Single,
)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
@@ -101,7 +99,6 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
shadeMode = ShadeMode.Single,
)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
@@ -119,7 +116,6 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
shadeMode = ShadeMode.Split,
)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
@@ -137,7 +133,6 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
shadeMode = ShadeMode.Split,
)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
@@ -155,7 +150,6 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
shadeMode = ShadeMode.Dual,
)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(
@@ -171,7 +165,6 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
setUpState(isShadeTouchable = true, isDeviceUnlocked = true, shadeMode = ShadeMode.Dual)
assertThat(actions).isNotEmpty()
- assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home))
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
index 366b55db4f20..329f90a1006a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
@@ -398,6 +398,16 @@ class QSLongPressEffectTest : SysuiTestCase() {
verify(controller).onTransitionAnimationCancelled(newOccludedState)
}
+ @Test
+ fun onTileLongClick_whileIdle_performsLongClick() =
+ testWhileInState(QSLongPressEffect.State.IDLE) {
+ // WHEN a long-click is detected by the view
+ val longClicks = longPressEffect.onTileLongClick()
+
+ // THEN the long click is handled
+ assertThat(longClicks).isTrue()
+ }
+
private fun testWithScope(initialize: Boolean = true, test: suspend TestScope.() -> Unit) =
with(kosmos) {
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
index cc4c7c419a11..f04540426fc1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
@@ -20,11 +20,21 @@ import android.content.Context
import android.content.Context.INPUT_SERVICE
import android.hardware.input.InputGestureData
import android.hardware.input.InputGestureData.createKeyTrigger
-import android.hardware.input.KeyGestureEvent
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
import android.hardware.input.fakeInputManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import android.view.KeyEvent
+import android.view.KeyEvent.KEYCODE_A
+import android.view.KeyEvent.KEYCODE_SLASH
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CAPS_LOCK_ON
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_FUNCTION_ON
+import android.view.KeyEvent.META_META_LEFT_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyEvent.META_SHIFT_RIGHT_ON
+import android.view.KeyEvent.META_SYM_ON
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES
@@ -32,17 +42,16 @@ import com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyboard.shortcut.customShortcutCategoriesRepository
-import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.AppCategories
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.userTracker
import com.android.systemui.testKosmos
@@ -83,7 +92,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
whenever(
fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
)
- .thenReturn(customizableInputGesturesWithSimpleShortcutCombinations)
+ .thenReturn(allCustomizableInputGesturesWithSimpleShortcutCombinations)
helper.toggle(deviceId = 123)
val categories by collectLastValue(repo.categories)
@@ -100,7 +109,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
whenever(
fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
)
- .thenReturn(customizableInputGesturesWithSimpleShortcutCombinations)
+ .thenReturn(allCustomizableInputGesturesWithSimpleShortcutCombinations)
helper.toggle(deviceId = 123)
val categories by collectLastValue(repo.categories)
@@ -125,167 +134,147 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
}
}
- private fun simpleInputGestureData(
- keyCode: Int = KeyEvent.KEYCODE_A,
- modifiers: Int = KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
- keyGestureType: Int,
- ): InputGestureData {
- val builder = InputGestureData.Builder()
- builder.setKeyGestureType(keyGestureType)
- builder.setTrigger(createKeyTrigger(keyCode, modifiers))
- return builder.build()
+ @Test
+ fun pressedKeys_isEmptyByDefault() {
+ testScope.runTest {
+ val pressedKeys by collectLastValue(repo.pressedKeys)
+ assertThat(pressedKeys).isEmpty()
+
+ helper.toggle(deviceId = 123)
+ assertThat(pressedKeys).isEmpty()
+ }
}
- private fun simpleShortcutCategory(
- category: ShortcutCategoryType,
- subcategoryLabel: String,
- shortcutLabel: String,
- ): ShortcutCategory {
- return ShortcutCategory(
- type = category,
- subCategories =
- listOf(
- ShortcutSubCategory(
- label = subcategoryLabel,
- shortcuts = listOf(simpleShortcut(shortcutLabel)),
- )
- ),
- )
+ @Test
+ fun pressedKeys_recognizesAllSupportedModifiers() {
+ testScope.runTest {
+ helper.toggle(deviceId = 123)
+ val pressedKeys by collectLastValue(repo.pressedKeys)
+ repo.updateUserKeyCombination(
+ KeyCombination(modifiers = allSupportedModifiers, keyCode = null)
+ )
+
+ assertThat(pressedKeys)
+ .containsExactly(
+ ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
+ ShortcutKey.Text("Ctrl"),
+ ShortcutKey.Text("Fn"),
+ ShortcutKey.Text("Shift"),
+ ShortcutKey.Text("Alt"),
+ ShortcutKey.Text("Sym"),
+ )
+ }
}
- private fun simpleShortcut(label: String) =
- Shortcut(
- label = label,
- commands =
- listOf(
- ShortcutCommand(
- isCustom = true,
- keys =
- listOf(
- ShortcutKey.Text("Ctrl"),
- ShortcutKey.Text("Alt"),
- ShortcutKey.Text("A"),
- ),
- )
- ),
- )
+ @Test
+ fun pressedKeys_ignoresUnsupportedModifiers() {
+ testScope.runTest {
+ helper.toggle(deviceId = 123)
+ val pressedKeys by collectLastValue(repo.pressedKeys)
+ repo.updateUserKeyCombination(
+ KeyCombination(modifiers = META_CAPS_LOCK_ON, keyCode = null)
+ )
- private val customizableInputGestureWithUnknownKeyGestureType =
- // These key gesture events are currently not supported by shortcut helper customizer
- listOf(
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS
- ),
- simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY),
- )
+ assertThat(pressedKeys).isEmpty()
+ }
+ }
+
+ @Test
+ fun pressedKeys_assertCorrectConversion() {
+ testScope.runTest {
+ helper.toggle(deviceId = 123)
+ val pressedKeys by collectLastValue(repo.pressedKeys)
+ repo.updateUserKeyCombination(
+ KeyCombination(modifiers = META_META_ON, keyCode = KEYCODE_SLASH)
+ )
+
+ assertThat(pressedKeys)
+ .containsExactly(
+ ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
+ ShortcutKey.Text("/"),
+ )
+ }
+ }
+
+ @Test
+ fun shortcutBeingCustomized_updatedOnCustomizationRequested() {
+ testScope.runTest {
+ repo.onCustomizationRequested(standardCustomizationRequestInfo)
- private val expectedShortcutCategoriesWithSimpleShortcutCombination =
- listOf(
- simpleShortcutCategory(System, "System apps", "Open assistant"),
- simpleShortcutCategory(System, "System controls", "Go to home screen"),
- simpleShortcutCategory(System, "System apps", "Open settings"),
- simpleShortcutCategory(System, "System controls", "Lock screen"),
- simpleShortcutCategory(System, "System controls", "View notifications"),
- simpleShortcutCategory(System, "System apps", "Take a note"),
- simpleShortcutCategory(System, "System controls", "Take screenshot"),
- simpleShortcutCategory(System, "System controls", "Go back"),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Switch from split screen to full screen",
- ),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Use split screen with current app on the left",
- ),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Switch to app on left or above while using split screen",
- ),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Use split screen with current app on the right",
- ),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Switch to app on right or below while using split screen",
- ),
- simpleShortcutCategory(System, "System controls", "Show shortcuts"),
- simpleShortcutCategory(System, "System controls", "View recent apps"),
- simpleShortcutCategory(AppCategories, "Applications", "Calculator"),
- simpleShortcutCategory(AppCategories, "Applications", "Calendar"),
- simpleShortcutCategory(AppCategories, "Applications", "Browser"),
- simpleShortcutCategory(AppCategories, "Applications", "Contacts"),
- simpleShortcutCategory(AppCategories, "Applications", "Email"),
- simpleShortcutCategory(AppCategories, "Applications", "Maps"),
- simpleShortcutCategory(AppCategories, "Applications", "SMS"),
- simpleShortcutCategory(MultiTasking, "Recent apps", "Cycle forward through recent apps"),
+ val shortcutBeingCustomized = repo.getShortcutBeingCustomized()
+
+ assertThat(shortcutBeingCustomized).isEqualTo(standardCustomizationRequestInfo)
+ }
+ }
+
+ @Test
+ fun buildInputGestureDataForShortcutBeingCustomized_noShortcutBeingCustomized_returnsNull() {
+ testScope.runTest {
+ helper.toggle(deviceId = 123)
+ repo.updateUserKeyCombination(standardKeyCombination)
+
+ val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
+
+ assertThat(inputGestureData).isNull()
+ }
+ }
+
+ @Test
+ fun buildInputGestureDataForShortcutBeingCustomized_noKeyCombinationSelected_returnsNull() {
+ testScope.runTest {
+ helper.toggle(deviceId = 123)
+ repo.onCustomizationRequested(standardCustomizationRequestInfo)
+
+ val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
+
+ assertThat(inputGestureData).isNull()
+ }
+ }
+
+ @Test
+ fun buildInputGestureDataForShortcutBeingCustomized_successfullyBuildInputGestureData() {
+ testScope.runTest {
+ helper.toggle(deviceId = 123)
+ repo.onCustomizationRequested(standardCustomizationRequestInfo)
+ repo.updateUserKeyCombination(standardKeyCombination)
+ val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
+
+ // using toString as we're testing for only structural equality not referential.
+ // inputGestureData is a java class and isEqual Tests for referential equality
+ // as well which would cause this assert to fail
+ assertThat(inputGestureData.toString()).isEqualTo(standardInputGestureData.toString())
+ }
+ }
+
+ private val standardCustomizationRequestInfo =
+ ShortcutCustomizationRequestInfo.Add(
+ label = "Open apps list",
+ categoryType = ShortcutCategoryType.System,
+ subCategoryLabel = "System controls",
)
- private val customizableInputGesturesWithSimpleShortcutCombinations =
- listOf(
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT
- ),
- simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_HOME),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS
- ),
- simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL
- ),
- simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_NOTES),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT
- ),
- simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_BACK),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER
- ),
- simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER
- ),
+ private val standardKeyCombination =
+ KeyCombination(
+ modifiers = META_META_ON or META_SHIFT_ON or META_META_LEFT_ON or META_SHIFT_RIGHT_ON,
+ keyCode = KEYCODE_A,
)
+
+ private val allSupportedModifiers =
+ META_META_ON or
+ META_CTRL_ON or
+ META_FUNCTION_ON or
+ META_SHIFT_ON or
+ META_ALT_ON or
+ META_SYM_ON
+
+ private val standardInputGestureData =
+ InputGestureData.Builder()
+ .setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
+ .setTrigger(
+ createKeyTrigger(
+ /* keycode = */ standardKeyCombination.keyCode!!,
+ /* modifierState = */ standardKeyCombination.modifiers and allSupportedModifiers,
+ )
+ )
+ .build()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index c9c39b3ebf66..a1e7ef4ac5a3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -16,11 +16,20 @@
package com.android.systemui.keyboard.shortcut.data.source
+import android.hardware.input.InputGestureData
+import android.hardware.input.InputGestureData.createKeyTrigger
+import android.hardware.input.KeyGestureEvent
import android.view.KeyEvent
import android.view.KeyboardShortcutGroup
import android.view.KeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.AppCategories
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import com.android.systemui.keyboard.shortcut.shared.model.shortcut
import com.android.systemui.res.R
@@ -64,6 +73,13 @@ object TestShortcuts {
}
}
+ private val goHomeShortcutInfo =
+ KeyboardShortcutInfo(
+ /* label = */ "Go to home screen",
+ /* keycode = */ KeyEvent.KEYCODE_B,
+ /* modifiers = */ KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
+ )
+
private val standardShortcutInfo1 =
KeyboardShortcutInfo(
/* label = */ "Standard shortcut 1",
@@ -79,6 +95,16 @@ object TestShortcuts {
}
}
+ private val customGoHomeShortcut =
+ shortcut("Go to home screen") {
+ command {
+ key("Ctrl")
+ key("Alt")
+ key("A")
+ isCustom(true)
+ }
+ }
+
private val standardShortcutInfo2 =
KeyboardShortcutInfo(
/* label = */ "Standard shortcut 2",
@@ -123,35 +149,38 @@ object TestShortcuts {
listOf(
shortcutInfoWithRepeatedLabel,
shortcutInfoWithRepeatedLabelAlternate,
- shortcutInfoWithRepeatedLabelSecondAlternate
- )
+ shortcutInfoWithRepeatedLabelSecondAlternate,
+ ),
)
private val subCategoryWithGroupedRepeatedShortcutLabels =
ShortcutSubCategory(
label = groupWithRepeatedShortcutLabels.label!!.toString(),
- shortcuts = listOf(shortcutWithGroupedRepeatedLabel)
+ shortcuts = listOf(shortcutWithGroupedRepeatedLabel),
)
private val groupWithStandardShortcutInfo =
KeyboardShortcutGroup("Standard group", listOf(standardShortcutInfo1))
+ val groupWithGoHomeShortcutInfo =
+ KeyboardShortcutGroup("System controls", listOf(goHomeShortcutInfo))
+
private val subCategoryWithStandardShortcut =
ShortcutSubCategory(
label = groupWithStandardShortcutInfo.label!!.toString(),
- shortcuts = listOf(standardShortcut1)
+ shortcuts = listOf(standardShortcut1),
)
private val groupWithOnlyUnsupportedModifierShortcut =
KeyboardShortcutGroup(
"Group with unsupported modifiers",
- listOf(shortcutInfoWithUnsupportedModifiers)
+ listOf(shortcutInfoWithUnsupportedModifiers),
)
private val groupWithSupportedAndUnsupportedModifierShortcut =
KeyboardShortcutGroup(
"Group with mix of supported and not supported modifiers",
- listOf(standardShortcutInfo3, shortcutInfoWithUnsupportedModifiers)
+ listOf(standardShortcutInfo3, shortcutInfoWithUnsupportedModifiers),
)
private val switchToNextLanguageShortcut =
@@ -174,19 +203,19 @@ object TestShortcuts {
private val subCategoryForInputLanguageSwitchShortcuts =
ShortcutSubCategory(
"Input",
- listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut)
+ listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut),
)
private val subCategoryWithUnsupportedShortcutsRemoved =
ShortcutSubCategory(
groupWithSupportedAndUnsupportedModifierShortcut.label!!.toString(),
- listOf(standardShortcut3)
+ listOf(standardShortcut3),
)
private val standardGroup1 =
KeyboardShortcutGroup(
"Standard group 1",
- listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3)
+ listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3),
)
private val standardPackageName1 = "standard.app.group1"
@@ -194,38 +223,63 @@ object TestShortcuts {
private val standardAppGroup1 =
KeyboardShortcutGroup(
"Standard app group 1",
- listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3)
+ listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3),
)
.apply { packageName = standardPackageName1 }
+ private val standardSystemAppSubcategoryWithCustomHomeShortcut =
+ ShortcutSubCategory("System controls", listOf(customGoHomeShortcut))
+
private val standardSubCategory1 =
ShortcutSubCategory(
standardGroup1.label!!.toString(),
- listOf(standardShortcut1, standardShortcut2, standardShortcut3)
+ listOf(standardShortcut1, standardShortcut2, standardShortcut3),
)
private val standardGroup2 =
KeyboardShortcutGroup(
"Standard group 2",
- listOf(standardShortcutInfo3, standardShortcutInfo2, standardShortcutInfo1)
+ listOf(standardShortcutInfo3, standardShortcutInfo2, standardShortcutInfo1),
)
private val standardSubCategory2 =
ShortcutSubCategory(
standardGroup2.label!!.toString(),
- listOf(standardShortcut3, standardShortcut2, standardShortcut1)
+ listOf(standardShortcut3, standardShortcut2, standardShortcut1),
)
private val standardGroup3 =
KeyboardShortcutGroup(
"Standard group 3",
- listOf(standardShortcutInfo2, standardShortcutInfo1)
+ listOf(standardShortcutInfo2, standardShortcutInfo1),
)
private val standardSubCategory3 =
ShortcutSubCategory(
standardGroup3.label!!.toString(),
- listOf(standardShortcut2, standardShortcut1)
+ listOf(standardShortcut2, standardShortcut1),
+ )
+
+ private val systemSubCategoryWithGoHomeShortcuts =
+ ShortcutSubCategory(
+ label = "System controls",
+ shortcuts =
+ listOf(
+ shortcut("Go to home screen") {
+ command {
+ key("Ctrl")
+ key("Alt")
+ key("B")
+ }
+ command {
+ key("Ctrl")
+ key("Alt")
+ key("A")
+ isCustom(true)
+ }
+ }
+ ),
)
+
val imeGroups = listOf(standardGroup1, standardGroup2, standardGroup3)
val imeCategory =
ShortcutCategory(
@@ -235,8 +289,8 @@ object TestShortcuts {
subCategoryForInputLanguageSwitchShortcuts,
standardSubCategory1,
standardSubCategory2,
- standardSubCategory3
- )
+ standardSubCategory3,
+ ),
)
val currentAppGroups = listOf(standardAppGroup1)
@@ -245,15 +299,33 @@ object TestShortcuts {
val systemGroups = listOf(standardGroup3, standardGroup2, standardGroup1)
val systemCategory =
ShortcutCategory(
- type = ShortcutCategoryType.System,
- subCategories = listOf(standardSubCategory3, standardSubCategory2, standardSubCategory1)
+ type = System,
+ subCategories = listOf(standardSubCategory3, standardSubCategory2, standardSubCategory1),
+ )
+
+ val systemCategoryWithMergedGoHomeShortcut =
+ ShortcutCategory(
+ type = System,
+ subCategories = listOf(systemSubCategoryWithGoHomeShortcuts),
+ )
+
+ val systemCategoryWithCustomHomeShortcut =
+ ShortcutCategory(
+ type = System,
+ subCategories =
+ listOf(
+ standardSubCategory3,
+ standardSubCategory2,
+ standardSubCategory1,
+ standardSystemAppSubcategoryWithCustomHomeShortcut,
+ ),
)
val multitaskingGroups = listOf(standardGroup2, standardGroup1)
val multitaskingCategory =
ShortcutCategory(
- type = ShortcutCategoryType.MultiTasking,
- subCategories = listOf(standardSubCategory2, standardSubCategory1)
+ type = MultiTasking,
+ subCategories = listOf(standardSubCategory2, standardSubCategory1),
)
val groupsWithDuplicateShortcutLabels =
@@ -266,14 +338,14 @@ object TestShortcuts {
listOf(
subCategoryForInputLanguageSwitchShortcuts,
subCategoryWithGroupedRepeatedShortcutLabels,
- subCategoryWithStandardShortcut
+ subCategoryWithStandardShortcut,
)
val groupsWithUnsupportedModifier =
listOf(
groupWithStandardShortcutInfo,
groupWithOnlyUnsupportedModifierShortcut,
- groupWithSupportedAndUnsupportedModifierShortcut
+ groupWithSupportedAndUnsupportedModifierShortcut,
)
val subCategoriesWithUnsupportedModifiersRemoved =
@@ -283,8 +355,174 @@ object TestShortcuts {
listOf(
subCategoryForInputLanguageSwitchShortcuts,
subCategoryWithStandardShortcut,
- subCategoryWithUnsupportedShortcutsRemoved
+ subCategoryWithUnsupportedShortcutsRemoved,
)
val groupsWithOnlyUnsupportedModifiers = listOf(groupWithOnlyUnsupportedModifierShortcut)
+
+ private fun simpleInputGestureData(
+ keyCode: Int = KeyEvent.KEYCODE_A,
+ modifiers: Int = KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
+ keyGestureType: Int,
+ ): InputGestureData {
+ val builder = InputGestureData.Builder()
+ builder.setKeyGestureType(keyGestureType)
+ builder.setTrigger(createKeyTrigger(keyCode, modifiers))
+ return builder.build()
+ }
+
+ private fun simpleShortcutCategory(
+ category: ShortcutCategoryType,
+ subcategoryLabel: String,
+ shortcutLabel: String,
+ ): ShortcutCategory {
+ return ShortcutCategory(
+ type = category,
+ subCategories =
+ listOf(
+ ShortcutSubCategory(
+ label = subcategoryLabel,
+ shortcuts = listOf(simpleShortcut(shortcutLabel)),
+ )
+ ),
+ )
+ }
+
+ private fun simpleShortcut(label: String) =
+ Shortcut(
+ label = label,
+ commands =
+ listOf(
+ ShortcutCommand(
+ isCustom = true,
+ keys =
+ listOf(
+ ShortcutKey.Text("Ctrl"),
+ ShortcutKey.Text("Alt"),
+ ShortcutKey.Text("A"),
+ ),
+ )
+ ),
+ )
+
+ val customizableInputGestureWithUnknownKeyGestureType =
+ // These key gesture events are currently not supported by shortcut helper customizer
+ listOf(
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS
+ ),
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY),
+ )
+
+ val expectedShortcutCategoriesWithSimpleShortcutCombination =
+ listOf(
+ simpleShortcutCategory(System, "System apps", "Open assistant"),
+ simpleShortcutCategory(System, "System controls", "Go to home screen"),
+ simpleShortcutCategory(System, "System apps", "Open settings"),
+ simpleShortcutCategory(System, "System controls", "Lock screen"),
+ simpleShortcutCategory(System, "System controls", "View notifications"),
+ simpleShortcutCategory(System, "System apps", "Take a note"),
+ simpleShortcutCategory(System, "System controls", "Take screenshot"),
+ simpleShortcutCategory(System, "System controls", "Go back"),
+ simpleShortcutCategory(
+ MultiTasking,
+ "Split screen",
+ "Switch from split screen to full screen",
+ ),
+ simpleShortcutCategory(
+ MultiTasking,
+ "Split screen",
+ "Use split screen with current app on the left",
+ ),
+ simpleShortcutCategory(
+ MultiTasking,
+ "Split screen",
+ "Switch to app on left or above while using split screen",
+ ),
+ simpleShortcutCategory(
+ MultiTasking,
+ "Split screen",
+ "Use split screen with current app on the right",
+ ),
+ simpleShortcutCategory(
+ MultiTasking,
+ "Split screen",
+ "Switch to app on right or below while using split screen",
+ ),
+ simpleShortcutCategory(System, "System controls", "Show shortcuts"),
+ simpleShortcutCategory(System, "System controls", "View recent apps"),
+ simpleShortcutCategory(AppCategories, "Applications", "Calculator"),
+ simpleShortcutCategory(AppCategories, "Applications", "Calendar"),
+ simpleShortcutCategory(AppCategories, "Applications", "Browser"),
+ simpleShortcutCategory(AppCategories, "Applications", "Contacts"),
+ simpleShortcutCategory(AppCategories, "Applications", "Email"),
+ simpleShortcutCategory(AppCategories, "Applications", "Maps"),
+ simpleShortcutCategory(AppCategories, "Applications", "SMS"),
+ simpleShortcutCategory(MultiTasking, "Recent apps", "Cycle forward through recent apps"),
+ )
+ val customInputGestureTypeHome =
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_HOME)
+
+ val allCustomizableInputGesturesWithSimpleShortcutCombinations =
+ listOf(
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT
+ ),
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_HOME),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS
+ ),
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL
+ ),
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_NOTES),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT
+ ),
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_BACK),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER
+ ),
+ simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING
+ ),
+ simpleInputGestureData(
+ keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER
+ ),
+ )
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
index 57c8b444b922..f7c77017e239 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
@@ -16,12 +16,24 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
+import android.content.Context
+import android.content.Context.INPUT_SERVICE
+import android.hardware.input.InputGestureData
+import android.hardware.input.fakeInputManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customInputGestureTypeHome
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.groupWithGoHomeShortcutInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.systemCategoryWithCustomHomeShortcut
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.systemCategoryWithMergedGoHomeShortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.InputMethodEditor
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
@@ -34,6 +46,8 @@ import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSourc
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.userTracker
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -42,13 +56,18 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
+ private val mockUserContext: Context = mock()
private val systemShortcutsSource = FakeKeyboardShortcutGroupsSource()
private val multitaskingShortcutsSource = FakeKeyboardShortcutGroupsSource()
+
@OptIn(ExperimentalCoroutinesApi::class)
private val kosmos =
testKosmos().also {
@@ -57,17 +76,23 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
it.shortcutHelperMultiTaskingShortcutsSource = multitaskingShortcutsSource
it.shortcutHelperAppCategoriesShortcutsSource = FakeKeyboardShortcutGroupsSource()
it.shortcutHelperCurrentAppShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
}
+ private val fakeInputManager = kosmos.fakeInputManager
private val testScope = kosmos.testScope
- private val interactor = kosmos.shortcutHelperCategoriesInteractor
+ private lateinit var interactor: ShortcutHelperCategoriesInteractor
private val helper = kosmos.shortcutHelperTestHelper
+ private val inter by lazy { kosmos.shortcutHelperCategoriesInteractor }
@Before
fun setShortcuts() {
+ interactor = kosmos.shortcutHelperCategoriesInteractor
helper.setImeShortcuts(TestShortcuts.imeGroups)
systemShortcutsSource.setGroups(TestShortcuts.systemGroups)
multitaskingShortcutsSource.setGroups(TestShortcuts.multitaskingGroups)
+ whenever(mockUserContext.getSystemService(INPUT_SERVICE))
+ .thenReturn(fakeInputManager.inputManager)
}
@Test
@@ -120,7 +145,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
ShortcutCategory(
type = InputMethodEditor,
subCategories =
- TestShortcuts.imeSubCategoriesWithGroupedDuplicatedShortcutLabels
+ TestShortcuts.imeSubCategoriesWithGroupedDuplicatedShortcutLabels,
),
)
.inOrder()
@@ -140,7 +165,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
ShortcutCategory(
type = System,
subCategories =
- TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels
+ TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels,
),
TestShortcuts.multitaskingCategory,
TestShortcuts.imeCategory,
@@ -163,7 +188,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
ShortcutCategory(
type = MultiTasking,
subCategories =
- TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels
+ TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels,
),
TestShortcuts.imeCategory,
)
@@ -185,7 +210,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
ShortcutCategory(
type = InputMethodEditor,
subCategories =
- TestShortcuts.imeSubCategoriesWithUnsupportedModifiersRemoved
+ TestShortcuts.imeSubCategoriesWithUnsupportedModifiersRemoved,
),
)
.inOrder()
@@ -203,7 +228,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
.containsExactly(
ShortcutCategory(
type = System,
- subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved
+ subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved,
),
TestShortcuts.multitaskingCategory,
TestShortcuts.imeCategory,
@@ -224,7 +249,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
TestShortcuts.systemCategory,
ShortcutCategory(
type = MultiTasking,
- subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved
+ subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved,
),
TestShortcuts.imeCategory,
)
@@ -240,10 +265,7 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
helper.showFromActivity()
assertThat(categories)
- .containsExactly(
- TestShortcuts.multitaskingCategory,
- TestShortcuts.imeCategory,
- )
+ .containsExactly(TestShortcuts.multitaskingCategory, TestShortcuts.imeCategory)
.inOrder()
}
@@ -256,10 +278,63 @@ class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
helper.showFromActivity()
assertThat(categories)
+ .containsExactly(TestShortcuts.systemCategory, TestShortcuts.imeCategory)
+ .inOrder()
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_KEYBOARD_SHORTCUT_HELPER_SHORTCUT_CUSTOMIZER)
+ fun categories_excludesCustomShortcutsWhenFlagIsOff() {
+ testScope.runTest {
+ setCustomInputGestures(allCustomizableInputGesturesWithSimpleShortcutCombinations)
+ helper.showFromActivity()
+ val categories by collectLastValue(interactor.shortcutCategories)
+ assertThat(categories)
.containsExactly(
TestShortcuts.systemCategory,
+ TestShortcuts.multitaskingCategory,
+ TestShortcuts.imeCategory,
+ )
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_SHORTCUT_HELPER_SHORTCUT_CUSTOMIZER)
+ fun categories_includesCustomShortcutsWhenFlagIsOn() {
+ testScope.runTest {
+ setCustomInputGestures(listOf(customInputGestureTypeHome))
+ helper.showFromActivity()
+ val categories by collectLastValue(interactor.shortcutCategories)
+ assertThat(categories)
+ .containsExactly(
+ systemCategoryWithCustomHomeShortcut,
+ TestShortcuts.multitaskingCategory,
+ TestShortcuts.imeCategory,
+ )
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_SHORTCUT_HELPER_SHORTCUT_CUSTOMIZER)
+ fun categories_correctlyMergesDefaultAndCustomShortcutsOfSameType() {
+ testScope.runTest {
+ setCustomInputGestures(listOf(customInputGestureTypeHome))
+ systemShortcutsSource.setGroups(groupWithGoHomeShortcutInfo)
+ helper.showFromActivity()
+
+ val categories by collectLastValue(interactor.shortcutCategories)
+
+ assertThat(categories)
+ .containsExactly(
+ systemCategoryWithMergedGoHomeShortcut,
+ TestShortcuts.multitaskingCategory,
TestShortcuts.imeCategory,
)
- .inOrder()
}
+ }
+
+ private fun setCustomInputGestures(customInputGestures: List<InputGestureData>) {
+ whenever(fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
+ .thenReturn(customInputGestures)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
index 1580ea5c1272..000024f9b814 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
@@ -16,6 +16,9 @@
package com.android.systemui.keyboard.shortcut.ui
+import android.content.Context
+import android.content.Context.INPUT_SERVICE
+import android.hardware.input.fakeInputManager
import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -36,6 +39,8 @@ import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.activityStarter
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.userTracker
import com.android.systemui.statusbar.phone.systemUIDialogFactory
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -44,6 +49,8 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -52,7 +59,7 @@ class ShortcutHelperDialogStarterTest : SysuiTestCase() {
private val fakeSystemSource = FakeKeyboardShortcutGroupsSource()
private val fakeMultiTaskingSource = FakeKeyboardShortcutGroupsSource()
-
+ private val mockUserContext: Context = mock()
private val kosmos =
Kosmos().also {
it.testCase = this
@@ -62,8 +69,10 @@ class ShortcutHelperDialogStarterTest : SysuiTestCase() {
it.shortcutHelperAppCategoriesShortcutsSource = FakeKeyboardShortcutGroupsSource()
it.shortcutHelperInputShortcutsSource = FakeKeyboardShortcutGroupsSource()
it.shortcutHelperCurrentAppShortcutsSource = FakeKeyboardShortcutGroupsSource()
+ it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
}
+ private val inputManager = kosmos.fakeInputManager.inputManager
private val testScope = kosmos.testScope
private val testHelper = kosmos.shortcutHelperTestHelper
private val dialogFactory = kosmos.systemUIDialogFactory
@@ -85,6 +94,7 @@ class ShortcutHelperDialogStarterTest : SysuiTestCase() {
fun setUp() {
fakeSystemSource.setGroups(TestShortcuts.systemGroups)
fakeMultiTaskingSource.setGroups(TestShortcuts.multitaskingGroups)
+ whenever(mockUserContext.getSystemService(INPUT_SERVICE)).thenReturn(inputManager)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
new file mode 100644
index 000000000000..77c615cce287
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.communalSceneRepository
+import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalEnabled
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.andSceneContainer
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+@EnableFlags(Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON)
+@RunWith(ParameterizedAndroidJunit4::class)
+class GlanceableHubQuickAffordanceConfigTest(flags: FlagsParameterization?) : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ private lateinit var underTest: GlanceableHubQuickAffordanceConfig
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags!!)
+ }
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ underTest =
+ GlanceableHubQuickAffordanceConfig(
+ context = context,
+ communalInteractor = kosmos.communalInteractor,
+ communalSceneRepository = kosmos.communalSceneRepository,
+ sceneInteractor = kosmos.sceneInteractor,
+ )
+ }
+
+ @Test
+ fun lockscreenState_whenGlanceableHubEnabled_returnsVisible() =
+ testScope.runTest {
+ kosmos.setCommunalEnabled(true)
+ runCurrent()
+
+ val lockScreenState by collectLastValue(underTest.lockScreenState)
+
+ assertTrue(lockScreenState is KeyguardQuickAffordanceConfig.LockScreenState.Visible)
+ }
+
+ @Test
+ fun lockscreenState_whenGlanceableHubDisabled_returnsHidden() =
+ testScope.runTest {
+ kosmos.setCommunalEnabled(false)
+ val lockScreenState by collectLastValue(underTest.lockScreenState)
+ runCurrent()
+
+ assertTrue(lockScreenState is KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
+ }
+
+ @Test
+ fun pickerScreenState_whenGlanceableHubEnabled_returnsDefault() =
+ testScope.runTest {
+ kosmos.setCommunalEnabled(true)
+ runCurrent()
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
+ }
+
+ @Test
+ fun pickerScreenState_whenGlanceableHubDisabled_returnsDisabled() =
+ testScope.runTest {
+ kosmos.setCommunalEnabled(false)
+ runCurrent()
+
+ assertThat(
+ underTest.getPickerScreenState()
+ is KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
+ )
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_SCENE_CONTAINER)
+ fun onTriggered_changesSceneToCommunal() =
+ testScope.runTest {
+ underTest.onTriggered(expandable = null)
+ runCurrent()
+
+ assertThat(kosmos.communalSceneRepository.currentScene.value)
+ .isEqualTo(CommunalScenes.Communal)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SCENE_CONTAINER)
+ fun testTransitionToGlanceableHub_sceneContainer() =
+ testScope.runTest {
+ underTest.onTriggered(expandable = null)
+ runCurrent()
+
+ assertThat(kosmos.sceneContainerRepository.currentScene.value)
+ .isEqualTo(Scenes.Communal)
+ }
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf(
+ Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON
+ )
+ .andSceneContainer()
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
index 92764ae94271..74a0bafda931 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
@@ -17,6 +17,10 @@
package com.android.systemui.keyguard.ui.binder
import android.app.IActivityTaskManager
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -25,8 +29,10 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardDismissTransition
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
+import com.android.window.flags.Flags
import com.android.wm.shell.keyguard.KeyguardTransitions
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
@@ -41,6 +47,9 @@ import org.mockito.kotlin.any
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
+
+ @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
private lateinit var underTest: WindowManagerLockscreenVisibilityManager
private lateinit var executor: FakeExecutor
@@ -68,32 +77,62 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
}
@Test
- fun testLockscreenVisible_andAodVisible() {
+ @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testLockscreenVisible_andAodVisible_without_keyguard_shell_transitions() {
underTest.setLockscreenShown(true)
- underTest.setAodVisible(true)
-
verify(activityTaskManagerService).setLockScreenShown(true, false)
+ underTest.setAodVisible(true)
verify(activityTaskManagerService).setLockScreenShown(true, true)
+
verifyNoMoreInteractions(activityTaskManagerService)
}
@Test
- fun testGoingAway_whenLockscreenVisible_thenSurfaceMadeVisible() {
+ @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testLockscreenVisible_andAodVisible_with_keyguard_shell_transitions() {
underTest.setLockscreenShown(true)
+ verify(keyguardTransitions).startKeyguardTransition(true, false)
underTest.setAodVisible(true)
+ verify(keyguardTransitions).startKeyguardTransition(true, true)
+ verifyNoMoreInteractions(keyguardTransitions)
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testGoingAway_whenLockscreenVisible_thenSurfaceMadeVisible_without_keyguard_shell_transitions() {
+ underTest.setLockscreenShown(true)
verify(activityTaskManagerService).setLockScreenShown(true, false)
+ underTest.setAodVisible(true)
verify(activityTaskManagerService).setLockScreenShown(true, true)
+
verifyNoMoreInteractions(activityTaskManagerService)
underTest.setSurfaceBehindVisibility(true)
-
verify(activityTaskManagerService).keyguardGoingAway(anyInt())
+
verifyNoMoreInteractions(activityTaskManagerService)
}
@Test
- fun testSurfaceVisible_whenLockscreenNotShowing_doesNotTriggerGoingAway() {
+ @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testGoingAway_whenLockscreenVisible_thenSurfaceMadeVisible_with_keyguard_shell_transitions() {
+ underTest.setLockscreenShown(true)
+ verify(keyguardTransitions).startKeyguardTransition(true, false)
+ underTest.setAodVisible(true)
+ verify(keyguardTransitions).startKeyguardTransition(true, true)
+
+ verifyNoMoreInteractions(keyguardTransitions)
+
+ underTest.setSurfaceBehindVisibility(true)
+ verify(keyguardTransitions).startKeyguardTransition(false, false)
+
+ verifyNoMoreInteractions(keyguardTransitions)
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testSurfaceVisible_whenLockscreenNotShowing_doesNotTriggerGoingAway_without_keyguard_shell_transitions() {
underTest.setLockscreenShown(false)
underTest.setAodVisible(false)
@@ -106,7 +145,22 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
}
@Test
- fun testAodVisible_noLockscreenShownCallYet_doesNotShowLockscreenUntilLater() {
+ @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testSurfaceVisible_whenLockscreenNotShowing_doesNotTriggerGoingAway_with_keyguard_shell_transitions() {
+ underTest.setLockscreenShown(false)
+ underTest.setAodVisible(false)
+
+ verify(keyguardTransitions).startKeyguardTransition(false, false)
+ verifyNoMoreInteractions(keyguardTransitions)
+
+ underTest.setSurfaceBehindVisibility(true)
+
+ verifyNoMoreInteractions(keyguardTransitions)
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testAodVisible_noLockscreenShownCallYet_doesNotShowLockscreenUntilLater_without_keyguard_shell_transitions() {
underTest.setAodVisible(false)
verifyNoMoreInteractions(activityTaskManagerService)
@@ -116,7 +170,19 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
}
@Test
- fun setSurfaceBehindVisibility_goesAwayFirst_andIgnoresSecondCall() {
+ @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun testAodVisible_noLockscreenShownCallYet_doesNotShowLockscreenUntilLater_with_keyguard_shell_transitions() {
+ underTest.setAodVisible(false)
+ verifyNoMoreInteractions(keyguardTransitions)
+
+ underTest.setLockscreenShown(true)
+ verify(keyguardTransitions).startKeyguardTransition(true, false)
+ verifyNoMoreInteractions(activityTaskManagerService)
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun setSurfaceBehindVisibility_goesAwayFirst_andIgnoresSecondCall_without_keyguard_shell_transitions() {
underTest.setLockscreenShown(true)
underTest.setSurfaceBehindVisibility(true)
verify(activityTaskManagerService).keyguardGoingAway(0)
@@ -126,8 +192,27 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
}
@Test
- fun setSurfaceBehindVisibility_falseSetsLockscreenVisibility() {
+ @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun setSurfaceBehindVisibility_goesAwayFirst_andIgnoresSecondCall_with_keyguard_shell_transitions() {
+ underTest.setLockscreenShown(true)
+ underTest.setSurfaceBehindVisibility(true)
+ verify(keyguardTransitions).startKeyguardTransition(false, false)
+
+ underTest.setSurfaceBehindVisibility(true)
+ verifyNoMoreInteractions(keyguardTransitions)
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun setSurfaceBehindVisibility_falseSetsLockscreenVisibility_without_keyguard_shell_transitions() {
underTest.setSurfaceBehindVisibility(false)
verify(activityTaskManagerService).setLockScreenShown(eq(true), any())
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_ENSURE_KEYGUARD_DOES_TRANSITION_STARTING)
+ fun setSurfaceBehindVisibility_falseSetsLockscreenVisibility_with_keyguard_shell_transitions() {
+ underTest.setSurfaceBehindVisibility(false)
+ verify(keyguardTransitions).startKeyguardTransition(eq(true), any())
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt
index b0959e4eea0b..d42b538cf355 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt
@@ -27,10 +27,13 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepos
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -43,6 +46,16 @@ class DeviceEntryForegroundViewModelTest : SysuiTestCase() {
private val underTest: DeviceEntryForegroundViewModel =
kosmos.deviceEntryForegroundIconViewModel
+ @Before
+ fun setup() {
+ context.orCreateTestableResources.addOverride(R.integer.udfps_padding_debounce_duration, 0)
+ }
+
+ @After
+ fun teardown() {
+ context.orCreateTestableResources.removeOverride(R.integer.udfps_padding_debounce_duration)
+ }
+
@Test
fun aodIconColorWhite() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt
index 450aadd70171..ebc00c3897cb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt
@@ -20,6 +20,7 @@ import android.content.Context
import android.content.Intent
import android.graphics.drawable.Icon
import android.os.UserHandle
+import com.android.wm.shell.bubbles.Bubble
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
import kotlinx.coroutines.CoroutineDispatcher
@@ -33,14 +34,29 @@ import kotlinx.coroutines.CoroutineDispatcher
class FakeNoteTaskBubbleController(
unUsed1: Context,
unsUsed2: CoroutineDispatcher,
- private val optionalBubbles: Optional<Bubbles>
+ private val optionalBubbles: Optional<Bubbles>,
) : NoteTaskBubblesController(unUsed1, unsUsed2) {
override suspend fun areBubblesAvailable() = optionalBubbles.isPresent
- override suspend fun showOrHideAppBubble(intent: Intent, userHandle: UserHandle, icon: Icon) {
+ override suspend fun showOrHideAppBubble(
+ intent: Intent,
+ userHandle: UserHandle,
+ icon: Icon,
+ bubbleExpandBehavior: NoteTaskBubbleExpandBehavior,
+ ) {
optionalBubbles.ifPresentOrElse(
- { bubbles -> bubbles.showOrHideAppBubble(intent, userHandle, icon) },
- { throw IllegalAccessException() }
+ { bubbles ->
+ if (
+ bubbleExpandBehavior == NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED &&
+ bubbles.isBubbleExpanded(
+ Bubble.getAppBubbleKeyForApp(intent.`package`, userHandle)
+ )
+ ) {
+ return@ifPresentOrElse
+ }
+ bubbles.showOrHideAppBubble(intent, userHandle, icon)
+ },
+ { throw IllegalAccessException() },
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
index 9ef6b9c13315..e55d6ad6c5a0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
@@ -21,9 +21,9 @@ import android.graphics.drawable.Icon
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.notetask.NoteTaskBubblesController.NoteTaskBubblesService
+import com.android.systemui.res.R
import com.android.wm.shell.bubbles.Bubbles
import com.google.common.truth.Truth.assertThat
import java.util.Optional
@@ -33,6 +33,9 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.whenever
/** atest SystemUITests:NoteTaskBubblesServiceTest */
@SmallTest
@@ -61,12 +64,40 @@ internal class NoteTaskBubblesServiceTest : SysuiTestCase() {
}
@Test
- fun showOrHideAppBubble() {
+ fun showOrHideAppBubble_defaultExpandBehavior_shouldCallBubblesApi() {
val intent = Intent()
val user = UserHandle.SYSTEM
val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
+ val bubbleExpandBehavior = NoteTaskBubbleExpandBehavior.DEFAULT
+ whenever(bubbles.isBubbleExpanded(any())).thenReturn(false)
+
+ createServiceBinder().showOrHideAppBubble(intent, user, icon, bubbleExpandBehavior)
+
+ verify(bubbles).showOrHideAppBubble(intent, user, icon)
+ }
+
+ @Test
+ fun showOrHideAppBubble_keepIfExpanded_bubbleShown_shouldNotCallBubblesApi() {
+ val intent = Intent().apply { setPackage("test") }
+ val user = UserHandle.SYSTEM
+ val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
+ val bubbleExpandBehavior = NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED
+ whenever(bubbles.isBubbleExpanded(any())).thenReturn(true)
+
+ createServiceBinder().showOrHideAppBubble(intent, user, icon, bubbleExpandBehavior)
+
+ verify(bubbles, never()).showOrHideAppBubble(intent, user, icon)
+ }
+
+ @Test
+ fun showOrHideAppBubble_keepIfExpanded_bubbleNotShown_shouldCallBubblesApi() {
+ val intent = Intent().apply { setPackage("test") }
+ val user = UserHandle.SYSTEM
+ val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
+ val bubbleExpandBehavior = NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED
+ whenever(bubbles.isBubbleExpanded(any())).thenReturn(false)
- createServiceBinder().showOrHideAppBubble(intent, user, icon)
+ createServiceBinder().showOrHideAppBubble(intent, user, icon, bubbleExpandBehavior)
verify(bubbles).showOrHideAppBubble(intent, user, icon)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskInfoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskInfoTest.kt
index 8f4078b88fc0..d3578fb9f69b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskInfoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskInfoTest.kt
@@ -19,6 +19,7 @@ import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.notetask.NoteTaskEntryPoint.QS_NOTES_TILE
import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE
import com.google.common.truth.Truth.assertThat
import org.junit.Test
@@ -44,10 +45,19 @@ internal class NoteTaskInfoTest : SysuiTestCase() {
}
@Test
- fun launchMode_keyguardUnlocked_launchModeAppBubble() {
+ fun launchMode_keyguardUnlocked_launchModeAppBubble_withDefaultExpandBehavior() {
val underTest = DEFAULT_INFO.copy(isKeyguardLocked = false)
- assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.AppBubble)
+ assertThat(underTest.launchMode)
+ .isEqualTo(NoteTaskLaunchMode.AppBubble(NoteTaskBubbleExpandBehavior.DEFAULT))
+ }
+
+ @Test
+ fun launchMode_keyguardUnlocked_qsTileEntryPoint_launchModeAppBubble_withKeepIfExpandedExpandBehavior() {
+ val underTest = DEFAULT_INFO.copy(isKeyguardLocked = false, entryPoint = QS_NOTES_TILE)
+
+ assertThat(underTest.launchMode)
+ .isEqualTo(NoteTaskLaunchMode.AppBubble(NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED))
}
private companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 2e074da02103..cca847effe94 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -56,6 +56,7 @@ import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepositor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryHapticsInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus
import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus
import com.android.systemui.flags.EnableSceneContainer
@@ -2532,6 +2533,146 @@ class SceneContainerStartableTest : SysuiTestCase() {
assertThat(isAlternateBouncerVisible).isFalse()
}
+ @Test
+ fun handleDeviceUnlockStatus_deviceLockedWhileOnDream_stayOnDream() =
+ testScope.runTest {
+ val transitionState =
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ )
+ underTest.start()
+
+ val isUnlocked by
+ collectLastValue(
+ kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+ )
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+ // Unlock device.
+ kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ assertThat(isUnlocked).isTrue()
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
+
+ // Change to Dream.
+ sceneInteractor.changeScene(Scenes.Dream, "test")
+ transitionState.value = ObservableTransitionState.Idle(Scenes.Dream)
+ runCurrent()
+ assertThat(isUnlocked).isTrue()
+ assertThat(currentScene).isEqualTo(Scenes.Dream)
+
+ // Lock device, and verify stay on dream.
+ kosmos.fakeDeviceEntryRepository.deviceUnlockStatus.value =
+ DeviceUnlockStatus(isUnlocked = false, deviceUnlockSource = null)
+ runCurrent()
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Dream)
+ }
+
+ @Test
+ fun handleDeviceUnlockStatus_deviceLockedWhileOnCommunal_stayOnCommunal() =
+ testScope.runTest {
+ val transitionState =
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ )
+ underTest.start()
+
+ val isUnlocked by
+ collectLastValue(
+ kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+ )
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+ // Unlock device.
+ kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+ SuccessFingerprintAuthenticationStatus(0, true)
+ )
+ assertThat(isUnlocked).isTrue()
+ assertThat(currentScene).isEqualTo(Scenes.Gone)
+
+ // Change to Communal.
+ sceneInteractor.changeScene(Scenes.Communal, "test")
+ transitionState.value = ObservableTransitionState.Idle(Scenes.Communal)
+ runCurrent()
+ assertThat(isUnlocked).isTrue()
+ assertThat(currentScene).isEqualTo(Scenes.Communal)
+
+ // Lock device, and verify stay on Communal.
+ kosmos.fakeDeviceEntryRepository.deviceUnlockStatus.value =
+ DeviceUnlockStatus(isUnlocked = false, deviceUnlockSource = null)
+ runCurrent()
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Communal)
+ }
+
+ @Test
+ fun replacesLockscreenSceneOnBackStack_whenFaceUnlocked_fromShade_noAlternateBouncer() =
+ testScope.runTest {
+ val transitionState =
+ prepareState(
+ isDeviceUnlocked = false,
+ initialSceneKey = Scenes.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ )
+ underTest.start()
+
+ val isUnlocked by
+ collectLastValue(
+ kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+ )
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val backStack by collectLastValue(sceneBackInteractor.backStack)
+ val isAlternateBouncerVisible by
+ collectLastValue(kosmos.alternateBouncerInteractor.isVisible)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(isAlternateBouncerVisible).isFalse()
+
+ // Change to shade.
+ sceneInteractor.changeScene(Scenes.Shade, "")
+ transitionState.value = ObservableTransitionState.Idle(Scenes.Shade)
+ runCurrent()
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Lockscreen)
+ assertThat(isAlternateBouncerVisible).isFalse()
+
+ // Show the alternate bouncer.
+ kosmos.alternateBouncerInteractor.forceShow()
+ kosmos.sysuiStatusBarStateController.leaveOpen = true // leave shade open
+ runCurrent()
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Lockscreen)
+ assertThat(isAlternateBouncerVisible).isTrue()
+
+ // Simulate race condition by hiding the alternate bouncer *before* the face unlock:
+ kosmos.alternateBouncerInteractor.hide()
+ runCurrent()
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Lockscreen)
+ assertThat(isAlternateBouncerVisible).isFalse()
+
+ // Trigger a face unlock.
+ updateFaceAuthStatus(isSuccess = true)
+ runCurrent()
+ assertThat(isUnlocked).isTrue()
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Gone)
+ assertThat(isAlternateBouncerVisible).isFalse()
+ }
+
private fun TestScope.emulateSceneTransition(
transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
toScene: SceneKey,
@@ -2768,15 +2909,16 @@ class SceneContainerStartableTest : SysuiTestCase() {
}
private fun updateFaceAuthStatus(isSuccess: Boolean) {
- if (isSuccess) {
- kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
- SuccessFaceAuthenticationStatus(
- successResult = Mockito.mock(FaceManager.AuthenticationResult::class.java)
- )
- )
- } else {
- kosmos.fakeDeviceEntryFaceAuthRepository.setAuthenticationStatus(
- FailedFaceAuthenticationStatus()
+ with(kosmos.fakeDeviceEntryFaceAuthRepository) {
+ isAuthenticated.value = isSuccess
+ setAuthenticationStatus(
+ if (isSuccess) {
+ SuccessFaceAuthenticationStatus(
+ successResult = Mockito.mock(FaceManager.AuthenticationResult::class.java)
+ )
+ } else {
+ FailedFaceAuthenticationStatus()
+ }
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 94a19c80dc00..ed31f366e1d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -349,6 +349,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock private KeyguardClockPositionAlgorithm mKeyguardClockPositionAlgorithm;
@Mock private NaturalScrollingSettingObserver mNaturalScrollingSettingObserver;
@Mock private LargeScreenHeaderHelper mLargeScreenHeaderHelper;
+ @Mock private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector;
protected final int mMaxUdfpsBurnInOffsetY = 5;
protected FakeFeatureFlagsClassic mFeatureFlags = new FakeFeatureFlagsClassic();
protected KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
@@ -819,6 +820,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mNotificationShadeDepthController,
mShadeHeaderController,
mStatusBarTouchableRegionManager,
+ () -> mStatusBarLongPressGestureDetector,
mKeyguardStateController,
mKeyguardBypassController,
mScrimController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index ef132d5a4989..61d4c9968d49 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -126,6 +126,7 @@ public class QuickSettingsControllerImplBaseTest extends SysuiTestCase {
@Mock protected NotificationShadeDepthController mNotificationShadeDepthController;
@Mock protected ShadeHeaderController mShadeHeaderController;
@Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+ @Mock protected StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector;
@Mock protected DozeParameters mDozeParameters;
@Mock protected KeyguardStateController mKeyguardStateController;
@Mock protected KeyguardBypassController mKeyguardBypassController;
@@ -250,6 +251,7 @@ public class QuickSettingsControllerImplBaseTest extends SysuiTestCase {
mNotificationShadeDepthController,
mShadeHeaderController,
mStatusBarTouchableRegionManager,
+ () -> mStatusBarLongPressGestureDetector,
mKeyguardStateController,
mKeyguardBypassController,
mScrimController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
index 4e7839efe2a3..af01547be7e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/ShadePrimaryDisplayCommandTest.kt
@@ -21,7 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.display.data.repository.displayRepository
import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.ShadePrimaryDisplayCommand
import com.android.systemui.statusbar.commandline.commandRegistry
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -34,13 +36,16 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
-class ShadeDisplaysRepositoryTest : SysuiTestCase() {
+class ShadePrimaryDisplayCommandTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val commandRegistry = kosmos.commandRegistry
+ private val displayRepository = kosmos.displayRepository
+ private val shadeDisplaysRepository = ShadeDisplaysRepositoryImpl()
private val pw = PrintWriter(StringWriter())
- private val underTest = ShadeDisplaysRepositoryImpl(commandRegistry)
+ private val underTest =
+ ShadePrimaryDisplayCommand(commandRegistry, displayRepository, shadeDisplaysRepository)
@Before
fun setUp() {
@@ -50,7 +55,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
@Test
fun commandDisplayOverride_updatesDisplayId() =
testScope.runTest {
- val displayId by collectLastValue(underTest.displayId)
+ val displayId by collectLastValue(shadeDisplaysRepository.displayId)
assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
val newDisplayId = 2
@@ -65,7 +70,7 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
@Test
fun commandShadeDisplayOverride_resetsDisplayId() =
testScope.runTest {
- val displayId by collectLastValue(underTest.displayId)
+ val displayId by collectLastValue(shadeDisplaysRepository.displayId)
assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
val newDisplayId = 2
@@ -78,4 +83,17 @@ class ShadeDisplaysRepositoryTest : SysuiTestCase() {
commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", "reset"))
assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
}
+
+ @Test
+ fun commandShadeDisplayOverride_anyExternalDisplay_notOnDefaultAnymore() =
+ testScope.runTest {
+ val displayId by collectLastValue(shadeDisplaysRepository.displayId)
+ assertThat(displayId).isEqualTo(Display.DEFAULT_DISPLAY)
+ val newDisplayId = 2
+ displayRepository.addDisplay(displayId = newDisplayId)
+
+ commandRegistry.onShellCommand(pw, arrayOf("shade_display_override", "any_external"))
+
+ assertThat(displayId).isEqualTo(newDisplayId)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index fb7252b24295..60a185537b0d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -16,8 +16,6 @@
package com.android.systemui.statusbar;
-import static android.app.Notification.CATEGORY_CALL;
-
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
@@ -199,19 +197,6 @@ public class StatusBarIconViewTest extends SysuiTestCase {
}
@Test
- public void testContentDescForNotification_noNotifContent() {
- Notification n = new Notification.Builder(mContext, "test")
- .setSmallIcon(0)
- .setContentTitle("hello")
- .setCategory(CATEGORY_CALL)
- .build();
- assertThat(NotificationContentDescription.contentDescForNotification(mContext, n)
- .toString()).startsWith("com.android.systemui.tests notification");
- assertThat(NotificationContentDescription.contentDescForNotification(mContext, n)
- .toString()).doesNotContain("hello");
- }
-
- @Test
@EnableFlags({Flags.FLAG_MODES_UI, Flags.FLAG_MODES_UI_ICONS})
public void setIcon_withPreloaded_usesPreloaded() {
Icon mockIcon = mock(Icon.class);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java
new file mode 100644
index 000000000000..b2962eeb9001
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
+import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+import android.telecom.TelecomManager;
+import android.testing.TestableLooper;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.AssistantFeedbackController;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@TestableLooper.RunWithLooper
+public class BundleNotificationInfoTest extends SysuiTestCase {
+ private static final String TEST_PACKAGE_NAME = "test_package";
+ private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME;
+ private static final int TEST_UID = 1;
+ private static final String TEST_CHANNEL = "test_channel";
+ private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
+
+ private TestableLooper mTestableLooper;
+ private BundleNotificationInfo mInfo;
+ private NotificationChannel mNotificationChannel;
+ private StatusBarNotification mSbn;
+ private NotificationEntry mEntry;
+ private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
+
+ @Rule
+ public MockitoRule mockito = MockitoJUnit.rule();
+ @Mock
+ private MetricsLogger mMetricsLogger;
+ @Mock
+ private INotificationManager mMockINotificationManager;
+ @Mock
+ private PackageManager mMockPackageManager;
+ @Mock
+ private OnUserInteractionCallback mOnUserInteractionCallback;
+ @Mock
+ private ChannelEditorDialogController mChannelEditorDialogController;
+ @Mock
+ private AssistantFeedbackController mAssistantFeedbackController;
+ @Mock
+ private TelecomManager mTelecomManager;
+
+ @Before
+ public void setUp() throws Exception {
+ mTestableLooper = TestableLooper.get(this);
+
+ mContext.addMockSystemService(TelecomManager.class, mTelecomManager);
+
+ mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+ // Inflate the layout
+ final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+ mInfo = (BundleNotificationInfo) layoutInflater.inflate(R.layout.bundle_notification_info,
+ null);
+ mInfo.setGutsParent(mock(NotificationGuts.class));
+ // Our view is never attached to a window so the View#post methods in
+ // BundleNotificationInfo never get called. Setting this will skip the post and do the
+ // action immediately.
+ mInfo.mSkipPost = true;
+
+ // PackageManager must return a packageInfo and applicationInfo.
+ final PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = TEST_PACKAGE_NAME;
+ when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
+ .thenReturn(packageInfo);
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.uid = TEST_UID; // non-zero
+ final PackageInfo systemPackageInfo = new PackageInfo();
+ systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME;
+ when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt()))
+ .thenReturn(systemPackageInfo);
+ when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
+ .thenReturn(packageInfo);
+
+ // Package has one channel by default.
+ when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+ eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1);
+
+ // Some test channels.
+ mNotificationChannel = new NotificationChannel(
+ TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
+ Notification notification = new Notification();
+ notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, applicationInfo);
+ mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
+ notification, UserHandle.getUserHandleForUid(TEST_UID), null, 0);
+ mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();
+ when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(false);
+ when(mAssistantFeedbackController.getInlineDescriptionResource(any()))
+ .thenReturn(R.string.notification_channel_summary_automatic);
+ }
+
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void testBindNotification_setsOnClickListenerForFeedback() throws Exception {
+ // When Notification Assistant is available,
+ when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(
+ new ComponentName("assistantPkg", "assistantCls"));
+
+ // ...and Package manager has an intent that matches.
+ ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
+ ResolveInfo info = new ResolveInfo();
+ info.activityInfo = new ActivityInfo();
+ info.activityInfo.packageName = "assistantPkg";
+ info.activityInfo.name = "assistantCls";
+ resolveInfos.add(info);
+ when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfos);
+
+ // And we attempt to bind the notification to the Info object
+ final CountDownLatch latch = new CountDownLatch(1);
+ mInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ mChannelEditorDialogController,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ null,
+ (View v, Intent intent) -> {
+ // Assert that the intent action and package match.
+ assertEquals(intent.getAction(),
+ ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
+ assertEquals(intent.getPackage(), "assistantPkg");
+ latch.countDown();
+ },
+ mUiEventLogger,
+ true,
+ false,
+ true,
+ mAssistantFeedbackController,
+ mMetricsLogger);
+ // and the feedback button is clicked,
+ final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
+ feedbackButton.performClick();
+
+ // then of the intents queried for is the feedback intent,
+ ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+ verify(mMockPackageManager, atLeastOnce()).queryIntentActivities(captor.capture(),
+ anyInt());
+ List<Intent> capturedIntents = captor.getAllValues();
+ Intent feedbackIntent = null;
+ for (int i = 0; i < capturedIntents.size(); i++) {
+ final Intent capturedIntent = capturedIntents.get(i);
+ if (capturedIntent.getAction() == ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS
+ && capturedIntent.getPackage().equals("assistantPkg")) {
+ feedbackIntent = capturedIntent;
+ }
+ }
+ assertNotNull("feedbackIntent should be not null", feedbackIntent);
+ assertEquals(mSbn.getKey(),
+ feedbackIntent.getExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY));
+
+ // and verify that listener was triggered.
+ assertEquals(0, latch.getCount());
+ assertEquals(View.VISIBLE, feedbackButton.getVisibility());
+ }
+
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void testBindNotification_hidesFeedbackButtonWhenNoNAS() throws Exception {
+ // When the Notification Assistant is not available
+ when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(null);
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ mInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ mChannelEditorDialogController,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ null,
+ (View v, Intent intent) -> {
+ // Assert that the intent action and package match.
+ assertEquals(intent.getAction(),
+ ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
+ assertEquals(intent.getPackage(), "assistantPkg");
+ latch.countDown();
+ },
+ mUiEventLogger,
+ true,
+ false,
+ true,
+ mAssistantFeedbackController,
+ mMetricsLogger);
+
+ final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
+ feedbackButton.performClick();
+ // Listener was not triggered
+ assertEquals(1, latch.getCount());
+ assertEquals(View.GONE, feedbackButton.getVisibility());
+ }
+
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void testBindNotification_hidesFeedbackButtonWhenNoIntent() throws Exception {
+ // When the Notification Assistant is available,
+ when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(
+ new ComponentName("assistantPkg", "assistantCls"));
+
+ // But the intent activity is null
+ when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(null);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ mInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ mChannelEditorDialogController,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ null,
+ (View v, Intent intent) -> {
+ // Assert that the intent action and package match.
+ assertEquals(intent.getAction(),
+ ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
+ assertEquals(intent.getPackage(), "assistantPkg");
+ latch.countDown();
+ },
+ mUiEventLogger,
+ true,
+ false,
+ true,
+ mAssistantFeedbackController,
+ mMetricsLogger);
+
+ final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
+ feedbackButton.performClick();
+ // Listener was not triggered
+ assertEquals(1, latch.getCount());
+ assertEquals(View.GONE, feedbackButton.getVisibility());
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
index a1b63b159277..b16d3ea5337b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
@@ -168,7 +168,10 @@ class NotificationGutsManagerTest(flags: FlagsParameterization) : SysuiTestCase(
@JvmStatic
@Parameters(name = "{0}")
fun getParams(): List<FlagsParameterization> {
- return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ return FlagsParameterization.allCombinationsOf(
+ android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI
+ )
+ .andSceneContainer()
}
}
@@ -614,6 +617,43 @@ class NotificationGutsManagerTest(flags: FlagsParameterization) : SysuiTestCase(
)
}
+ @Test
+ @Throws(Exception::class)
+ fun testInitializeBundleNotificationInfoView() {
+ val infoView: BundleNotificationInfo = mock()
+ val row = spy(helper.createRow())
+ val entry = row.entry
+
+ // Modify the notification entry to have a channel that is in SYSTEM_RESERVED_IDS
+ val channel = NotificationChannel(NotificationChannel.NEWS_ID, "name", 2)
+ NotificationEntryHelper.modifyRanking(entry).setChannel(channel).build()
+
+ whenever(row.isNonblockable).thenReturn(false)
+ val statusBarNotification = entry.sbn
+ // Can we change this to a call to bindGuts instead? We have the row,
+ // we need a MenuItem that we can put the infoView into.
+ gutsManager.initializeBundleNotificationInfo(row, infoView)
+
+ verify(infoView)
+ .bindNotification(
+ any<PackageManager>(),
+ any<INotificationManager>(),
+ eq(onUserInteractionCallback),
+ eq(channelEditorDialogController),
+ eq(statusBarNotification.packageName),
+ any<NotificationChannel>(),
+ eq(entry),
+ any<NotificationInfo.OnSettingsClickListener>(),
+ any<NotificationInfo.OnAppSettingsClickListener>(),
+ any<UiEventLogger>(),
+ /* isDeviceProvisioned = */ eq(false),
+ /* isNonblockable = */ eq(false),
+ /* wasShownHighPriority = */ eq(false),
+ eq(assistantFeedbackController),
+ eq(metricsLogger),
+ )
+ }
+
private fun createTestNotificationRow(): ExpandableNotificationRow {
val nb =
Notification.Builder(mContext, testNotificationChannel.id)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
index abb3e6e0c1f2..0fbee6d29441 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
@@ -321,7 +321,7 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
BaseHeadsUpManager.HeadsUpEntry.class);
headsUpEntry.mEntry = notifEntry;
- hum.onEntryRemoved(headsUpEntry);
+ hum.onEntryRemoved(headsUpEntry, "test");
verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(notifEntry));
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
index 8ebdbaaa6bf0..6175e05923a7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt
@@ -82,7 +82,6 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager
private val mJavaAdapter: JavaAdapter = JavaAdapter(testScope.backgroundScope)
@Mock private lateinit var mShadeInteractor: ShadeInteractor
-
@Mock private lateinit var dumpManager: DumpManager
private lateinit var mAvalancheController: AvalancheController
@@ -205,6 +204,25 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager
assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)).isTrue()
}
+ class TestAnimationStateHandler : AnimationStateHandler {
+ override fun setHeadsUpGoingAwayAnimationsAllowed(allowed: Boolean) {}
+ }
+
+ @Test
+ @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testReorderingAllowed_clearsListOfEntriesToRemove() {
+ whenever(mVSProvider.isReorderingAllowed).thenReturn(true)
+ val hmp = createHeadsUpManagerPhone()
+
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ hmp.showNotification(notifEntry)
+ assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)).isTrue()
+
+ hmp.setAnimationStateHandler(TestAnimationStateHandler())
+ hmp.mOnReorderingAllowedListener.onReorderingAllowed()
+ assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.isEmpty()).isTrue()
+ }
+
@Test
@EnableFlags(NotificationThrottleHun.FLAG_NAME)
fun testShowNotification_reorderNotAllowed_seenInShadeTrue() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt
new file mode 100644
index 000000000000..799ca4a49038
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.dialog.sliders.domain.interactor
+
+import android.app.ActivityManager
+import android.testing.TestableLooper
+import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.fakeVolumeDialogController
+import com.android.systemui.testKosmos
+import com.android.systemui.volume.Events
+import com.android.systemui.volume.dialog.domain.interactor.volumeDialogVisibilityInteractor
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.runner.RunWith
+
+private val volumeDialogTimeout = 3.seconds
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
+class VolumeDialogSliderInputEventsInteractorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos()
+
+ private lateinit var underTest: VolumeDialogSliderInputEventsInteractor
+
+ @Before
+ fun setup() {
+ underTest = kosmos.volumeDialogSliderInputEventsInteractor
+ }
+
+ @Test
+ fun inputEvents_resetDialogVisibilityTimeout() =
+ with(kosmos) {
+ testScope.runTest {
+ runCurrent()
+ val dialogVisibility by
+ collectLastValue(volumeDialogVisibilityInteractor.dialogVisibility)
+ fakeVolumeDialogController.onShowRequested(
+ Events.SHOW_REASON_VOLUME_CHANGED,
+ false,
+ ActivityManager.LOCK_TASK_MODE_LOCKED,
+ )
+ runCurrent()
+ advanceTimeBy(volumeDialogTimeout / 2)
+ assertThat(dialogVisibility)
+ .isInstanceOf(VolumeDialogVisibilityModel.Visible::class.java)
+
+ underTest.onTouchEvent(
+ MotionEvent.obtain(
+ /* downTime = */ 0,
+ /* eventTime = */ 0,
+ /* action = */ 0,
+ /* x = */ 0f,
+ /* y = */ 0f,
+ /* metaState = */ 0,
+ )
+ )
+ advanceTimeBy(volumeDialogTimeout / 2)
+
+ assertThat(dialogVisibility)
+ .isInstanceOf(VolumeDialogVisibilityModel.Visible::class.java)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt
index 7c5a48728a11..3f995c69c32f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt
@@ -155,6 +155,30 @@ class VolumeDialogSlidersInteractorTest : SysuiTestCase() {
}
}
+ @Test
+ fun activeStreamChanges_showBoth() {
+ with(kosmos) {
+ testScope.runTest {
+ runCurrent()
+ fakeVolumeDialogController.updateState {
+ activeStream = AudioManager.STREAM_SYSTEM
+ states.put(AudioManager.STREAM_MUSIC, buildStreamState())
+ states.put(AudioManager.STREAM_SYSTEM, buildStreamState())
+ }
+ val slidersModel by collectLastValue(underTest.sliders)
+ runCurrent()
+
+ fakeVolumeDialogController.updateState { activeStream = AudioManager.STREAM_MUSIC }
+ runCurrent()
+
+ assertThat(slidersModel!!.slider)
+ .isEqualTo(VolumeDialogSliderType.Stream(AudioManager.STREAM_MUSIC))
+ assertThat(slidersModel!!.floatingSliders)
+ .containsExactly(VolumeDialogSliderType.Stream(AudioManager.STREAM_SYSTEM))
+ }
+ }
+ }
+
private fun buildStreamState(
build: VolumeDialogController.StreamState.() -> Unit = {}
): VolumeDialogController.StreamState {
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index 074277c55c88..dcb15a7cd9aa 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -103,6 +103,15 @@ public interface BcSmartspaceDataPlugin extends Plugin {
void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets);
}
+ /**
+ * Sets {@link BcSmartspaceConfigPlugin}.
+ *
+ * TODO: b/259566300 - Remove once isViewPager2Enabled is fully rolled out
+ */
+ default void registerConfigProvider(BcSmartspaceConfigPlugin configProvider) {
+ throw new UnsupportedOperationException("Not implemented by " + getClass());
+ }
+
/** View to which this plugin can be registered, in order to get updates. */
interface SmartspaceView {
void registerDataProvider(BcSmartspaceDataPlugin plugin);
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index d069c0181218..fe9036bb2252 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -65,7 +65,7 @@
<string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"‏يجب إدخال رقم PIN لأنّك أجريت محاولات كثيرة جدًا."</string>
<string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"يجب إدخال كلمة المرور لأنك أجريت محاولات كثيرة جدًا."</string>
<string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"يجب رسم النقش لأنّك أجريت محاولات كثيرة جدًا."</string>
- <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"‏افتح برقم PIN أو البصمة."</string>
+ <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"افتح الجهاز برقم التعريف الشخصي أو البصمة."</string>
<string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"افتح القفل بكلمة مرور أو ببصمة إصبع."</string>
<string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"افتح بالنقش أو بصمة الإصبع"</string>
<string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"لمزيد من الأمان، تم قفل الجهاز وفقًا لسياسة العمل."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 5ae41fedac49..e7116d63d5fc 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -65,7 +65,7 @@
<string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"Se requiere PIN luego de demasiados intentos"</string>
<string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"Se requiere contraseña luego de demasiados intentos"</string>
<string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"Se requiere patrón luego de demasiados intentos"</string>
- <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"Desbloq. PIN/huella"</string>
+ <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"Desbloquear con PIN o huella dactilar"</string>
<string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"Desbloq. contraseña/huella"</string>
<string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"Desbloq. patrón/huella"</string>
<string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"Dispositivo bloqueado con la política del trabajo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 83a607b14a19..41c3e06bd062 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -42,7 +42,7 @@
<string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIMa PUKaren bidez desblokeatu behar da."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMa desblokeatzen…"</string>
<string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"PIN kodearen eremua"</string>
- <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Gailuko pasahitza"</string>
+ <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Gailuaren pasahitza"</string>
<string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM txartelaren PIN kodearen eremua"</string>
<string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM txartelaren PUK kodearen eremua"</string>
<string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Ezabatu"</string>
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index 4a6696869bd6..fd4d47b6bfbf 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -32,7 +32,7 @@
<string name="kg_failed_attempts_now_wiping" product="default" msgid="6381835450014881813">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ଫୋନ୍‌ଟି ରିସେଟ୍ କରିଦିଆଯିବ, ଫଳରେ ଏହାର ସମସ୍ତ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="7325071812832605911">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲ୍କୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="8110939900089863103">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g> ଭୁଲ ପ୍ରୟାସ ପରେ, ଏହି ୟୁଜର ପ୍ରୋଫାଇଲକୁ କାଢ଼ି ଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
- <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତା ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
+ <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="8509811676952707883">"ଆପଣ ଟାବଲେଟକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ କାଢ଼ି ଦିଆଯିବ, ଯାହାଦ୍ୱାରା ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
<string name="kg_failed_attempts_now_erasing_user" product="default" msgid="3051962486994265014">"ଆପଣ ଫୋନକୁ ଅନଲକ କରିବାକୁ <xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଏହି ୟୁଜରଙ୍କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଦ୍ୱାରା ସମସ୍ତ ୟୁଜର ଡାଟା ଡିଲିଟ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="1049523640263353830">"ଆପଣ ଟାବ୍‌ଲେଟ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"ଆପଣ ଫୋନ୍‌କୁ ଅନ୍‌ଲକ୍ କରିବାକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ୍ ପ୍ରୟାସ ପରେ, ୱାର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
diff --git a/packages/SystemUI/res/drawable/ic_widgets.xml b/packages/SystemUI/res/drawable/ic_widgets.xml
new file mode 100644
index 000000000000..9e05809bfb33
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_widgets.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/black"
+ android:pathData="M666,520L440,294L666,68L892,294L666,520ZM120,440L120,120L440,120L440,440L120,440ZM520,840L520,520L840,520L840,840L520,840ZM120,840L120,520L440,520L440,840L120,840ZM200,360L360,360L360,200L200,200L200,360ZM667,408L780,295L667,182L554,295L667,408ZM600,760L760,760L760,600L600,600L600,760ZM200,760L360,760L360,600L200,600L200,760ZM360,360L360,360L360,360L360,360L360,360ZM554,295L554,295L554,295L554,295L554,295ZM360,600L360,600L360,600L360,600L360,600ZM600,600L600,600L600,600L600,600L600,600Z" />
+</vector>
diff --git a/packages/SystemUI/res/layout/bundle_notification_info.xml b/packages/SystemUI/res/layout/bundle_notification_info.xml
new file mode 100644
index 000000000000..8700832c0eb0
--- /dev/null
+++ b/packages/SystemUI/res/layout/bundle_notification_info.xml
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2024, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<com.android.systemui.statusbar.notification.row.BundleNotificationInfo
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:id="@+id/notification_guts"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:clipChildren="false"
+ android:clipToPadding="true"
+ android:orientation="vertical"
+ android:paddingStart="@dimen/notification_shade_content_margin_horizontal">
+
+ <!-- Package Info -->
+ <LinearLayout
+ android:id="@+id/header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:clipChildren="false"
+ android:paddingTop="@dimen/notification_guts_header_top_padding"
+ android:clipToPadding="true">
+ <ImageView
+ android:id="@+id/pkg_icon"
+ android:layout_width="@dimen/notification_guts_conversation_icon_size"
+ android:layout_height="@dimen/notification_guts_conversation_icon_size"
+ android:layout_centerVertical="true"
+ android:layout_alignParentStart="true"
+ android:layout_marginEnd="15dp" />
+ <LinearLayout
+ android:id="@+id/names"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_guts_conversation_icon_size"
+ android:layout_centerVertical="true"
+ android:gravity="center_vertical"
+ android:layout_alignEnd="@id/pkg_icon"
+ android:layout_toEndOf="@id/pkg_icon">
+ <TextView
+ android:id="@+id/channel_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textDirection="locale"
+ style="@style/TextAppearance.NotificationImportanceChannel"/>
+ <TextView
+ android:id="@+id/group_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textDirection="locale"
+ android:ellipsize="end"
+ style="@style/TextAppearance.NotificationImportanceChannelGroup"/>
+ <TextView
+ android:id="@+id/pkg_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.NotificationImportanceApp"
+ android:ellipsize="end"
+ android:textDirection="locale"
+ android:maxLines="1"/>
+ <TextView
+ android:id="@+id/delegate_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ style="@style/TextAppearance.NotificationImportanceHeader"
+ android:layout_marginStart="2dp"
+ android:layout_marginEnd="2dp"
+ android:ellipsize="end"
+ android:textDirection="locale"
+ android:text="@string/notification_delegate_header"
+ android:maxLines="1" />
+
+ </LinearLayout>
+
+ <!-- end aligned fields -->
+ <!-- Optional link to app. Only appears if the channel is not disabled and the app
+asked for it -->
+ <ImageButton
+ android:id="@+id/app_settings"
+ android:layout_width="@dimen/notification_importance_toggle_size"
+ android:layout_height="@dimen/notification_importance_toggle_size"
+ android:layout_centerVertical="true"
+ android:visibility="gone"
+ android:background="@drawable/ripple_drawable"
+ android:contentDescription="@string/notification_app_settings"
+ android:src="@drawable/ic_info"
+ android:layout_toStartOf="@id/info"
+ android:tint="?androidprv:attr/materialColorPrimary"/>
+ <ImageButton
+ android:id="@+id/info"
+ android:layout_width="@dimen/notification_importance_toggle_size"
+ android:layout_height="@dimen/notification_importance_toggle_size"
+ android:layout_centerVertical="true"
+ android:contentDescription="@string/notification_more_settings"
+ android:background="@drawable/ripple_drawable_20dp"
+ android:src="@drawable/ic_settings"
+ android:tint="?androidprv:attr/materialColorPrimary"
+ android:layout_alignParentEnd="true" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/inline_controls"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingEnd="@dimen/notification_shade_content_margin_horizontal"
+ android:layout_marginTop="@dimen/notification_guts_option_vertical_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical">
+
+ <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
+ <TextView
+ android:id="@+id/non_configurable_text"
+ android:text="@string/notification_unblockable_desc"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+ <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
+ <TextView
+ android:id="@+id/non_configurable_call_text"
+ android:text="@string/notification_unblockable_call_desc"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+ <!-- Non configurable multichannel text. appears instead of @+id/interruptiveness_settings-->
+ <TextView
+ android:id="@+id/non_configurable_multichannel_text"
+ android:text="@string/notification_multichannel_desc"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
+
+ <LinearLayout
+ android:id="@+id/interruptiveness_settings"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical">
+ <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+ android:id="@+id/automatic"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_importance_button_separation"
+ android:padding="@dimen/notification_importance_button_padding"
+ android:clickable="true"
+ android:focusable="true"
+ android:background="@drawable/notification_guts_priority_button_bg"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center"
+ >
+ <ImageView
+ android:id="@+id/automatic_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_notifications_automatic"
+ android:background="@android:color/transparent"
+ android:tint="@color/notification_guts_priority_contents"
+ android:clickable="false"
+ android:focusable="false"/>
+ <TextView
+ android:id="@+id/automatic_label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+ android:layout_weight="1"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:clickable="false"
+ android:focusable="false"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+ android:text="@string/notification_automatic_title"/>
+ </LinearLayout>
+ <TextView
+ android:id="@+id/automatic_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+ android:visibility="gone"
+ android:text="@string/notification_channel_summary_automatic"
+ android:clickable="false"
+ android:focusable="false"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+ </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
+
+ <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+ android:id="@+id/alert"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/notification_importance_button_padding"
+ android:clickable="true"
+ android:focusable="true"
+ android:background="@drawable/notification_guts_priority_button_bg"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center"
+ >
+ <ImageView
+ android:id="@+id/alert_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_notifications_alert"
+ android:background="@android:color/transparent"
+ android:tint="@color/notification_guts_priority_contents"
+ android:clickable="false"
+ android:focusable="false"/>
+ <TextView
+ android:id="@+id/alert_label"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+ android:layout_weight="1"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:clickable="false"
+ android:focusable="false"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+ android:text="@string/notification_alert_title"/>
+ </LinearLayout>
+ <TextView
+ android:id="@+id/alert_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+ android:visibility="gone"
+ android:text="@string/notification_channel_summary_default"
+ android:clickable="false"
+ android:focusable="false"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+ </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
+
+ <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+ android:id="@+id/silence"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_importance_button_separation"
+ android:padding="@dimen/notification_importance_button_padding"
+ android:clickable="true"
+ android:focusable="true"
+ android:background="@drawable/notification_guts_priority_button_bg"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center"
+ >
+ <ImageView
+ android:id="@+id/silence_icon"
+ android:src="@drawable/ic_notifications_silence"
+ android:background="@android:color/transparent"
+ android:tint="@color/notification_guts_priority_contents"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="false"
+ android:focusable="false"/>
+ <TextView
+ android:id="@+id/silence_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:clickable="false"
+ android:focusable="false"
+ android:layout_toEndOf="@id/silence_icon"
+ android:layout_marginStart="@dimen/notification_importance_drawable_padding"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
+ android:text="@string/notification_silence_title"/>
+ </LinearLayout>
+ <TextView
+ android:id="@+id/silence_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
+ android:visibility="gone"
+ android:text="@string/notification_channel_summary_low"
+ android:clickable="false"
+ android:focusable="false"
+ android:ellipsize="end"
+ android:maxLines="2"
+ android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
+ </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/notification_guts_bundle_feedback"
+ android:text="@string/notification_guts_bundle_feedback"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:minWidth="@dimen/notification_guts_bundle_feedback_size"
+ android:minHeight="@dimen/notification_guts_bundle_feedback_size"
+ android:maxWidth="200dp"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+
+ <RelativeLayout
+ android:id="@+id/bottom_buttons"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="60dp"
+ android:gravity="center_vertical"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ >
+ <TextView
+ android:id="@+id/turn_off_notifications"
+ android:text="@string/inline_turn_off_notifications"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
+ android:gravity="start|center_vertical"
+ android:minWidth="@dimen/notification_importance_toggle_size"
+ android:minHeight="@dimen/notification_importance_toggle_size"
+ android:maxWidth="200dp"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ <TextView
+ android:id="@+id/done"
+ android:text="@string/inline_ok_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:gravity="end|center_vertical"
+ android:minWidth="@dimen/notification_importance_toggle_size"
+ android:minHeight="@dimen/notification_importance_toggle_size"
+ android:maxWidth="125dp"
+ style="@style/TextAppearance.NotificationInfo.Button"/>
+ </RelativeLayout>
+ </LinearLayout>
+</com.android.systemui.statusbar.notification.row.BundleNotificationInfo>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 694357d534fb..b8544a64d9da 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -31,10 +31,10 @@
app:layout_constraintBottom_toBottomOf="@id/volume_dialog_settings"
app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
- app:layout_constraintTop_toTopOf="@id/volume_ringer_and_drawer_container" />
+ app:layout_constraintTop_toTopOf="@id/volume_ringer_drawer" />
<include
- android:id="@id/volume_ringer_and_drawer_container"
+ android:id="@id/volume_ringer_drawer"
layout="@layout/volume_ringer_drawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/volume_ringer_button.xml b/packages/SystemUI/res/layout/volume_ringer_button.xml
index dc6780aeae60..38bb783c2920 100644
--- a/packages/SystemUI/res/layout/volume_ringer_button.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_button.xml
@@ -14,6 +14,7 @@
~ limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
@@ -25,6 +26,7 @@
android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
android:contentDescription="@string/volume_ringer_mode"
android:gravity="center"
+ android:tint="?androidprv:attr/materialColorOnSurface"
android:src="@drawable/volume_ringer_item_bg"
android:background="@drawable/volume_ringer_item_bg"/>
diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
index b71c4700c0fa..d850bbe63afd 100644
--- a/packages/SystemUI/res/layout/volume_ringer_drawer.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
@@ -14,55 +14,18 @@
~ limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:id="@+id/volume_ringer_and_drawer_container"
- android:layout_width="wrap_content"
+<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/volume_ringer_drawer"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:gravity="center"
- android:layoutDirection="ltr">
+ android:layoutDirection="ltr"
+ android:orientation="vertical"
+ app:layoutDescription="@xml/volume_dialog_ringer_drawer_motion_scene">
- <!-- Drawer view, invisible by default. -->
- <FrameLayout
- android:id="@+id/volume_drawer_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
+ <!-- add ringer buttons here -->
- <!-- View that is animated to a tapped ringer selection, so it appears selected. -->
- <FrameLayout
- android:id="@+id/volume_drawer_selection_background"
- android:layout_width="@dimen/volume_dialog_ringer_drawer_button_size"
- android:layout_height="@dimen/volume_dialog_ringer_drawer_button_size"
- android:layout_gravity="bottom|right"
- android:alpha="0.0"
- android:background="@drawable/volume_drawer_selection_bg" />
-
- <LinearLayout
- android:id="@+id/volume_drawer_options"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <!-- add ringer buttons here -->
-
- </LinearLayout>
-
- </FrameLayout>
-
- <!-- The current ringer selection. When the drawer is opened, this animates to the corresponding
- position in the drawer. When the drawer is closed, it animates back. -->
- <ImageButton
- android:id="@+id/volume_new_ringer_active_button"
- android:layout_width="@dimen/volume_dialog_ringer_drawer_button_size"
- android:layout_height="@dimen/volume_dialog_ringer_drawer_button_size"
- android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
- android:background="@drawable/volume_drawer_selection_bg"
- android:contentDescription="@string/volume_ringer_change"
- android:gravity="center"
- android:src="@drawable/ic_volume_media"
- android:tint="?androidprv:attr/materialColorOnPrimary" />
-
-</FrameLayout> \ No newline at end of file
+</androidx.constraintlayout.motion.widget.MotionLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 048ddaf735da..ebee1576342a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Gehoortoestelle"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Skakel tans aan …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kan nie helderheid verstel nie omdat dit\n deur die topapp beheer word"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outodraai"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Outodraai skerm"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ligging"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nuwe toestel saam te bind"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kon nie voorafstelling opdateer nie"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorafstelling"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Gekies"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nutsgoed"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Intydse Onderskrifte"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokkeer toestelmikrofoon?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokkeer toestelkamera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokkeer toestelkamera en mikrofoon?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nuwe kennisgewings nie"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Kennisgewingdemping is nou aan"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jou toestelvolume en -waarskuwings word outomaties vir tot 2 minute lank verminder wanneer jy te veel kennisgewings op een slag kry."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Skakel af"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontsluit om ouer kennisgewings te sien"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skakel oor na app regs of onder terwyl jy verdeelde skerm gebruik"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skakel oor na app links of bo terwyl jy verdeelde skerm gebruik"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Skuif aktiewe venster tussen skerms"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Skakel oor na volgende taal"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skakel oor na vorige taal"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gebruik minder as <xliff:g id="LENGTH">%1$d</xliff:g> karakters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Gespreklegstukke"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tik op \'n gesprek om dit by jou tuisskerm te voeg"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Keer die foon om vir hoër resolusie"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gevou"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"oopgevou"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pasmaak kortpadsleutels"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Druk sleutel om kortpad toe te wys"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Soekkortpaaie"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen soekresultate nie"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Vou ikoon in"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikoon vir Handeling- of Meta-sleutel"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikoon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pasmaak"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klaar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vou ikoon uit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sleephandvatsel"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Sleutelbordinstellings"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stel kortpad"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselleer"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk sleutel"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Sleutelkombinasie is reeds in gebruik. Probeer ’n ander sleutel."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeer met jou sleutelbord"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer kortpadsleutels"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeer met jou raakpaneel"</string>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 4afae3328cf7..fbeefc83c43d 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Af"</item>
<item msgid="3028994095749238254">"Aan"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Onbeskikbaar"</item>
+ <item msgid="6419996398343291862">"Af"</item>
+ <item msgid="5908720590832378783">"Aan"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 9d03a911b9d3..0351c7508703 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ግቤት"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"መስሚያ አጋዥ መሣሪያዎች"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"በማብራት ላይ..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ከላይ ባለው መተግበሪያ ቁጥጥር ላይ ስለሆነ\n ብሩህነትን ማስተካከል አልተቻለም"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"በራስ ሰር አሽከርክር"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ማያ ገጽን በራስ-አሽከርክር"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"አካባቢ"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"አዲስ መሣሪያ ለማጣመር ጠቅ ያድርጉ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ቅድመ-ቅምጥን ማዘመን አልተቻለም"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ቅድመ-ቅምጥ"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ተመርጧል"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"መሣሪያዎች"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"የቀጥታ መግለጫ ጽሑፍ"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ማስታወሻ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"የመሣሪያ ማይክሮፎን እገዳ ይነሳ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"የመሣሪያ ካሜራ እገዳ ይነሳ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"የመሣሪያ ካሜራ እና ማይክሮፎን እገዳ ይነሳ?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"የማሳወቂያ ረጋ ማለት አሁን በርቷል"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"በአንድ ጊዜ ብዙ ማሳወቂያዎችን ሲያገኙ የመሣሪያዎ ድምፅ እና ማንቂያዎች እስከ 2 ደቂቃዎች ድረስ በራስ-ሰር ይቀንሳሉ።"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"አጥፋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከታች ወዳለ መተግበሪያ ይቀይሩ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከላይ ወዳለ መተግበሪያ ይቀይሩ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"በተከፈለ ማያ ገጽ ወቅት፡- መተግበሪያን ከአንዱ ወደ ሌላው ተካ"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"በማሳያዎች መካከል ንቁ መስኮትን ያንቀሳቅሱ"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ግቤት"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ወደ ቀጣዩ ቋንቋ ቀይር"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ወደ ቀዳሚ ቋንቋ ቀይር"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ከ<xliff:g id="LENGTH">%1$d</xliff:g> የሚያንሱ ቁምፊዎችን ይጠቀሙ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"የውይይት ምግብሮች"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"በመነሻ ማያ ገጽዎ ላይ ለማከል አንድ ውይይት መታ ያድርጉ"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ለከፍተኛ ጥራት ስልኩን ይቀይሩ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"የታጠፈ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"የተዘረጋ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"አቋራጭ ለመመደብ ቁልፍ ይጫኑ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"የእርምጃ ወይም ሜታ ቁልፍ አዶ"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"የመደመር አዶ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"አብጅ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ተከናውኗል"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"መዘርጊያ አዶ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ወይም"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"መያዣ ይጎትቱ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"የቁልፍ ሰሌዳ ቅንብሮች"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"አቋራጭ አቀናብር"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ይቅር"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ቁልፍ ይጫኑ"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"የቁልፍ ጥምረት አስቀድሞ በሥራ ላይ ነው። ሌላ ቁልፍ ይሞክሩ።"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"የቁልፍ ሰሌዳዎን በመጠቀም ያስሱ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"የቁልፍ ሰሌዳ አቋራጮችን ይወቁ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"የመዳሰሻ ሰሌዳዎን በመጠቀም ያስሱ"</string>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index 8601132cf141..b98fe57c232e 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"አጥፋ"</item>
<item msgid="3028994095749238254">"አብራ"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"አይገኝም"</item>
+ <item msgid="6419996398343291862">"ጠፍቷል"</item>
+ <item msgid="5908720590832378783">"በርቷል"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 062ab78d1b31..645d88008b21 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -109,14 +109,14 @@
<string name="screenrecord_title" msgid="4257171601439507792">"مسجّل الشاشة"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
- <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل محتوى الشاشة؟"</string>
- <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل محتوى تطبيق واحد"</string>
- <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل محتوى الشاشة بالكامل"</string>
+ <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل الشاشة؟"</string>
+ <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل شاشة تطبيق واحد"</string>
+ <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل الشاشة بكاملها"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏تسجيل محتوى الشاشة بالكامل: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"أثناء تسجيل محتوى تطبيق، يتم تسجيل أي محتوى يتم عرضه أو تشغيله في ذلك التطبيق. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
- <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل محتوى الشاشة"</string>
- <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"اختيار تطبيق لتسجيل محتواه"</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"سيتم تسجيل كل المحتوى المعروض أو المشغَّل على شاشة التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
+ <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل الشاشة"</string>
+ <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"يُرجى اختيار تطبيق لتسجيل شاشته"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"تسجيل الصوت"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"صوت الجهاز"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"الصوت من جهازك، مثلاً الموسيقى والمكالمات ونغمات الرنين"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"الإدخال"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سماعات الأذن الطبية"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"جارٍ التفعيل…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"لا يمكن ضبط مستوى السطوع لأنّ\n التطبيق الأول يتحكّم فيه"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"التدوير التلقائي"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"التدوير التلقائي للشاشة"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"الموقع الجغرافي"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"انقر لإقران جهاز جديد"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"تعذَّر تعديل الإعداد المسبق"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"الإعدادات المسبقة"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"تمّ اختياره"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"الأدوات"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"النسخ النصي التلقائي"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ملاحظات"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"هل تريد إزالة حظر ميكروفون الجهاز؟"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"هل تريد إزالة حظر كاميرا الجهاز؟"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"هل تريد إزالة حظر الكاميرا والميكروفون؟"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"غير مفعَّل"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"لم يتم ضبط الوضع"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"الإدارة في الإعدادات"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ما مِن أوضاع مفعَّلة}=1{الوضع \"{mode}\" مفعَّل}two{وضعان مفعَّلان}few{‫# أوضاع مفعَّلة}many{‫# وضعًا مفعَّلاً}other{‫# وضع مفعَّل}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ما مِن أوضاع مفعَّلة}=1{‫\"{mode}\" مفعَّل}two{وضعان مفعَّلان}few{‫# أوضاع مفعَّلة}many{‫# وضعًا مفعَّلاً}other{‫# وضع مفعَّل}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات والتذكيرات والأحداث والمتصلين الذين تحددهم. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"لن يتم إزعاجك بالأصوات والاهتزاز، باستثناء المُنبِّهات. وسيظل بإمكانك سماع أي عناصر أخرى تختار تشغيلها، بما في ذلك الموسيقى والفيديوهات والألعاب."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"تخصيص"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"التبديل إلى التطبيق على اليسار أو الأسفل أثناء استخدام \"تقسيم الشاشة\""</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"التبديل إلى التطبيق على اليمين أو الأعلى أثناء استخدام \"تقسيم الشاشة\""</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"نقل نافذة نشطة بين شاشات العرض"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"الإدخال"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"التبديل إلى اللغة التالية"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"التبديل إلى اللغة السابقة"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"يجب استخدام أقل من <xliff:g id="LENGTH">%1$d</xliff:g> حرف."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"التطبيقات المصغّرة للمحادثات"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\""</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"للحصول على درجة دقة أعلى، اقلِب الهاتف."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"مطوي"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"غير مطوي"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"‫%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"اضغط على مفتاح لتخصيص الاختصار"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"البحث في الاختصارات"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"‏رمز مفتاح الإجراء (مفتاح Meta)"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"رمز علامة الجمع (+)"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"تخصيص"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"تم"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"رمز التوسيع"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"أو"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"مقبض السحب"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"إعدادات لوحة المفاتيح"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ضبط الاختصار"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"إلغاء"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"اضغط على مفتاح"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"يتم حاليًا استخدام مجموعة المفاتيح هذه. يُرجى تجربة مفتاح آخر."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"التنقّل باستخدام لوحة المفاتيح"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"تعرَّف على اختصارات لوحة المفاتيح"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"التنقّل باستخدام لوحة اللمس"</string>
@@ -1459,11 +1455,11 @@
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"عرض التطبيقات المستخدَمة مؤخرًا"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"مرِّر سريعًا للأعلى مع الاستمرار باستخدام 3 أصابع على لوحة اللمس"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"أحسنت."</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"لقد أكملْت الدليل التوجيهي على إيماءة \"عرض التطبيقات المستخدَمة مؤخرًا\"."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"لقد أكملْت التدريب على إيماءة عرض التطبيقات المستخدَمة مؤخرًا."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"عرض جميع التطبيقات"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اضغط على مفتاح الإجراء في لوحة المفاتيح"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"أحسنت!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت الدليل التوجيهي عن إيماءة \"عرض جميع التطبيقات\""</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت التدريب على إيماءة عرض جميع التطبيقات"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏مستوى الإضاءة: %1$d من %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index f985e2f001c6..0be4367ae144 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"غير مفعَّلة"</item>
<item msgid="3028994095749238254">"مفعَّلة"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"غير متوفِّرة"</item>
+ <item msgid="6419996398343291862">"متوقّفة"</item>
+ <item msgid="5908720590832378783">"مفعّلة"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 7b3f0bbbc93c..e14f4ccdece6 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ইনপুট"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"শ্ৰৱণ যন্ত্ৰ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"অন কৰি থকা হৈছে…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"উজ্জ্বলতা মিলাব নোৱাৰি কাৰণ সেয়া\n শীৰ্ষৰ এপটোৱে নিয়ন্ত্ৰণ কৰি আছে"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"স্বয়ং-ঘূৰ্ণন"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"অৱস্থান"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইচ পেয়াৰ কৰিবলৈ ক্লিক কৰক"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"প্ৰিছেট আপডে’ট কৰিব পৰা নগ’ল"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্ৰিছেট"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বাছনি কৰা হৈছে"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"সঁজুলি"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ কেপশ্বন"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"টোকা"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইচৰ মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইচৰ কেমেৰা অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইচৰ কেমেৰা আৰু মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"কোনো নতুন জাননী নাই"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"জাননী কুলডাউন কৰা সুবিধাটো এতিয়া অন কৰা হৈছে"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"আপুনি একেলগে বহুতো জাননী পালে আপোনাৰ ডিভাইচটোৰ ভলিউম আৰু সতৰ্কবাৰ্তা স্বয়ংক্ৰিয়ভাৱে ২ মিনিটলৈকে কমোৱা হয়।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"অফ কৰক"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুৰণি জাননী চবলৈ আনলক কৰক"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত সোঁফালে অথবা তলত থকা এপলৈ সলনি কৰক"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত বাওঁফালে অথবা ওপৰত থকা এপলৈ সলনি কৰক"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"বিভাজিত স্ক্ৰীনৰ ব্যৱহাৰ কৰাৰ সময়ত: কোনো এপ্ এখন স্ক্ৰীনৰ পৰা আনখনলৈ নিয়ক"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ডিছপ্লে’সমূহৰ মাজত সক্রিয় হৈ থকা ৱিণ্ড’ সলনা সলনিকৈ ব্যৱহাৰ কৰক"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ইনপুট"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"পৰৱৰ্তী ভাষাটোলৈ সলনি কৰক"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"পূৰ্বৰ ভাষালৈ সলনি কৰক"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> টাতকৈ কম বৰ্ণ ব্যৱহাৰ কৰক"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"বাৰ্তালাপ ৱিজেট"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"আপোনাৰ গৃহ স্ক্ৰীনত কোনো বাৰ্তালাপ যোগ দিবলৈ সেইটোত টিপক"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"অধিক ৰিজ’লিউশ্বনৰ বাবে, ফ’নটো লুটিয়াই দিয়ক"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফ’ল্ড কৰা"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"আনফ’ল্ড কৰা"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"শ্বৰ্টকাটৰ ভূমিকা অৰ্পণ কৰিবলৈ কী টিপক"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"কাৰ্য বা মেটা কীৰ চিহ্ন"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"যোগ চিনৰ চিহ্ন"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"কাষ্টমাইজ কৰক"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"হ’ল"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"বিস্তাৰ কৰাৰ চিহ্ন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ড্ৰেগ হেণ্ডেল"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীব’ৰ্ডৰ ছেটিং"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শ্বৰ্টকাট ছেট কৰক"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল কৰক"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী টিপক"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"কীৰ মিশ্ৰণ ইতিমধ্যে ব্যৱহাৰ হৈ আছে। অন্য এটা কী ব্যৱহাৰ কৰি চাওক।"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"কীব’ৰ্ড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীব’ৰ্ডৰ শ্বৰ্টকাটসমূহৰ বিষয়ে জানক"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index 3ec2f5c67557..da237e51101e 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"অফ আছে"</item>
<item msgid="3028994095749238254">"অন আছে"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"উপলব্ধ নহয়"</item>
+ <item msgid="6419996398343291862">"অফ আছে"</item>
+ <item msgid="5908720590832378783">"অন আছে"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 1c84a590d6b9..90168703b896 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Giriş"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Eşitmə aparatları"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiv edilir..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Yuxarıdakı tətbiq tərəfindən idarə olunduğu üçün\n parlaqlığı tənzimləmək mümkün deyil"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avtodönüş"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranın avtomatik dönməsi"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Məkan"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz birləşdirmək üçün klikləyin"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncəllənmədi"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçilib"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alətlər"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qeyd"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası və mikrofonu blokdan çıxarılsın?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildiriş yoxdur"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Bildiriş gözləmə müddəti artıq aktivdir"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Eyni anda çox bildiriş aldıqda cihazın səs və xəbərdarlıqları avtomatik 2 dəqiqəyə qədər azalır."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiv edin"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Köhnə bildirişləri görmək üçün kilidi açın"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran istifadə edərkən sağda və ya aşağıda tətbiqə keçin"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran istifadə edərkən solda və ya yuxarıda tətbiqə keçin"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişin"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktiv pəncərəni displeylər arasında hərəkət etdirin"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Daxiletmə"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Növbəti dilə keçin"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Əvvəlki dilə keçin"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Maksimum <xliff:g id="LENGTH">%1$d</xliff:g> simvol istifadə edin"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Söhbət vidcetləri"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Əsas ekranınıza əlavə etmək üçün söhbətə toxunun"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksək ayırdetmə dəqiqliyi üçün telefonu çevirin"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"qatlanmış"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"açıq"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatura qısayollarını fərdiləşdirin"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Qısayol təyin etmək üçün düyməni basın"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Axtarış qısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Axtarış nəticəsi yoxdur"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"İkonanı yığcamlaşdırın"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Əməliyyat və ya Meta düyməsi ikonası"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Üstəgəl ikonası"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Fərdiləşdirin"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hazırdır"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"İkonanı genişləndirin"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"və ya"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dəstəyi çəkin"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura ayarları"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Qısayol ayarlayın"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Ləğv edin"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Düyməni basın"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Düymə kombinasiyası artıq istifadə olunur. Başqa düyməni sınayın."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviaturadan istifadə edərək hərəkət edin"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klaviatura qısayolları haqqında öyrənin"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Taçpeddən istifadə edərək hərəkət edin"</string>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index 4eea105107c1..0203fb08ba6a 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Deaktiv"</item>
<item msgid="3028994095749238254">"Aktiv"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Əlçatan deyil"</item>
+ <item msgid="6419996398343291862">"Deaktiv"</item>
+ <item msgid="5908720590832378783">"Aktiv"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index f260f5369f7c..d2636c050db0 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključuje se..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ne možete da prilagodite osvetljenost jer je\n kontroliše aplikacija u vrhu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unapred određena podešavanja"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izabrano"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatke"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titl uživo"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Beleška"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređi u aplikaciju zdesna ili ispod dok je podeljen ekran"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju sleva ili iznad dok koristite podeljeni ekran"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"U režimu podeljenog ekrana: zamena jedne aplikacije drugom"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premesti aktivan prozor na sledeći ekran"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Pređi na sledeći jezik"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Pređi na prethodni jezik"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Koristite manji broj znakova od <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za veću rezoluciju obrnite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Uređaj na preklop se otvara"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Uređaj na preklop se obrće"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zatvoreno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otvoreno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite taster da biste dodelili prečicu"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pretražite prečice"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tastera za radnju ili meta tastera"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za prevlačenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Podešavanja tastature"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Podesi prečicu"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite taster"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tastera se već koristi. Probajte sa drugim tasterom."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tasterskim prečicama"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću tačpeda"</string>
@@ -1450,7 +1446,7 @@
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prevucite ulevo ili udesno sa tri prsta na tačpedu"</string>
- <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Svaka čast!"</string>
+ <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Super!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Dovršili ste pokret za povratak."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Idi na početni ekran"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prevucite nagore sa tri prsta na tačpedu"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index 3f8841afb4f2..2401e4a2fc37 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Isključeno"</item>
<item msgid="3028994095749238254">"Uključeno"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nedostupno"</item>
+ <item msgid="6419996398343291862">"Isključeno"</item>
+ <item msgid="5908720590832378783">"Uključeno"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a303c11ef0fc..388950cb7bdd 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Увод"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слыхавыя апараты"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Уключэнне…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не ўдаецца адрэгуляваць яркасць, бо яна\nкантралюецца асноўнай праграмай"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Націсніце, каб спалучыць новую прыладу"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не ўдалося абнавіць набор налад"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор налад"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрана"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменты"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Аўтаматычныя субцітры"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нататка"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблакіраваць мікрафон прылады?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблакіраваць камеру прылады?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблакіраваць камеру і мікрафон прылады?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пераключыцца на праграму справа або ўнізе на падзеленым экране"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пераключыцца на праграму злева або ўверсе на падзеленым экране"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"У рэжыме падзеленага экрана замяніць адну праграму на іншую"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Перамясціць актыўнае акно паміж дысплэямі"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Увод"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Пераключыцца на наступную мову"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Пераключыцца на папярэднюю мову"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Колькасць сімвалаў павінна быць меншай за <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Віджэты размовы"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Націсніце на размову, каб дадаць яе на галоўны экран"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Каб зрабіць фота з больш высокай раздзяляльнасцю, павярніце тэлефон"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складзена"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"раскладзена"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Націсніце клавішу, каб прызначыць спалучэнне клавіш"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Значок клавішы дзеяння (мета-клавішы)"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Значок плюса"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Наладзіць"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Гатова"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Разгарнуць\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перацягвання"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налады клавіятуры"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Наладзіць спалучэнне клавіш"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасаваць"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Націсніце клавішу"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Гэта спалучэнне клавіш ужо выкарыстоўваецца. Паспрабуйце іншую клавішу."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігацыя з дапамогай клавіятуры"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Азнаёмцеся са спалучэннямі клавіш"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігацыя з дапамогай сэнсарнай панэлі"</string>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index 85602864dc76..2dc705772c6c 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Выключана"</item>
<item msgid="3028994095749238254">"Уключана"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Недаступна"</item>
+ <item msgid="6419996398343291862">"Выключана"</item>
+ <item msgid="5908720590832378783">"Уключана"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a127515e8f19..2d68f9190a30 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Вход"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слухови апарати"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Включва се..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Яркостта не може да се коригира, защото се контролира\n от приложението на екрана"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авт. ориентация"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично завъртане на екрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Местоположение"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за сдвояване на ново устройство"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Предварително зададените настройки не бяха актуализирани"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Предварително зададено"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменти"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Надписи на живо"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Бележка"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се отблокира ли микрофонът на устройството?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се отблокира ли камерата на устройството?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Да се отблокират ли камерата и микрофонът на устройството?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Превключване към приложението вдясно/отдолу в режима на разделен екран"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Превключване към приложението вляво/отгоре в режима на разделен екран"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"При разделен екран: замяна на дадено приложение с друго"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Преместване на активния прозорец между екраните"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Въвеждане"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Превключване към следващия език"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Превключване към предишния език"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Използвайте по-малко от <xliff:g id="LENGTH">%1$d</xliff:g> знака"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Приспособления за разговор"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Докоснете разговор, за да го добавите към началния си екран"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За по-висока разделителна способност обърнете телефона"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Персонализиране на клавишните комбинации"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Натиснете клавиш, за да зададете клавишна комбинация"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма резултати от търсенето"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Икона на клавиша за действия или клавиша Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Икона на плюс"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Персонализиране"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за разгъване"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Манипулатор за преместване с плъзгане"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки на клавиатурата"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задаване на клавишна комбинация"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отказ"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Натиснете клавиш"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Клавишната комбинация вече се използва. Опитайте с друг клавиш."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигирайте посредством клавиатурата си"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете за клавишните комбинации"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигирайте посредством сензорния панел"</string>
@@ -1449,7 +1445,7 @@
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Преглед на скорошните приложения"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
- <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Прекарайте три пръста наляво или надясно по сензорния панел"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Плъзнете три пръста наляво или надясно по сензорния панел"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Чудесно!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Изпълнихте жеста за връщане назад."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Към началния екран"</string>
@@ -1457,7 +1453,7 @@
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Отлично!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Изпълнихте жеста за преминаване към началния екран"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Преглед на скорошните приложения"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Прекарайте три пръста нагоре по сензорния панел и задръжте"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Плъзнете три пръста нагоре по сензорния панел и задръжте"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Отлично!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Изпълнихте жеста за преглед на скорошните приложения."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Преглед на всички приложения"</string>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index 9b808de65480..cc632db72abf 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Изкл."</item>
<item msgid="3028994095749238254">"Вкл."</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Не е налице"</item>
+ <item msgid="6419996398343291862">"Изкл."</item>
+ <item msgid="5908720590832378783">"Вкл."</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index ae810a612d28..4281ea111b03 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ইনপুট"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"হিয়ারিং এড"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"চালু করা হচ্ছে…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"উজ্জ্বলতা টপ অ্যাপ নিয়ন্ত্রণ করায়\n এটিকে অ্যাডজাস্ট করা যাচ্ছে না"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"নিজে থেকে ঘুরবে"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"অটো-রোটেট স্ক্রিন"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"লোকেশন"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইস পেয়ার করতে ক্লিক করুন"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"প্রিসেট আপডেট করা যায়নি"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্রিসেট"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বেছে নেওয়া হয়েছে"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"টুল"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ ক্যাপশন"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"মনে রাখবেন"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইসের মাইক্রোফোন আনব্লক করতে চান?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইসের ক্যামেরা আনব্লক করতে চান?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইসের ক্যামেরা এবং মাইক্রোফোন আনব্লক করতে চান?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"কোনও বিজ্ঞপ্তি নেই"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"নতুন কোনও বিজ্ঞপ্তি নেই"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"নোটিফিকেশন কুলডাউন এখন চালু আছে"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"আপনি একসঙ্গে খুব বেশি বিজ্ঞপ্তি পেলে আপনার ডিভাইসের ভলিউম এবং সতর্কবার্তা সর্বাধিক ২ মিনিটের জন্য অটোমেটিক কমে যায়।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"বন্ধ করুন"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুরনো বিজ্ঞপ্তি দেখতে আনলক করুন"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"স্প্লিট স্ক্রিন ব্যবহার করার সময় ডানদিকের বা নিচের অ্যাপে পাল্টে নিন"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"স্প্লিট স্ক্রিন ব্যবহার করার সময় বাঁদিকের বা উপরের অ্যাপে পাল্টে নিন"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"\'স্প্লিট স্ক্রিন\' থাকাকালীন: একটি অ্যাপ থেকে অন্যটিতে পাল্টান"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ডিসপ্লের মধ্যে একটি থেকে অপরটিতে অ্যাক্টিভ উইন্ডোটি সরান"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ইনপুট"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"পরবর্তী ভাষায় পাল্টান"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"আগের ভাষায় পাল্টান"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>টির চেয়ে কম অক্ষর ব্যবহার করুন"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"কথোপকথন উইজেট"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"কোনও কথোপথন আপনার হোম স্ক্রিনে যোগ করার জন্য এতে ট্যাপ করুন"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"আরও বেশি রেজোলিউশনের জন্য, ফোন ফ্লিপ করুন"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ফোল্ড করা রয়েছে"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ফোল্ড করা নেই"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীবোর্ড শর্টকাট কাস্টমাইজ করুন"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"শর্টকাট অ্যাসাইন করতে কী প্রেস করুন"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"শর্টকাট সার্চ করুন"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"কোনও সার্চ ফলাফল নেই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"আইকন আড়াল করুন"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"অ্যাকশন বা মেটা কী আইকন"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"প্লাস আইকন"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"কাস্টমাইজ করুন"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"হয়ে গেছে"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"আইকন বড় করুন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"টেনে আনার হ্যান্ডেল"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীবোর্ড সেটিংস"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শর্টকাট সেট করুন"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল করুন"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী প্রেস করুন"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"কী কম্বিনেশন আগে থেকে ব্যবহার হচ্ছে। অন্য কী ব্যবহার করে দেখুন।"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"আপনার কীবোর্ড ব্যবহার করে নেভিগেট করুন"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীবোর্ড শর্টকাট সম্পর্কে জানুন"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপনার টাচপ্যাড ব্যবহার করে নেভিগেট করুন"</string>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index dd5b40636fb6..e21392857e7a 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"বন্ধ আছে"</item>
<item msgid="3028994095749238254">"চালু আছে"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"উপলভ্য নেই"</item>
+ <item msgid="6419996398343291862">"বন্ধ আছে"</item>
+ <item msgid="5908720590832378783">"চালু আছে"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index df562ef3508a..9d9bf7f004a2 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -113,8 +113,8 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimaj jednu aplikaciju"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimaj cijeli ekran"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimi cijeli ekran: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimaj ekran"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Odaberite aplikaciju koju želite snimati"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimanje zvuka"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ulaz"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključivanje…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nije moguće podesiti osvijetljenost\n jer njome upravlja aplikacija pri vrhu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko rotiranje"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da uparite novi uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadane postavke nije uspjelo"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Zadana postavka"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Bilješka"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokirati mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokirati kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokirati kameru i mikrofon uređaja?"</string>
@@ -555,21 +555,21 @@
<string name="screen_share_permission_dialog_option_entire_screen" msgid="4493174362775038997">"Dijeli cijeli ekran"</string>
<!-- no translation found for media_projection_entry_app_permission_dialog_option_text_entire_screen (5100078808078139706) -->
<skip />
- <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Kada dijelite cijeli ekran, sve što je na ekranu će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
- <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Kada dijelite cijeli ekran, sve što je na ekranu će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dijeli ekran"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila tu opciju"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju koju želite dijeliti"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Emitirati ekran?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitiraj jednu aplikaciju"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Emitiraj cijeli ekran"</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kada emitirate cijeli ekran, vidljivo je sve što je na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kada emitirate aplikaciju, vidljivo je sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kada emitirate cijeli ekran, vidljivo je sve što je na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kada emitirate aplikaciju, vidljivo je sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Emitiraj ekran"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Odaberite aplikaciju koju želite emitirati"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Pokrenuti dijeljenje?"</string>
- <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada dijelite, snimate ili emitirate, Android ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
- <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kada dijelite, snimate ili emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
+ <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada dijelite, snimate ili emitirate, Android ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
+ <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kada dijelite, snimate ili emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Pokreni"</string>
<string name="media_projection_entry_generic_permission_dialog_continue_single_app" msgid="5920814988611877051">"Naprijed"</string>
<string name="media_projection_task_switcher_text" msgid="590885489897412359">"Dijeljenje se pauzira kada promijenite aplikaciju"</string>
@@ -593,7 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavještenja"</string>
- <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Stišavanje obavijesti sada je uključeno"</string>
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Stišavanje obavještenja je sada uključeno"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Jačina zvuka uređaja i obavještenja se automatski stišavaju do 2 minute kada odjednom dobijete previše obavještenja."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obavještenja"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak u aplikaciju desno ili ispod uz podijeljeni ekran"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju lijevo ili iznad dok koristite podijeljeni ekran"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premještanje aktivnog prozora između ekrana"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Prebacivanje na sljedeći jezik"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prebacivanje na prethodni jezik"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Koristite manje od <xliff:g id="LENGTH">%1$d</xliff:g> znak(ov)a"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti razgovora"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da ga dodate na početni ekran"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu rezoluciju obrnite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sklopljeno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otklopljeno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipku da dodijelite prečicu"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke radnji ili meta tipka"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagođavanje"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona proširivanja"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ručica za prevlačenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tastature"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavi prečicu"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ta se kombinacija tipki već koristi. Pokušajte s drugom tipkom."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o prečicama tastature"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index 3f8841afb4f2..2401e4a2fc37 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Isključeno"</item>
<item msgid="3028994095749238254">"Uključeno"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nedostupno"</item>
+ <item msgid="6419996398343291862">"Isključeno"</item>
+ <item msgid="5908720590832378783">"Uključeno"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0ecd8c0e0c23..0be3d80edcb7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audiòfons"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"S\'està activant…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"No es pot ajustar la brillantor perquè\n està controlada per l\'aplicació superior"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Gira automàticament"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Gira la pantalla automàticament"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicació"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Valors predefinits"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionat"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eines"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítols instantanis"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vols desbloquejar la càmera i el micròfon del dispositiu?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Desactivat"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"No definit"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gestiona a la configuració"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hi ha cap mode actiu}=1{{mode} està actiu}many{Hi ha # de modes actius}other{Hi ha # modes actius}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Cap mode actiu}=1{{mode} està actiu}many{# de modes actius}other{# modes actius}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes, recordatoris, esdeveniments i trucades de les persones que especifiquis. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"No t\'interromprà cap so ni cap vibració, tret dels de les alarmes. Continuaràs sentint tot allò que decideixis reproduir, com ara música, vídeos i jocs."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalitza"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hi ha cap notificació nova"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"La moderació de notificacions està activada"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volum i les alertes del dispositiu es redueixen automàticament durant 2 minuts com a màxim quan reps massa notificacions alhora."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueja per veure notif. anteriors"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Canvia a l\'aplicació de la dreta o de sota amb la pantalla dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Canvia a l\'aplicació de l\'esquerra o de dalt amb la pantalla dividida"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mou la finestra activa entre pantalles"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Canvia a l\'idioma següent"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Caniva a l\'idioma anterior"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilitza menys de <xliff:g id="LENGTH">%1$d</xliff:g> caràcters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversa per afegir-la a la teva pantalla d\'inici"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Per a una resolució més alta, gira el telèfon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegat"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegat"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Prem la tecla per assignar la drecera"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icona de la tecla d\'acció o Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icona del signe més"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalitza"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fet"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Desplega la icona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ansa per arrossegar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuració del teclat"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configura la drecera"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel·la"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prem una tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinació de tecles ja s\'està utilitzant. Prova-ho amb una altra tecla."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega amb el teclat"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprèn les tecles de drecera"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega amb el ratolí tàctil"</string>
@@ -1458,7 +1453,7 @@
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ben fet!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Has completat el gest per anar a la pantalla d\'inici"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Mostra les aplicacions recents"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Llisca cap amunt amb tres dits i mantén premut al ratolí tàctil"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Llisca cap amunt amb tres dits i mantén-los premuts al ratolí tàctil"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ben fet!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completat el gest per veure les aplicacions recents."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Mostra totes les aplicacions"</string>
@@ -1482,7 +1477,7 @@
<string name="home_edu_notification_title" msgid="6097902076909654045">"Utilitza el ratolí tàctil per anar a la pantalla d\'inici"</string>
<string name="home_edu_notification_content" msgid="6631697734535766588">"Llisca tres dits cap amunt. Toca per aprendre més gestos."</string>
<string name="overview_edu_notification_title" msgid="1265824157319562406">"Utilitza el ratolí tàctil per veure les aplicacions recents"</string>
- <string name="overview_edu_notification_content" msgid="3578204677648432500">"Llisca cap amunt amb tres dits i mantén premut. Toca per aprendre més gestos."</string>
+ <string name="overview_edu_notification_content" msgid="3578204677648432500">"Llisca cap amunt amb tres dits i mantén-los premut. Toca per aprendre més gestos."</string>
<string name="all_apps_edu_notification_title" msgid="372262997265569063">"Utilitza el teclat per veure totes les aplicacions"</string>
<string name="all_apps_edu_notification_content" msgid="3255070575694025585">"Prem la tecla d\'acció en qualsevol moment. Toca per aprendre més gestos."</string>
<string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"L\'atenuació extra ara forma part del control lliscant de brillantor"</string>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index ea1a576d2cc0..94d554562b1c 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desactivat"</item>
<item msgid="3028994095749238254">"Activat"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"No disponible"</item>
+ <item msgid="6419996398343291862">"Desactivat"</item>
+ <item msgid="5908720590832378783">"Activat"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3f00ce42939a..1bbef7bce160 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vstup"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Naslouchátka"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Zapínání…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Jas nelze upravit, protože ho\n řídí hlavní aplikace"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. otáčení"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčení obrazovky"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zařízení"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Předvolba"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybráno"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okamžité titulky"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokovat fotoaparát a mikrofon zařízení?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žádná nová oznámení"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Oznámení jsou teď zeslabená"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Když máte moc oznámení najednou, až na dvě minuty se sníží hlasitost zařízení a oznámení se omezí."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnout"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Starší oznámení se zobrazí po odemknutí"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Přepnout na aplikaci vpravo nebo dole v režimu rozdělené obrazovky"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Přepnout na aplikaci vlevo nebo nahoře v režimu rozdělené obrazovky"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Přesunout aktivní okno mezi obrazovkami"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Přepnout na další jazyk"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Přepnout na předchozí jazyk"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Použijte méně než <xliff:g id="LENGTH">%1$d</xliff:g> znaků"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgety konverzací"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Klepnutím na konverzaci ji přidáte na plochu"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Otočte telefon, abyste dosáhli vyššího rozlišení"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"složené"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Přizpůsobení klávesových zkratek"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nastavte zkratku stisknutím klávesy"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhledat zkratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žádné výsledky hledání"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sbalení"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona klávesy Akce nebo Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona Plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Přizpůsobit"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalení"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"nebo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Úchyt pro přetažení"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavení klávesnice"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavit zkratku"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušit"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stiskněte klávesu"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinace kláves se už používá. Použijte jinou klávesu."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigujte pomocí klávesnice"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte se klávesové zkratky"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigujte pomocí touchpadu"</string>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index abfe50df0d36..a02ed764ab0e 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Vypnuto"</item>
<item msgid="3028994095749238254">"Zapnuto"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Není k dispozici"</item>
+ <item msgid="6419996398343291862">"Vypnuto"</item>
+ <item msgid="5908720590832378783">"Zapnuto"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9229b18d3363..b2e17a929900 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Høreapparater"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiverer…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Lysstyrken kan ikke justeres, fordi den\n styres af den øverste app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Roter automatisk"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Roter skærmen automatisk"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokation"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik for at parre en ny enhed"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Forindstillingen kunne ikke opdateres"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forindstilling"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Værktøjer"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstning"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du fjerne blokeringen af enhedens mikrofon?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du fjerne blokeringen af enhedens kamera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du fjerne blokeringen af enhedens kamera og mikrofon?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye notifikationer"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Dæmpning af notifikationer er nu aktiveret"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enheden skruer automatisk ned for lydstyrken og minimerer underretninger på skærmen i op til 2 minutter, når du får for mange notifikationer på én gang."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås op for at se ældre notifikationer"</string>
@@ -700,7 +699,7 @@
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Rumlig lyd"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Fra"</string>
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fast"</string>
- <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Register. af hoved­bevægelser"</string>
+ <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hovedregistrering"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringetilstand"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skift til en app til højre eller nedenfor, når du bruger opdelt skærm"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skift til en app til venstre eller ovenfor, når du bruger opdelt skærm"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Ved opdelt skærm: Udskift én app med en anden"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Flyt det aktive vindue fra skærm til skærm"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Skift til næste sprog"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skift til forrige sprog"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Angiv færre end <xliff:g id="LENGTH">%1$d</xliff:g> tegn"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Samtalewidgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tryk på en samtale for at føje den til din startskærm"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vend telefonen for at få højere opløsning"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"foldet"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"foldet ud"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpas tastaturgenveje"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tryk på en tast for at tildele genvejen"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Der er ingen søgeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon for handlingstast eller metatast"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tilpas"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Udfør"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon for Udvid"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtag"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastaturindstillinger"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Konfigurer genvej"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuller"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tryk på en tast"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tastekombinationen er allerede i brug. Prøv en anden tast."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger ved hjælp af dit tastatur"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Se tastaturgenveje"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger ved hjælp af din touchplade"</string>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 9009eedc39cc..8b536a286af0 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Fra"</item>
<item msgid="3028994095749238254">"Til"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Ikke tilgængelig"</item>
+ <item msgid="6419996398343291862">"Fra"</item>
+ <item msgid="5908720590832378783">"Til"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e8dcae9828ce..5f7128e804d0 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Eingabe"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hörgerät"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Wird aktiviert…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Die Helligkeit kann nicht angepasst werden, weil sie\n von der obersten App gesteuert wird"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. drehen"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Bildschirm automatisch drehen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Standort"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicken, um neues Gerät zu koppeln"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Voreinstellung konnte nicht aktualisiert werden"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voreinstellung"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ausgewählt"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatische Untertitel"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notiz"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blockierung des Gerätemikrofons aufheben?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blockierung der Gerätekamera aufheben?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blockierung von Gerätekamera und Gerätemikrofon aufheben?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Keine neuen Benachrichtigungen"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"„Benachrichtigungen reduzieren” ist jetzt aktiviert"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Wenn du zu viele Benachrichtigungen auf einmal erhältst, wird die Lautstärke automatisch bis zu 2 min lang verringert und Benachrichtigungen werden minimiert."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktivieren"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Für ältere Benachrichtigungen entsperren"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Im Splitscreen-Modus zu einer App rechts oder unten wechseln"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Im Splitscreen-Modus zu einer App links oder oben wechseln"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Im Splitscreen: eine App durch eine andere ersetzen"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktives Fenster auf anderes Display verschieben"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Eingabe"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Zur nächsten Sprache wechseln"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Zur vorherigen Sprache wechseln"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Maximal <xliff:g id="LENGTH">%1$d</xliff:g> Zeichen möglich"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Unterhaltungs-Widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tippe auf eine Unterhaltung, um sie deinem Startbildschirm hinzuzufügen"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Für höhere Auflösung Smartphone umdrehen"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zugeklappt"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aufgeklappt"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tastenkombinationen anpassen"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Drücke eine Taste, um eine Tastenkombination festzulegen"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tastenkürzel suchen"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Keine Suchergebnisse"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Symbol „Minimieren“"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Symbol für Aktions- oder Meta-Taste"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plussymbol"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassen"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fertig"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Symbol „Maximieren“"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oder"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ziehpunkt"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastatureinstellungen"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tastenkombination festlegen"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Abbrechen"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Taste drücken"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Diese Tastenkombination wird bereits verwendet. Versuche es mit einer anderen Taste."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigation mit der Tastatur"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informationen zu Tastenkombinationen"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigation mit dem Touchpad"</string>
@@ -1452,7 +1447,7 @@
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zurück"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Wische mit drei Fingern auf dem Touchpad nach links oder rechts"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sehr gut!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du hast den Schritt für die „Zurück“-Geste abgeschlossen."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du hast das Tutorial für die „Zurück“-Touch-Geste abgeschlossen."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Startbildschirm"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Wische an einer beliebigen Stelle auf dem Touchpad mit drei Fingern nach oben"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Gut gemacht!"</string>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index e7f5b574755a..bb39b4e3c2b3 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Aus"</item>
<item msgid="3028994095749238254">"An"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nicht verfügbar"</item>
+ <item msgid="6419996398343291862">"Aus"</item>
+ <item msgid="5908720590832378783">"An"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index cf9adddcc3ea..fd8e37a34030 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Είσοδος"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Βοηθήματα ακοής"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ενεργοποίηση…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Δεν είναι δυνατή η προσαρμογή της φωτεινότητας, επειδή\n ελέγχεται από την εφαρμογή στην κορυφή"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Αυτόματη περιστροφή"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Αυτόματη περιστροφή οθόνης"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Τοποθεσία"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Κάντε κλικ για σύζευξη νέας συσκευής"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Δεν ήταν δυνατή η ενημέρωση της προεπιλογής"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Προεπιλογή"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Έχει επιλεγεί"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Εργαλεία"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ζωντανοί υπότιτλοι"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Σημείωση"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Κατάργηση αποκλεισμού μικροφώνου συσκευής;"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Κατάργηση αποκλεισμού κάμερας συσκευής;"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Κατάργηση αποκλεισμού κάμερας και μικροφώνου συσκευής;"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Εναλλαγή στην εφαρμογή δεξιά ή κάτω κατά τη χρήση διαχωρισμού οθόνης"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Εναλλαγή σε εφαρμογή αριστερά ή επάνω κατά τη χρήση διαχωρισμού οθόνης"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Κατά τον διαχωρισμό οθόνης: αντικατάσταση μιας εφαρμογής με άλλη"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Μετακίνηση ενεργού παραθύρου μεταξύ οθονών"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Είσοδος"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Εναλλαγή στην επόμενη γλώσσα"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Εναλλαγή στην προηγούμενη γλώσσα"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Χρησιμοποιήστε λιγότερους από <xliff:g id="LENGTH">%1$d</xliff:g> χαρακτήρες"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Γραφικά στοιχεία συνομιλίας"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Πατήστε μια συνομιλία για να την προσθέσετε στην αρχική οθόνη"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Για υψηλότερη ανάλυση, αναστρέψτε το τηλέφωνο"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"διπλωμένη"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ξεδιπλωμένη"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Προσαρμογή συντομεύσεων πληκτρολογίου"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Πατήστε το πλήκτρο για εκχώρηση της συντόμευσης"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Συντομεύσεις αναζήτησης"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Κανένα αποτέλεσμα αναζήτησης"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Εικονίδιο σύμπτυξης"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Εικονίδιο πλήκτρου ενέργειας ή Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Εικονίδιο συν"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Προσαρμογή"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Τέλος"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Εικονίδιο ανάπτυξης"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ή"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Λαβή μεταφοράς"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ρυθμίσεις πληκτρολογίου"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ορισμός συντόμευσης"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Ακύρωση"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Πατήστε ένα πλήκτρο"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ο συνδυασμός πλήκτρων χρησιμοποιείται ήδη. Δοκιμάστε άλλο πλήκτρο."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Πλοήγηση με το πληκτρολόγιο"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Μάθετε συντομεύσεις πληκτρολογίου"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Πλοήγηση με την επιφάνεια αφής"</string>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 1276fb4addbc..ec2a930dcb75 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Ανενεργή"</item>
<item msgid="3028994095749238254">"Ενεργή"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Μη διαθέσιμο"</item>
+ <item msgid="6419996398343291862">"Ανενεργό"</item>
+ <item msgid="5908720590832378783">"Ενεργό"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 66659599dc94..4280ff2ad994 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -113,8 +113,8 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choose app to record"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Can\'t adjust brightness because it\'s being\n controlled by the top app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Move active window between displays"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard settings"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index c0bbabea4d78..1b60921d3237 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Off"</item>
<item msgid="3028994095749238254">"On"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Unavailable"</item>
+ <item msgid="6419996398343291862">"Off"</item>
+ <item msgid="5908720590832378783">"On"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 9a3bedaabe4c..3b009a1f1d14 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -414,6 +414,8 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
<string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
@@ -1218,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your Home screen"</string>
@@ -1353,6 +1357,7 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <string name="rear_display_unfolded_front_screen_on" msgid="5946436677205643170">"Front screen turned on"</string>
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 66659599dc94..4280ff2ad994 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -113,8 +113,8 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choose app to record"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Can\'t adjust brightness because it\'s being\n controlled by the top app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Move active window between displays"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard settings"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index c0bbabea4d78..1b60921d3237 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Off"</item>
<item msgid="3028994095749238254">"On"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Unavailable"</item>
+ <item msgid="6419996398343291862">"Off"</item>
+ <item msgid="5908720590832378783">"On"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 66659599dc94..4280ff2ad994 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -113,8 +113,8 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choose app to record"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Record audio"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hearing aids"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Turning on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Can\'t adjust brightness because it\'s being\n controlled by the top app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Move active window between displays"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Switch to previous language"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use fewer than <xliff:g id="LENGTH">%1$d</xliff:g> characters"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"folded"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"unfolded"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Press key to assign shortcut"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customise"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Keyboard settings"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Set shortcut"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Press key"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Key combination already in use. Try another key."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index c0bbabea4d78..1b60921d3237 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Off"</item>
<item msgid="3028994095749238254">"On"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Unavailable"</item>
+ <item msgid="6419996398343291862">"Off"</item>
+ <item msgid="5908720590832378783">"On"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3dc305811498..ad403b1658ee 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -114,7 +114,7 @@
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabar toda la pantalla: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se grabará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se registrará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se grabará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Elige una app para grabar"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabar audio"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audífonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"La app superior controla el brillo,\npor lo que no se puede ajustar"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar la pantalla automáticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para vincular un dispositivo nuevo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No se pudo actualizar el ajuste predeterminado"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ajuste predeterminado"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitulado instantáneo"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Quieres desbloquear el micrófono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Quieres desbloquear la cámara del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Quieres desbloquear la cámara y el micrófono del dispositivo?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Desactivado"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Sin establecer"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Administrar en configuración"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} está activo}many{# de modos están activos}other{# modos están activos}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} activo}many{# de modos activos}other{# modos activos}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas de los emisores que especifiques. Podrás escuchar el contenido que reproduzcas, como música, videos y juegos."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas. Podrás escuchar el contenido que reproduzcas, como música, videos y juegos."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ubicar la app a la derecha o abajo cuando usas la pantalla dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ubicar la app a la izquierda o arriba cuando usas la pantalla dividida"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Durante pantalla dividida: Reemplaza una app con otra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover la ventana activa de una pantalla a otra"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar al próximo idioma"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar al idioma anterior"</string>
@@ -1007,7 +1006,7 @@
<string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi desactivado"</string>
<string name="bt_is_off" msgid="7436344904889461591">"Bluetooth desactivado"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"No interrumpir desactivado"</string>
- <string name="dnd_is_on" msgid="7009368176361546279">"No interrumpir está activado"</string>
+ <string name="dnd_is_on" msgid="7009368176361546279">"No interrumpir activado"</string>
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Se activó el modo No interrumpir con una regla automática (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Se activó el modo No interrumpir con una app (<xliff:g id="ID_1">%s</xliff:g>)."</string>
<string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Se activó el modo No interrumpir con una app o regla automática."</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Presiona una conversación para agregarla a tu pantalla principal"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para obtener una resolución más alta, gira el teléfono"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable siendo girado"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personaliza las combinaciones de teclas"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Presiona la tecla para asignar el acceso directo"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Buscar combinaciones de teclas"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"La búsqueda no arrojó resultados"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícono de contraer"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícono tecla meta o de acción"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ícono de signo más"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Listo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícono de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuración del teclado"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Presiona una tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinación de teclas ya está en uso. Prueba con otra."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega con el teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega con el panel táctil"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index dec68dae3dc1..1c587d663563 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desactivados"</item>
<item msgid="3028994095749238254">"Activados"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"No disponible"</item>
+ <item msgid="6419996398343291862">"Desactivado"</item>
+ <item msgid="5908720590832378783">"Activado"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 4660d9879e76..50de6d2e452a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audífonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"No se puede ajustar el brillo porque la aplicación superior lo está\n controlando"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar pantalla automáticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para emparejar un nuevo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"No se ha podido actualizar el preajuste"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preajuste"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos automáticos"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Desbloquear la cámara y el micrófono del dispositivo?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Desactivado"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Sin definir"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gestionar en los ajustes"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} está activo}many{Hay # modos activos}other{Hay # modos activos}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{No hay modos activos}=1{{mode} activo}many{Hay # modos activos}other{Hay # modos activos}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas, los recordatorios, los eventos y las llamadas que especifiques. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"No te molestarán los sonidos ni las vibraciones, excepto las alarmas. Seguirás escuchando el contenido que quieras reproducir, como música, vídeos y juegos."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Bajar volumen de notificaciones ahora está activado"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"El volumen y las alertas de tu dispositivo se reducen durante hasta 2 minutos si recibes muchas notificaciones a la vez."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
@@ -716,7 +715,7 @@
<string name="volume_panel_hint_muted" msgid="1124844870181285320">"silenciado"</string>
<string name="volume_panel_hint_vibrate" msgid="4136223145435914132">"vibrar"</string>
<string name="media_output_label_title" msgid="872824698593182505">"Reproduciendo <xliff:g id="LABEL">%s</xliff:g> en"</string>
- <string name="media_output_title_without_playing" msgid="3825663683169305013">"Se reproducirá en"</string>
+ <string name="media_output_title_without_playing" msgid="3825663683169305013">"El audio se reproducirá en"</string>
<string name="media_output_title_ongoing_call" msgid="208426888064112006">"Llamando desde"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Configurador de UI del sistema"</string>
<string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar a la aplicación de la derecha o de abajo en pantalla dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar a la app de la izquierda o de arriba en pantalla dividida"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Con pantalla dividida: reemplazar una aplicación por otra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover ventana activa de una pantalla a otra"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar a siguiente idioma"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar a idioma anterior"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversación para añadirla a la pantalla de inicio"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para una mayor resolución, gira el teléfono"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plegado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"desplegado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pulsa una tecla para asignar una combinación de teclas"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icono de la tecla de acción o de la tecla Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icono de más"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hecho"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icono de desplegar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ajustes del teclado"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pulsa una tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"La combinación de teclas ya se está usando. Prueba con otra tecla."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Desplázate con el teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Desplázate con el panel táctil"</string>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index e872c263f1e6..5c4f36a064db 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desactivados"</item>
<item msgid="3028994095749238254">"Activado"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"No disponible"</item>
+ <item msgid="6419996398343291862">"Desactivado"</item>
+ <item msgid="5908720590832378783">"Activado"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f2a92f299081..9c0d56dad8c3 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -115,8 +115,8 @@
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Kogu ekraanikuva salvestamine: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kui salvestate kogu ekraani, salvestatakse kõik ekraanil kuvatud andmed. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kui salvestate rakendust, salvestatakse kõik, mida selles rakenduses näidatakse või esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
- <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekraanikuva jäädvustamine"</string>
- <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Vali salvestamiseks rakendus"</string>
+ <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Salvesta ekraanikuva"</string>
+ <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Valige salvestamiseks rakendus"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Salvesta heli"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Seadme heli"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Seadmest pärinev heli, nt muusika, kõned ja helinad"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Sisend"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Kuuldeaparaadid"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Sisselülitamine …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Heledust ei saa reguleerida, kuna seda\n juhib ülemine rakendus"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. pööramine"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Kuva automaatne pööramine"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Asukoht"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Eelseadistus"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valitud"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tööriistad"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Reaalajas subtiitrid"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Märkus"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kas tühistada seadme kaamera ja mikrofoni blokeerimine?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Uusi märguandeid ei ole"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Märguannete summutamine on nüüd sisse lülitatud"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Kui saate korraga liiga palju märguandeid, vähendab seade automaatselt helitugevust ja minimeerib märguanded kuni kaheks minutiks."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Lülita välja"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vanemate märguannete nägemiseks avage"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Paremale või alumisele rakendusele lülitamine jagatud ekraani ajal"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vasakule või ülemisele rakendusele lülitamine jagatud ekraani ajal"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Ekraanikuva jagamise ajal: ühe rakenduse asendamine teisega"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktiivse akna teisaldamine ekraanide vahel"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sisend"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Järgmisele keelele lülitamine"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Eelmisele keelele lülitamine"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Kasutage vähem kui <xliff:g id="LENGTH">%1$d</xliff:g> tähemärki"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Vestlusvidinad"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Puudutage vestlust, et lisada see oma avakuvale"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Suurema eraldusvõime saavutamiseks pöörake telefon ümber"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kokku volditud"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"lahti volditud"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,35 +1418,28 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatuuri otseteede kohandamine"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Otsetee lisamiseks vajutage klahvi"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsige otseteid"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Otsingutulemused puuduvad"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ahendamisikoon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Toiming või metaklahv"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluss-ikoon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Kohandamine"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Valmis"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laiendamisikoon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"või"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Lohistamispide"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatuuri seaded"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Määrake otsetee"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Tühista"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Vajutage klahvi"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Klahvikombinatsioon juba kasutusel. Proovige mõnda muud klahvi."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeerige klaviatuuri abil"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Õppige klaviatuuri otseteid"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeerige puuteplaadi abil"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Õppige puuteplaadi liigutusi"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Navigeerige klaviatuuri ja puuteplaadi abil"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Õppige puuteplaadi liigutusi, klaviatuuri otseteid ja palju muud"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Õppige puuteplaadi liigutusi, klaviatuuri otseteid ja palju muud."</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Mine tagasi"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Avakuvale"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Hiljutiste rakenduste vaatamine"</string>
@@ -1460,7 +1455,7 @@
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Hiljutiste rakenduste vaatamine"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Pühkige üles ja hoidke kolme sõrme puuteplaadil"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Väga hea!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Lõpetasite hiljutiste rakenduste vaatamise liigutuse."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Tegite hiljutiste rakenduste vaatamise liigutuse."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Kõigi rakenduste kuvamine"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Vajutage klaviatuuril toiminguklahvi"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hästi tehtud!"</string>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 3af8dea15541..f9951280e5d4 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Välja lülitatud"</item>
<item msgid="3028994095749238254">"Sisse lülitatud"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Pole saadaval"</item>
+ <item msgid="6419996398343291862">"Väljas"</item>
+ <item msgid="5908720590832378783">"Sees"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index daca2a37635e..a971d1c25a16 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pantaila osoa grabatzen ari zarenean, pantailan agertzen den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Aplikazio bat grabatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabatu pantaila"</string>
- <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Aukeratu zer aplikazio grabatu nahi duzun"</string>
+ <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Aukeratu zein aplikazio grabatu nahi duzun"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabatu audioa"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Gailuaren audioa"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Gailuko soinuak; adibidez, musika, deiak eta tonuak"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Sarrera"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audifonoak"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktibatzen…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ezin da doitu argitasuna,\ngaineko aplikazioak kontrolatzen duelako"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Biratze automatikoa"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Biratu pantaila automatikoki"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Kokapena"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Egin klik beste gailu bat parekatzeko"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ezin izan da eguneratu aurrezarpena"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Aurrezarpena"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Hautatuta"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tresnak"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Istanteko azpitituluak"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Oharra"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Gailuaren kamera eta mikrofonoa desblokeatu nahi dituzu?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ez dago jakinarazpen berririk"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Orain, jakinarazpenak arintzeko ezarpena aktibatuta dago"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Aldi berean jakinarazpen gehiegi jasotzen badituzu, gailuaren bolumena eta alertak automatikoki murriztuko dira 2 minutuz (gehienez)."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desaktibatu"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Jakinarazpen zaharragoak ikusteko, desblokeatu"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Aldatu eskuineko edo beheko aplikaziora pantaila zatitua erabiltzean"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Aldatu ezkerreko edo goiko aplikaziora pantaila zatitua erabiltzean"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Pantaila zatituan zaudela, ordeztu aplikazio bat beste batekin"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Eraman leiho aktiboa pantaila batetik bestera"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sarrera"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Aldatu hurrengo hizkuntzara"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Aldatu aurreko hizkuntzara"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Erabili <xliff:g id="LENGTH">%1$d</xliff:g> karaktere baino gutxiago"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Elkarrizketa-widgetak"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Sakatu elkarrizketa bat orri nagusian gehitzeko"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Irauli telefonoa bereizmen handiago a lortzeko"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"tolestuta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tolestu gabe"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pertsonalizatu lasterbideak"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Sakatu tekla lasterbidea esleitzeko"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bilatu lasterbideak"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ez dago bilaketa-emaitzarik"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tolesteko ikonoa"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ekintzaren edo Meta teklaren ikonoa"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus-ikonoa"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pertsonalizatu"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Eginda"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Zabaltzeko ikonoa"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"edo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Arrastatzeko kontrol-puntua"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Teklatuaren ezarpenak"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ezarri lasterbidea"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Utzi"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Sakatu tekla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tekla-konbinazio hori erabili da dagoeneko. Probatu beste tekla bat."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nabigatu teklatua erabilita"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ikasi lasterbideak"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nabigatu ukipen-panela erabilita"</string>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index 8ada72a9f3ae..5d4672f55adc 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desaktibatuta"</item>
<item msgid="3028994095749238254">"Aktibatuta"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Ez dago erabilgarri"</item>
+ <item msgid="6419996398343291862">"Desaktibatuta"</item>
+ <item msgid="5908720590832378783">"Aktibatuta"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 4f2c89e57216..bf7ccf0d8079 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ورودی"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سمعک"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"روشن کردن…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"نمی‌توان روشنایی را تنظیم کرد زیرا\n برنامه بالایی آن را کنترل می‌کند"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"چرخش خودکار"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"چرخش خودکار صفحه‌نمایش"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"مکان"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"برای جفت کردن دستگاه جدید، کلیک کنید"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"پیش‌تنظیم به‌روزرسانی نشد"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"پیش‌تنظیم"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"انتخاب‌شده"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ابزارها"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس زنده ناشنوایان"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"یادداشت"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"دوربین و میکروفون دستگاه لغو انسداد شود؟"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"رفتن به برنامه سمت راست یا پایین درحین استفاده از صفحهٔ دونیمه"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"رفتن به برنامه سمت چپ یا بالا درحین استفاده از صفحهٔ دونیمه"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"درحین صفحهٔ دونیمه: برنامه‌ای را با دیگری جابه‌جا می‌کند"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"جابه‌جا کردن پنجره فعال بین نمایشگرها"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ورودی"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"رفتن به زبان بعدی"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"رفتن به زبان قبلی"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"از کمتر از <xliff:g id="LENGTH">%1$d</xliff:g> نویسه استفاده کنید"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ابزارک‌های مکالمه"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمه‌ای تک‌ضرب بزنید تا به «صفحه اصلی» اضافه شود"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"برای وضوح بیشتر، تلفن را بچرخانید"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"تاشده"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"تانشده"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"میان‌برهای صفحه‌کلید"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"سفارشی‌سازی کردن میان‌برهای صفحه‌کلید"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"برای اختصاص دادن میان‌بر، کلید را فشار دهید"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"جستجوی میان‌برها"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"نتیجه‌ای برای جستجو پیدا نشد"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"نماد جمع کردن"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"نماد کلید کنش یا متا"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"نماد جمع"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"سفارشی‌سازی کردن"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"تمام"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"نماد ازهم بازکردن"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"دستگیره کشاندن"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"تنظیمات صفحه‌کلید"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"تنظیم میان‌بر"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"لغو"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید را فشار دهید"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ترکیب کلید ازقبل درحال استفاده است. کلید دیگری را امتحان کنید."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"پیمایش کردن بااستفاده از صفحه‌کلید"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"آشنایی با میان‌برهای صفحه‌کلید"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"پیمایش کردن بااستفاده از صفحه لمسی"</string>
@@ -1446,7 +1442,7 @@
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"آشنایی با اشاره‌های صفحه لمسی، میان‌برهای صفحه‌کلید، و موارد دیگر"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"برگشتن"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"رفتن به صفحه اصلی"</string>
- <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"مشاهده کردن برنامه‌های اخیر"</string>
+ <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"مشاهده برنامه‌های اخیر"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تمام"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"برگشتن"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"با سه انگشت روی صفحه لمسی تند به چپ یا راست بکشید."</string>
@@ -1456,14 +1452,14 @@
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"با سه انگشت روی صفحه لمسی تند به بالا بکشید"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"عالی است!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"اشاره رفتن به صفحه اصلی را تکمیل کردید"</string>
- <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"مشاهده کردن برنامه‌های اخیر"</string>
+ <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"مشاهده برنامه‌های اخیر"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"با سه انگشت روی صفحه لمسی تند به بالا بکشید و نگه دارید"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"عالی است!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"اشاره مشاهده برنامه‌های اخیر را انجام دادید"</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"اشاره «مشاهده برنامه‌های اخیر» را تمام کردید"</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"مشاهده همه برنامه‌ها"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"دکمه کنش را روی صفحه لمسی فشار دهید"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"عالی بود!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره مشاهده همه برنامه‌ها را انجام دادید"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره «مشاهده همه برنامه‌ها» را تمام کردید"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پس‌زمینه صفحه‌کلید"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏سطح %1$d از %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index b7f4830db666..1f9d6c6218f7 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"خاموش"</item>
<item msgid="3028994095749238254">"روشن"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"دردسترس نیست"</item>
+ <item msgid="6419996398343291862">"خاموش"</item>
+ <item msgid="5908720590832378783">"روشن"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 581f0eada3ac..89ed95f0115f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Syöttölaite"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Kuulolaitteet"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Otetaan käyttöön…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kirkkautta ei voi säätää, koska \n ensisijainen sovellus ohjaa sitä"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automaattinen kääntö"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Käännä näyttöä automaattisesti."</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Sijainti"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Esiasetus"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valittu"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Työkalut"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstitys"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Muistiinpano"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ei uusia ilmoituksia"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Ilmoitusten vaimennus on nyt päällä"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Äänenvoimakkuus ja ilmoitukset vaimennetaan enintään 2 minuutiksi, kun saat paljon ilmoituksia."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Laita pois päältä"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Avaa lukitus niin näet ilmoituksia"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Vaihda sovellukseen oikealla tai alapuolella jaetussa näytössä"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vaihda sovellukseen vasemmalla tai yläpuolella jaetussa näytössä"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Jaetun näytön aikana: korvaa sovellus toisella"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Siirrä aktiivinen ikkuna näytöltä toiselle"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Syöttötapa"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Vaihda seuraavaan kieleen"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Vaihda aiempaan kieleen"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Käytä alle <xliff:g id="LENGTH">%1$d</xliff:g> merkkiä"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Keskusteluwidgetit"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Lisää keskustelu aloitusnäytölle napauttamalla sitä"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Resoluutio on parempi, kun käännät puhelimen"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"taitettu"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"taittamaton"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Määritä pikanäppäin painamalla näppäintä"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Toiminto- tai Meta-näppäinkuvake"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluskuvake"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Muokkaa"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Valmis"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laajennuskuvake"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"tai"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vetokahva"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Näppäimistön asetukset"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Valitse pikanäppäin"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Peru"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paina näppäintä"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Näppäinyhdistelmä on jo käytössä. Kokeile toista näppäintä."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Siirry käyttämällä näppäimistöä"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Opettele pikanäppäimiä"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Siirry käyttämällä kosketuslevyä"</string>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index e323b8a46bc4..96750ef02d01 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Pois päältä"</item>
<item msgid="3028994095749238254">"Päällä"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Ei saatavilla"</item>
+ <item msgid="6419996398343291862">"Pois päältä"</item>
+ <item msgid="5908720590832378783">"Päällä"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index bae94715ae6b..708d8b910306 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrée"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Prothèses auditives"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activation en cours…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Impossible de régler la luminosité, car elle est\n contrôlée par l\'appli principale"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation auto"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquez ici pour associer un nouvel appareil"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour le préréglage"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le microphone?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'Écran divisé"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'appli à gauche ou au-dessus avec l\'Écran divisé"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une appli par une autre"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Déplacer la fenêtre active d\'un écran à l\'autre"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrée"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passer à la langue précédente"</string>
@@ -1202,7 +1201,7 @@
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Haut-parleurs et écrans"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string>
- <string name="media_input_group_title" msgid="2057057473860783021">"Entrer"</string>
+ <string name="media_input_group_title" msgid="2057057473860783021">"Entrée"</string>
<string name="media_output_group_title" msgid="6789001895863332576">"Sortie"</string>
<string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Arrêtez votre session partagée pour déplacer des contenus multimédias vers un autre appareil"</string>
<string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Arrêter"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilisez moins de <xliff:g id="LENGTH">%1$d</xliff:g> caractères"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Touchez une conversation pour l\'ajouter à votre écran d\'accueil"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une meilleure résolution, retournez le téléphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis-clavier"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Appuyez sur la touche pour attribuer un raccourci"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icône de la touche Action ou Méta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icône Plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personnaliser"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Terminé"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Définir un raccourci"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide de votre clavier"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis-clavier"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index 0bbacd09259c..782c05528fc0 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Désactivé"</item>
<item msgid="3028994095749238254">"Activé"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Non accessible"</item>
+ <item msgid="6419996398343291862">"Désactivée"</item>
+ <item msgid="5908720590832378783">"Activée"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2006ea6d0348..41bd9106fb45 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -113,7 +113,7 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer tout l\'écran"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Enregistrer tout l\'écran : %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails du mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails de mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans celle-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Choisir l\'appli à enregistrer"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrée"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Appareils auditifs"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activation…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Impossible d\'ajuster la luminosité, car celle-ci\n est contrôlée par l\'appli principale"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation auto"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"La limitation des notifications est maintenant activée"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Les alertes et le volume de l\'appareil sont réduits automatiquement pendant 2 minutes maximum quand vous recevez trop de notifications à la fois."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverrouiller pour voir anciennes notifications"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'écran partagé"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passez à l\'appli à gauche ou au-dessus avec l\'écran partagé"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Déplacer la fenêtre active d\'un écran à l\'autre"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Saisie"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Revenir à la langue précédente"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utilisez moins de <xliff:g id="LENGTH">%1$d</xliff:g> caractères"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Appuyez sur une conversation pour l\'ajouter à votre écran d\'accueil"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une résolution plus élevée, retournez le téléphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"plié"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"déplié"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,33 +1418,26 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis clavier"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Appuyez sur une touche pour attribuer un raccourci"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Rechercher des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icône de touche d\'action ou de méta-touche"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icône Plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personnaliser"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"OK"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Paramètres du clavier"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Définir un raccourci"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide du clavier"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis clavier"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string>
- <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Découvrir les gestes au pavé tactile"</string>
+ <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Découvrez les gestes au pavé tactile"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Naviguer à l\'aide de votre clavier et de votre pavé tactile"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Découvrir les gestes au pavé tactile, les raccourcis clavier et plus encore"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Retour"</string>
@@ -1452,7 +1447,7 @@
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Balayez vers la gauche ou la droite avec trois doigts sur le pavé tactile"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bravo !"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Vous avez appris le geste pour revenir en arrière."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Vous avez appris le geste pour revenir en arrière"</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Retour à l\'accueil"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Balayez vers le haut avec trois doigts sur le pavé tactile"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bravo !"</string>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index d0853f4a3185..ffceb0dfe776 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Désactivé"</item>
<item msgid="3028994095749238254">"Activé"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Indisponible"</item>
+ <item msgid="6419996398343291862">"Désactivé"</item>
+ <item msgid="5908720590832378783">"Activé"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index ebc19bd883f7..398360689afe 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Audiófonos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Activando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Non se pode axustar o brillo\n porque o controla a aplicación principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automaticamente"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Xirar pantalla automaticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localización"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic para vincular un novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Non se puido actualizar a configuración predeterminada"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Configuración predeterminada"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Elemento seleccionado"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos instantáneos"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Queres desbloquear a cámara do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Queres desbloquear a cámara e o micrófono do dispositivo?"</string>
@@ -578,7 +578,7 @@
<string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Cambio de aplicación"</string>
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"O teu administrador de TI bloqueou esta aplicación"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A política do dispositivo desactivou a opción de capturar a pantalla"</string>
- <string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todo"</string>
+ <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
<string name="notification_settings_button_description" msgid="2441994740884163889">"Configuración de notificacións"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Non hai notificacións novas"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Agora a opción Amainar notificacións está activada"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ao recibir moitas notificacións, o volume e as alertas redúcense automaticamente ata dous minutos."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver máis notificacións"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar á aplicación da dereita ou de abaixo coa pantalla dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar á aplicación da esquerda ou de arriba coa pantalla dividida"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"En modo de pantalla dividida: Substituír unha aplicación por outra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover ventá activa entre pantallas"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar ao seguinte idioma"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Cambiar ao idioma anterior"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Utiliza menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toca unha conversa para engadila á pantalla de inicio"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Dálle a volta ao teléfono para gozar dunha maior resolución"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dispositivo pregado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dispositivo despregado"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar os atallos de teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Preme a tecla para asignar o atallo"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Busca atallos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Non hai resultados de busca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona de contraer"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icona da tecla Meta ou de acción"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icona do signo máis"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Feito"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona de despregar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuración do teclado"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atallo"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Preme unha tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Xa se está usando esta combinación de teclas. Proba con outra."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega co teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende a usar os atallos de teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega co panel táctil"</string>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 18ad3df0a8c1..7889983f193b 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desactivados"</item>
<item msgid="3028994095749238254">"Activados"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Non dispoñible"</item>
+ <item msgid="6419996398343291862">"Opción desactivada"</item>
+ <item msgid="5908720590832378783">"Opción activada"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index d5e7ca4177aa..89012697cfac 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ઇનપુટ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"સાંભળવામાં મદદ આપતા યંત્રો"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ચાલુ કરી રહ્યાં છીએ…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"બ્રાઇટનેસ ગોઠવી શકતા નથી કારણ કે તે\n લોકપ્રિય ઍપ દ્વારા નિયંત્રિત કરવામાં આવી રહી છે"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ઑટો રોટેટ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ઑટો રોટેટ સ્ક્રીન"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"લોકેશન"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"નવા ડિવાઇસ સાથે જોડાણ કરવા માટે ક્લિક કરો"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"પ્રીસેટ અપડેટ કરી શક્યા નથી"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"પ્રીસેટ"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"પસંદ કરી છે"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ટૂલ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"લાઇવ કૅપ્શન"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"નોંધ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ડિવાઇસના માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ડિવાઇસના કૅમેરાને અનબ્લૉક કરીએ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ડિવાઇસના કૅમેરા અને માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે જમણી બાજુ કે નીચેની ઍપ પર સ્વિચ કરો"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે ડાબી બાજુની કે ઉપરની ઍપ પર સ્વિચ કરો"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"વિભાજિત સ્ક્રીન દરમિયાન: એક ઍપને બીજી ઍપમાં બદલો"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"સક્રિય વિન્ડોને ડિસ્પ્લેની વચ્ચે ખસેડો"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ઇનપુટ"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"આગલી ભાષા પર સ્વિચ કરો"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"પાછલી ભાષા પર સ્વિચ કરો"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> કરતાં ઓછા અક્ષરનો ઉપયોગ કરો"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"વાતચીતના વિજેટ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"તમારી હોમ સ્ક્રીનમાં વાતચીત ઉમેરવા માટે તેના પર ટૅપ કરો"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"વધુ રિઝોલ્યુશન માટે, ફોનને ફ્લિપ કરો"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ફોલ્ડ કરેલું"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"અનફોલ્ડ કરેલું"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"શૉર્ટકટ સોંપવા માટે દી દબાવો"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ઍક્શન અથવા મેટા કીનું આઇકન"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"પ્લસનું આઇકન"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"કસ્ટમાઇઝ કરો"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"થઈ ગયું"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\'મોટું કરો\'નું આઇકન"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"અથવા"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"કીબોર્ડના સેટિંગ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"શૉર્ટકટ સેટ કરો"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"રદ કરો"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"કી દબાવો"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"કી સંયોજન પેહલેથી ઉપયોગમાં છે. અન્ય કી અજમાવી જુઓ."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"તમારા કીબોર્ડ વડે નૅવિગેટ કરો"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"કીબોર્ડ શૉર્ટકર્ટ જાણો"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"તમારા ટચપૅડ વડે નૅવિગેટ કરો"</string>
@@ -1459,11 +1455,11 @@
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"તાજેતરની ઍપ જુઓ"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"તમારા ટચપૅડ પર ત્રણ આંગળીઓનો ઉપયોગ કરીને ઉપર સ્વાઇપ કરો અને દબાવી રાખો"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ખૂબ સરસ કામ!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"તમે \"તાજેતરની ઍપ જુઓ\" સંકેત પૂર્ણ કર્યો."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"તમે \'તાજેતરની ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"બધી ઍપ જુઓ"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"વાહ!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \"બધી ઍપ જુઓ\" સંકેત પૂર્ણ કર્યો"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \'બધી ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index e6202321148f..8c8d5f649407 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"બંધ છે"</item>
<item msgid="3028994095749238254">"ચાલુ છે"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"અનુપલબ્ધ"</item>
+ <item msgid="6419996398343291862">"બંધ"</item>
+ <item msgid="5908720590832378783">"ચાલુ"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index cad756d0cebb..241e2e630013 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -109,12 +109,12 @@
<string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रिकॉर्डर"</string>
<string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
<string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
- <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन रिकॉर्ड करनी है?"</string>
- <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन की रिकॉर्डिंग करें"</string>
+ <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन को रिकॉर्ड करना है?"</string>
+ <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन रिकॉर्ड करें"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरी स्क्रीन रिकॉर्ड करें"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"पूरी स्क्रीन रिकॉर्ड करें: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"पूरी स्क्रीन रिकॉर्ड करते समय, स्क्रीन पर दिखने वाली हर चीज़ रिकॉर्ड की जाती है. इसलिए पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, डिवाइस पर चल रहे ऑडियो और वीडियो, और फ़ोटो जैसी चीज़ों को लेकर सावधानी बरतें."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया दूसरी स्क्रीन पर भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रिकॉर्ड करें"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रिकॉर्ड करने के लिए ऐप्लिकेशन चुनें"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"ऑडियो रिकॉर्ड करें"</string>
@@ -125,7 +125,7 @@
<string name="screenrecord_continue" msgid="4055347133700593164">"शुरू करें"</string>
<string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रीन को रिकॉर्ड किया जा रहा है"</string>
<string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रीन और ऑडियो, दोनों रिकॉर्ड हो रहे हैं"</string>
- <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रीन को कहां-कहां छुआ गया, यह दिखाएं"</string>
+ <string name="screenrecord_taps_label" msgid="1595690528298857649">"दिखाएं कि स्क्रीन पर कहां-कहां टच किया जा रहा है"</string>
<string name="screenrecord_stop_label" msgid="72699670052087989">"रोकें"</string>
<string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
<string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रिकॉर्डिंग सेव की गई"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"कान की मशीनें"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ब्लूटूथ चालू हो रहा है…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"स्क्रीन की रोशनी को एडजस्ट नहीं किया जा सकता, क्योंकि\n इसे टॉप ऐप्लिकेशन कंट्रोल कर रहा है"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रीन का अपने-आप दिशा बदलना (ऑटो-रोटेट)"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"जगह की जानकारी"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चुना गया"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव कैप्शन"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"क्या आपको माइक्रोफ़ोन का ऐक्सेस अनब्लॉक करना है?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"क्या आपको कैमरे का ऐक्सेस अनब्लॉक करना है?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"क्या आप डिवाइस का कैमरा और माइक्रोफ़ोन अनब्लॉक करना चाहते हैं?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"बंद है"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"सेट नहीं है"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"सेटिंग में जाकर मैनेज करें"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{कोई मोड चालू नहीं है}=1{{mode} चालू है}one{# मोड चालू है}other{# मोड चालू हैं}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{कोई मोड चालू नहीं है}=1{{mode} मोड चालू है}one{# मोड चालू है}other{# मोड चालू हैं}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"आपको अलार्म, रिमाइंडर, इवेंट और चुनिंदा कॉल करने वालों के अलावा किसी और तरह से (आवाज़ करके और थरथरा कर ) परेशान नहीं किया जाएगा. आप फिर भी संगीत, वीडियो और गेम सहित अपना चुना हुआ सब कुछ सुन सकते हैं."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"आपको अलार्म छोड़कर दूसरी आवाज़ों और कंपनों से परेशान नहीं किया जाएगा. आपको अब भी संगीत, वीडियो और गेम सहित वह सब कुछ सुनाई देगा जो आपने चलाने के लिए चुना है."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"अपनी पसंद के मुताबिक बनाएं"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"कोई नई सूचना नहीं है"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"लगातार सूचनाएं आने पर आवाज़ कम करने की सेटिंग चालू है"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"एक साथ कई सूचनाएं मिलने पर, डिवाइस में सूचनाओं से होने वाली आवाज़ और सूचनाएं, दो मिनट के लिए अपने-आप कम हो जाएंगी."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करें"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुरानी सूचाएं देखने के लिए अनलॉक करें"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन पर, दाईं ओर या नीचे के ऐप पर स्विच करने के लिए"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन पर, बाईं ओर या ऊपर के ऐप पर स्विच करने के लिए"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीन के दौरान: एक ऐप्लिकेशन को दूसरे ऐप्लिकेशन से बदलें"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ऐक्टिव विंडो को एक से दूसरे डिसप्ले पर स्विच करें"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"अगली भाषा पर स्विच करने के लिए"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"पिछली भाषा पर स्विच करने के लिए"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वर्ण से कम इस्तेमाल करें"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"बातचीत वाला विजेट"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"किसी बातचीत को होम स्क्रीन पर जोड़ने के लिए, उस बातचीत पर टैप करें"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"बेहतर रिज़ॉल्यूशन वाली फ़ोटो खींचने के लिए, फ़ोन को फ़्लिप करें"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"डिवाइस फ़ोल्ड किया गया"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"डिवाइस अनफ़ोल्ड किया गया"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,55 +1418,48 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट को पसंद के मुताबिक बनाएं"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"शॉर्टकट असाइन करने के लिए बटन दबाएं"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शॉर्टकट खोजें"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"खोज का कोई नतीजा नहीं मिला"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"छोटा करने का आइकॉन"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ऐक्शन या मेटा बटन का आइकॉन"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"प्लस का आइकॉन"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"पसंद के मुताबिक बनाएं"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"हो गया"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"बड़ा करने का आइकॉन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"या"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"खींचकर छोड़ने वाला हैंडल"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करें"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करें"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"बटन दबाएं"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"बटन का यह कॉम्बिनेशन पहले से इस्तेमाल किया जा रहा है. कोई दूसरा कॉम्बिनेशन आज़माएं."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"कीबोर्ड का इस्तेमाल करके नेविगेट करें"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट के बारे में जानें"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचपैड का इस्तेमाल करके नेविगेट करें"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"टचपैड से जुड़े जेस्चर के बारे में जानें"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"कीबोर्ड और टचपैड का इस्तेमाल करके नेविगेट करें"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"टचपैड पर हाथ के जेस्चर, कीबोर्ड शॉर्टकट वगैरह के बारे में जानें"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"टचपैड से जुड़े जेस्चर, कीबोर्ड शॉर्टकट वगैरह के बारे में जानें"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"वापस जाएं"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"होम स्क्रीन पर जाएं"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"हो गया"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"वापस जाएं"</string>
- <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"अपने टचपैड पर तीन उंगलियों का इस्तेमाल करके, बाईं या दाईं ओर स्वाइप करें"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"अपने टचपैड पर तीन उंगलियों से बाईं या दाईं ओर स्वाइप करें"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"बढ़िया!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"अब आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके, पिछली स्क्रीन पर वापस कैसे जाएं."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, पिछली स्क्रीन पर वापस जाने का तरीका पता चल गया है."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"होम स्क्रीन पर जाएं"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"बहुत बढ़िया!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"अब आपको हाथ के जेस्चर का इस्तेमाल करके होम स्क्रीन पर जाने का तरीका पता चल गया है"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखें"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और फिर होल्ड करें"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और दबाकर रखें"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"बहुत बढ़िया!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"आपने हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने के लिए, हाथ के जेस्चर के बारे में जान लिया है."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने का तरीका पता चल गया है."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"सभी ऐप्लिकेशन देखें"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"अपने कीबोर्ड पर ऐक्शन बटन दबाएं"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"बहुत खूब!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"अब आपको इस बारे में जानकारी है कि सभी ऐप्लिकेशन देखने के लिए, हाथ के जेस्चर का इस्तेमाल कैसे किया जाता है"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, सभी ऐप्लिकेशन देखने का तरीका पता चल गया है"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index 6aa90789c246..69a4e4daa355 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"बंद हैं"</item>
<item msgid="3028994095749238254">"चालू हैं"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"उपलब्ध नहीं है"</item>
+ <item msgid="6419996398343291862">"बंद है"</item>
+ <item msgid="5908720590832378783">"चालू है"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 3a01d94ef510..a179649922d2 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Unos"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušna pomagala"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Uključivanje…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Svjetlina se ne može prilagoditi jer njome\n upravlja aplikacija pri vrhu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko zakretanje"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko zakretanje zaslona"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili novi uređaj"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unaprijed definirana postavka"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Napomena"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati kameru uređaja?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite li deblokirati kameru i mikrofon uređaja?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak na aplikaciju zdesna ili ispod uz podijeljeni zaslon"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prelazak na aplikaciju slijeva ili iznad uz podijeljeni zaslon"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Tijekom podijeljenog zaslona: zamijeni aplikaciju drugom"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premještanje aktivnog prozora između zaslona"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Prelazak na sljedeći jezik"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prelazak na prethodni jezik"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Upotrijebite manje od ovoliko znakova: <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgeti razgovora"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da biste ga dodali na početni zaslon"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu razlučivost okrenite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zatvoreno"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"otvoreno"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipku da biste dodijelili prečac"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke za radnju odnosno meta tipka"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona plusa"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za povlačenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tipkovnice"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavite prečac"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Odustani"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tipki već se upotrebljava. Pokušajte s drugom tipkom."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tipkovnice"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tipkovnim prečacima"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string>
@@ -1451,25 +1447,25 @@
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prijeđite ulijevo ili udesno trima prstima na dodirnoj podlozi"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Odlično!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Izvršili ste pokret za povratak."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Napravili ste pokret za povratak."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Na početnu stranicu"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prijeđite prema gore trima prstima na dodirnoj podlozi"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Sjajno!"</string>
- <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Izvršili ste pokret za otvaranje početnog zaslona"</string>
+ <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Napravili ste pokret za otvaranje početnog zaslona"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Pregled nedavnih aplikacija"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Prijeđite prema gore trima prstima na dodirnoj podlozi i zadržite pritisak"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Sjajno!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Izvršili ste pokret za prikaz nedavno korištenih aplikacija."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Napravili ste pokret za prikaz nedavno korištenih aplikacija."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Prikaži sve aplikacije"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku za radnju na tipkovnici"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Izvrsno!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvršili ste pokret za prikaz svih aplikacija"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Napravili ste pokret za prikaz svih aplikacija"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
<string name="home_controls_dream_description" msgid="4644150952104035789">"Brzo upravljajte uređajima putem čuvara zaslona"</string>
<string name="volume_undo_action" msgid="5815519725211877114">"Poništi"</string>
- <string name="back_edu_toast_content" msgid="4530314597378982956">"Za povratak prijeđite ulijevo ili udesno trima prstima na dodirnoj podlozi"</string>
+ <string name="back_edu_toast_content" msgid="4530314597378982956">"Za povratak trima prstima prijeđite ulijevo ili udesno na dodirnoj podlozi"</string>
<string name="home_edu_toast_content" msgid="3381071147871955415">"Da biste se vratili na početni zaslon, prijeđite prema gore trima prstima na dodirnoj podlozi."</string>
<string name="overview_edu_toast_content" msgid="5797030644017804518">"Za prikaz nedavnih aplikacija prijeđite prema gore trima prstima i zadržite pritisak na dodirnoj podlozi"</string>
<string name="all_apps_edu_toast_content" msgid="8807496014667211562">"Za prikaz svojih svih aplikacija pritisnite tipku za radnju na tipkovnici"</string>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index 3f8841afb4f2..2401e4a2fc37 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Isključeno"</item>
<item msgid="3028994095749238254">"Uključeno"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nedostupno"</item>
+ <item msgid="6419996398343291862">"Isključeno"</item>
+ <item msgid="5908720590832378783">"Uključeno"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c9e20f8359be..4b5b9162b01b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Bevitel"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hallókészülék"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Bekapcsolás…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nem lehet módosítani a fényerőt, mert a felső alkalmazás\n vezérli"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatikus elforgatás"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatikus képernyőforgatás"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Tartózkodási hely"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Beállításkészlet"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Kiválasztva"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eszközök"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Élő feliratozás"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Megjegyzés"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Feloldja az eszköz kamerájának és mikrofonjának letiltását?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Ki"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Nincs beállítva"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"A Beállítások között kezelheti"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nincs aktív mód}=1{A(z) {mode} aktív}other{# mód aktív}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nincs aktív mód}=1{{mode} aktív}other{# mód aktív}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Az Ön által meghatározott ébresztéseken, emlékeztetőkön, eseményeken és hívókon kívül nem fogja Önt más hang vagy rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Az ébresztéseken kívül nem fogja Önt más hang és rezgés megzavarni. Továbbra is lesz hangjuk azoknak a tartalmaknak, amelyeket Ön elindít, például zenék, videók és játékok."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Személyre szabás"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nincsenek új értesítések"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Az értesítések befagyasztása mostantól be van kapcsolva"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Az eszköz hangerejét és értesítéseit a rendszer automatikusan legfeljebb két percig csökkenti, ha egyszerre túl sok értesítést kap."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Igen"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"A régebbiek feloldás után láthatók"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Váltás a jobb oldalt, illetve lent lévő appra osztott képernyő esetén"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Váltás a bal oldalt, illetve fent lévő appra osztott képernyő esetén"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Osztott képernyőn: az egyik alkalmazás lecserélése egy másikra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktív ablak áthelyezése egyik kijelzőről a másikra"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Bevitel"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Váltás a következő nyelvre"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Váltás az előző nyelvre"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Legfeljebb <xliff:g id="LENGTH">%1$d</xliff:g> karaktert használhat"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Beszélgetési modulok"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Koppintson a kívánt beszélgetésre a kezdőképernyőre való felvételhez"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"A nagyobb felbontás érdekében fordítsa meg a telefont"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"összehajtva"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kihajtva"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"A billentyűparancsok személyre szabása"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nyomja meg a billentyűt a parancsikon hozzárendeléséhez"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Billentyűparancsok keresése"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nincsenek keresési találatok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Összecsukás ikon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Művelet vagy Meta billentyű ikonja"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluszikon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Személyre szabás"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Kész"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kibontás ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vagy"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Fogópont"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Billentyűzetbeállítások"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Billentyűparancs beállítása"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Mégse"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nyomja le a billentyűt"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"A billentyűkombináció már használatban van. Próbálkozzon másik kulccsal."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigáció a billentyűzet segítségével"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Billentyűparancsok megismerése"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigálás az érintőpaddal"</string>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 76b3410ab6cb..8911fe9e2f8d 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Ki"</item>
<item msgid="3028994095749238254">"Be"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nem áll rendelkezésre"</item>
+ <item msgid="6419996398343291862">"Ki"</item>
+ <item msgid="5908720590832378783">"Be"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1d46bc2c86da..a06209867663 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -116,7 +116,7 @@
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Երբ դուք տեսագրում եք ամբողջ էկրանը, էկրանին ցուցադրվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Երբ դուք որևէ հավելված եք տեսագրում, հավելվածում ցուցադրվող կամ նվագարկվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Տեսագրել էկրանը"</string>
- <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Հավելվածի ընտրություն՝ տեսագրելու համար"</string>
+ <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Հավելված ընտրեք՝ տեսագրելու համար"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Ձայնագրել"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Սարքի ձայները"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Ձեր սարքի ձայները, օրինակ՝ երաժշտությունը, զանգերն ու զանգերանգները"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Մուտքագրում"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Լսողական սարք"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Միացում…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Հնարավոր չէ կարգավորել պայծառությունը, քանի որ այն\n կառավարվում է գլխավոր հավելվածի կողմից"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ինքնապտտում"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ավտոմատ պտտել էկրանը"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Տեղորոշում"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Սեղմեք՝ նոր սարք զուգակցելու համար"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Չհաջողվեց թարմացնել կարգավորումների հավաքածուն"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Կարգավորումների հավաքածու"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ընտրված է"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Գործիքներ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Կենդանի ենթագրեր"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Նշում"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Արգելահանե՞լ սարքի խոսափողը"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Արգելահանե՞լ սարքի տեսախցիկը"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Արգելահանե՞լ սարքի տեսախցիկը և խոսափողը"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Անջատված է"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Կարգավորված չէ"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Կառավարել կարգավորումներում"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Ակտիվ ռեժիմներ չկան}=1{{mode} ռեժիմ ակտիվ է}one{# ռեժիմ ակտիվ է}other{# ռեժիմ ակտիվ է}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Ակտիվ ռեժիմ չկա}=1{{mode} ռեժիմն ակտիվ է}one{# ռեժիմ ակտիվ է}other{# ռեժիմ ակտիվ է}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Ձայները և թրթռոցները չեն անհանգստացնի ձեզ, բացի ձեր կողմից նշված զարթուցիչները, հիշեցումները, միջոցառումների ծանուցումները և զանգերը։ Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Ձայները և թրթռոցները, բացի զարթուցիչներից, չեն անհանգստացնի ձեզ: Դուք կլսեք ձեր ընտրածի նվագարկումը, այդ թվում՝ երաժշտություն, տեսանյութեր և խաղեր:"</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Հարմարեցնել"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Անցեք աջ կողմի կամ ներքևի հավելվածին տրոհված էկրանի միջոցով"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Անցեք աջ կողմի կամ վերևի հավելվածին տրոհված էկրանի միջոցով"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Տրոհված էկրանի ռեժիմում մեկ հավելվածը փոխարինել մյուսով"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Տեղափոխել ակտիվ պատուհանը էկրանների միջև"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ներածում"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Անցնել հաջորդ լեզվին"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Անցնել նախորդ լեզվին"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Օգտագործեք մինչև <xliff:g id="LENGTH">%1$d</xliff:g> նիշ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Զրույցի վիջեթներ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Հպեք զրույցին՝ այն հիմնական էկրանին ավելացնելու համար"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ավելի մեծ լուծաչափի համար շրջեք հեռախոսը"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ծալված"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"բացված"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Կարգավորեք ստեղնային դյուրանցումներ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Սեղմեք որևէ ստեղն՝ դյուրանցում նշանակելու համար"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Դյուրանցումների որոնում"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Որոնման արդյունքներ չկան"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ծալել պատկերակը"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Գործողության կամ Meta ստեղնի պատկերակ"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Պլյուս պատկերակ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Կարգավորել"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Պատրաստ է"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ծավալել պատկերակը"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"կամ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Տեղափոխման նշիչ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ստեղնաշարի կարգավորումներ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ստեղծել դյուրանցում"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Չեղարկել"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Սեղմեք որևէ ստեղն"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ստեղների համակցությունն արդեն օգտագործվում է։ Ընտրեք այլ ստեղն։"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Կողմնորոշվեք ձեր ստեղնաշարի օգնությամբ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Սովորեք օգտագործել ստեղնային դյուրանցումները"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Կողմնորոշվեք ձեր հպահարթակի օգնությամբ"</string>
@@ -1458,7 +1454,7 @@
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Դիտել վերջին հավելվածները"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Երեք մատով սահեցրեք վերև և սեղմած պահեք հպահարթակին"</string>
- <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Կեցցե՛ք։"</string>
+ <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Կեցցե՛ք"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Դուք կատարեցիք վերջին օգտագործված հավելվածների դիտման ժեստը։"</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Ինչպես դիտել բոլոր հավելվածները"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index ce930c39aa83..f2b09e059429 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Անջատված է"</item>
<item msgid="3028994095749238254">"Միացված է"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Հասանելի չէ"</item>
+ <item msgid="6419996398343291862">"Անջատված է"</item>
+ <item msgid="5908720590832378783">"Միացված է"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 1535314317a8..cf9b093a1d43 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Alat bantu dengar"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Mengaktifkan…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Tidak dapat menyesuaikan kecerahan karena sedang\n dikontrol oleh aplikasi atas"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Putar Otomatis"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Putar layar otomatis"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menyambungkan perangkat baru"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat memperbarui preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alat"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Teks Otomatis"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Catatan"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Berhenti memblokir mikrofon perangkat?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Berhenti memblokir kamera perangkat?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Berhenti memblokir kamera dan mikrofon perangkat?"</string>
@@ -565,7 +565,7 @@
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmisikan seluruh layar"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"JIka Anda mentransmisikan seluruh layar, semua hal yang ada di layar Anda akan terlihat. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
<string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Jika Anda mentransmisikan aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan terlihat. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
- <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Layar Cast"</string>
+ <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmisikan layar"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Pilih aplikasi yang akan ditransmisikan"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Mulai berbagi?"</string>
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Jika Anda membagikan, merekam, atau mentransmisikan, Android akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Tidak ada notifikasi baru"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Pengurangan suara dan getaran notifikasi kini aktif"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Saat Anda menerima terlalu banyak notifikasi sekaligus, volume dan getaran perangkat akan otomatis dikurangi hingga selama 2 menit."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Nonaktifkan"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat notifikasi lama"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Beralih ke aplikasi di bagian kanan atau bawah saat menggunakan layar terpisah"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Beralih ke aplikasi di bagian kiri atau atas saat menggunakan layar terpisah"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Dalam layar terpisah: ganti salah satu aplikasi dengan yang lain"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Memindahkan jendela aktif dari satu layar ke layar lainnya"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih ke bahasa berikutnya"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Beralih ke bahasa sebelumnya"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gunakan kurang dari <xliff:g id="LENGTH">%1$d</xliff:g> karakter"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widget Percakapan"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Ketuk percakapan untuk menambahkannya ke Layar utama"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk resolusi lebih tinggi, balik ponsel"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ditutup"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"dibuka"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,30 +1418,23 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Menyesuaikan pintasan keyboard"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tekan tombol untuk menetapkan pintasan"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Telusuri pintasan"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tidak ada hasil penelusuran"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon ciutkan"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon tombol Tindakan atau Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikon plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon luaskan"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handel geser"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Setelan Keyboard"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
- <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menavigasi menggunakan keyboard"</string>
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setel pintasan"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan tombol"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinasi tombol sudah digunakan. Coba tombol lain."</string>
+ <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menggunakan keyboard untuk navigasi"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Pelajari pintasan keyboard"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Menavigasi menggunakan touchpad"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Pelajari gestur touchpad"</string>
@@ -1451,8 +1446,8 @@
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Geser ke kiri atau kanan menggunakan tiga jari di touchpad"</string>
- <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bagus!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah menyelesaikan gestur kembali."</string>
+ <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sip!"</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah menyelesaikan gestur untuk kembali."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Buka layar utama"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Geser ke atas dengan tiga jari di touchpad"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bagus!"</string>
@@ -1463,7 +1458,7 @@
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah menyelesaikan gestur untuk melihat aplikasi terbaru."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua aplikasi"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan tombol tindakan di keyboard"</string>
- <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bagus!"</string>
+ <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Oke!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah menyelesaikan gestur untuk melihat semua aplikasi"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 5570edb557d4..7462ff6a98bd 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Nonaktif"</item>
<item msgid="3028994095749238254">"Aktif"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Tidak tersedia"</item>
+ <item msgid="6419996398343291862">"Nonaktif"</item>
+ <item msgid="5908720590832378783">"Aktif"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index edead8fdc433..fe32aba3d75b 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -113,10 +113,10 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Taka upp eitt forrit"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Taka upp allan skjáinn"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Taka upp allan skjáinn: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Taka upp skjá"</string>
- <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Velja forrit til að taka upp"</string>
+ <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Veldu forrit til að taka upp"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Taka upp hljóð"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Hljóð tækis"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Hljóð úr tækinu á borð við tónlist, símtöl og hringitóna"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Inntak"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Heyrnartæki"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Kveikir…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ekki er hægt að breyta birtustiginu vegna þess að \n efsta forritið stjórnar því"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Sjálfvirkur snúningur"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Snúa skjá sjálfkrafa"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Staðsetning"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forstilling"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valið"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verkfæri"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Skjátextar í rauntíma"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Glósa"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Opna fyrir myndavél og hljóðnema tækisins?"</string>
@@ -555,8 +555,8 @@
<string name="screen_share_permission_dialog_option_entire_screen" msgid="4493174362775038997">"Deila öllum skjánum"</string>
<!-- no translation found for media_projection_entry_app_permission_dialog_option_text_entire_screen (5100078808078139706) -->
<skip />
- <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Þegar þú deilir öllum skjánum verður allt á skjánum sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
- <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Þegar þú deilir forriti er allt sem sést eða er spilað í því forriti sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Þegar þú deilir öllum skjánum verður allt á skjánum sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Þegar þú deilir forriti er allt sem sést eða er spilað í því forriti sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deila skjá"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> slökkti á þessum valkosti"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Velja forrit til að deila"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skiptu í forrit til hægri eða fyrir neðan þegar skjáskipting er notuð"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skiptu í forrit til vinstri eða fyrir ofan þegar skjáskipting er notuð"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Færa virkan glugga á milli skjáa"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Innsláttur"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Skipta yfir í næsta tungumál"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Skipta yfir í fyrra tungumál"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Notaðu færri en <xliff:g id="LENGTH">%1$d</xliff:g> stafi"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Samtalsgræjur"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Ýttu á samtal til að bæta því á heimaskjáinn"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Snúðu símanum til að fá betri upplausn"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"samanbrotið"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opið"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Ýttu á lykil til að stilla flýtileið"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leita að flýtileiðum"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Tákn lýsilykils (aðgerðarlykils)"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plústákn"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sérsníða"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Lokið"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Stækka tákn"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eða"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dragkló"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Stillingar lyklaborðs"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stilltu flýtileið"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Hætta við"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Ýttu á lykil"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Lyklasamsetning er þegar í notkun. Prófaðu annan lykil."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Flettu með því að nota lyklaborðið"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Kynntu þér flýtilykla"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Flettu með því að nota snertiflötinn"</string>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 893ab6ce3bb6..df3bcf9f1f9b 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Slökkt"</item>
<item msgid="3028994095749238254">"Kveikt"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Ekki í boði"</item>
+ <item msgid="6419996398343291862">"Slökkt"</item>
+ <item msgid="5908720590832378783">"Kveikt"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index d7a279be03ea..a66ea91eb396 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ingresso"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Apparecchi acustici"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Attivazione…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Impossibile regolare la luminosità perché è\n controllata dall\'app in primo piano"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotazione automatica"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Posizione"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic per accoppiare un nuovo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossibile aggiornare preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selezionato"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Strumenti"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sottotitoli in tempo reale"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vuoi sbloccare il microfono del dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vuoi sbloccare la fotocamera del dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vuoi sbloccare la fotocamera e il microfono del dispositivo?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nessuna nuova notifica"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"L\'attenuazione delle notifiche è ora attiva"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e avvisi vengono ridotti automaticamente per un massimo di 2 minuti quando ricevi troppe notifiche contemporaneamente."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Disattiva"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Sblocca per vedere le notifiche meno recenti"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passa all\'app a destra o sotto mentre usi lo schermo diviso"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passa all\'app a sinistra o sopra mentre usi lo schermo diviso"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Sposta la finestra attiva tra gli schermi"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inserimento"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Passa alla lingua successiva"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passa alla lingua precedente"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Usa meno di <xliff:g id="LENGTH">%1$d</xliff:g> caratteri"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widget di conversazione"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tocca una conversazione per aggiungerla alla schermata Home"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Gira il telefono per una maggiore risoluzione"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"Piegato"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"Non piegato"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Premi un tasto per assegnare una scorciatoia"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icona tasto Azione o Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icona Più"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizza"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Fine"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona Espandi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oppure"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Punto di trascinamento"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Impostazioni tastiera"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Imposta scorciatoia"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annulla"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Premi un tasto"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinazione di tasti già in uso. Prova con un altro tasto."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviga usando la tastiera"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informazioni sulle scorciatoie da tastiera"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviga usando il touchpad"</string>
@@ -1455,11 +1450,11 @@
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Hai completato il gesto Indietro."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Vai alla schermata Home"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Scorri in alto con tre dita sul touchpad"</string>
- <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ottimo lavoro."</string>
+ <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ottimo lavoro!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Hai completato il gesto Vai alla schermata Home"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Visualizza app recenti"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Scorri verso l\'alto e tieni premuto con tre dita sul touchpad"</string>
- <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ottimo lavoro."</string>
+ <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ottimo lavoro!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Hai completato il gesto Visualizza app recenti."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Visualizza tutte le app"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Premi il tasto azione sulla tastiera"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 784a3091ef19..9d26859df5ed 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Disattivi"</item>
<item msgid="3028994095749238254">"Attivi"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Non disponibile"</item>
+ <item msgid="6419996398343291862">"Off"</item>
+ <item msgid="5908720590832378783">"On"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9064d3dac5cd..7b4245ee1c1e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"קלט"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"מכשירי שמיעה"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ההפעלה מתבצעת…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"לא ניתן להתאים את הבהירות כי היא\n נשלטת על ידי האפליקציה העליונה"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"סיבוב אוטומטי"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"סיבוב אוטומטי של המסך"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"מיקום"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"צריך ללחוץ כדי להתאים מכשיר חדש"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"לא ניתן לעדכן את ההגדרה הקבועה מראש"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"הגדרה קבועה מראש"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"נבחר"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"כלים"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"כתוביות מיידיות"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"פתק"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"לבטל את חסימת המיקרופון של המכשיר?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"לבטל את חסימת המצלמה של המכשיר?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"לבטל את חסימת המצלמה והמיקרופון של המכשיר?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"אין התראות חדשות"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"הפוגת ההתראות מופעלת"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"עוצמת הקול וההתראות במכשיר מופחתות אוטומטית למשך עד 2 דקות כשמתקבלות יותר מדי התראות בבת אחת."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"השבתה"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"יש לבטל את הנעילה כדי לראות התראות ישנות"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"מעבר לאפליקציה משמאל או למטה בזמן שימוש במסך מפוצל"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"מעבר לאפליקציה מימין או למעלה בזמן שימוש במסך מפוצל"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"העברת החלון הפעיל בין מסכים"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"קלט"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"מעבר לשפה הבאה"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"מעבר לשפה הקודמת"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"אפשר להזין עד <xliff:g id="LENGTH">%1$d</xliff:g> תווים"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ווידג\'טים של שיחות"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"יש להקיש על שיחה כדי להוסיף אותה למסך הבית"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"כדי לצלם תמונה ברזולוציה גבוהה יותר, כדאי להפוך את הטלפון"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"מצב מקופל"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"מצב לא מקופל"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"‏%1$s‏ / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"התאמה אישית של מקשי הקיצור"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"יש ללחוץ על מקש כדי להקצות מקש קיצור"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"אין תוצאות חיפוש"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"סמל מקש הפעולה (\"מטא\")"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"סמל הפלוס"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"התאמה אישית"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"סיום"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"סמל ההרחבה"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"או"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"נקודת האחיזה לגרירה"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"הגדרות המקלדת"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"הגדרה של מקש קיצור"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ביטול"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"יש ללחוץ על מקש"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"שילוב המקשים הזה כבר בשימוש. אפשר לנסות מקש אחר."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ניווט באמצעות המקלדת"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"מידע על מקשי קיצור"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ניווט באמצעות לוח המגע"</string>
@@ -1452,19 +1447,19 @@
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"מחליקים שמאלה או ימינה עם שלוש אצבעות על לוח המגע"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"איזה יופי!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"השלמת את התנועה \'הקודם\'."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"סיימת לתרגל את התנועה \'הקודם\'."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"מעבר למסך הבית"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"מחליקים כלפי מעלה עם שלוש אצבעות על לוח המגע"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"מעולה!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"סיימת לתרגל את תנועת החזרה למסך הבית"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"הצגת האפליקציות האחרונות"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות על לוח המגע"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"מחליקים למעלה עם שלוש אצבעות על לוח המגע ומשאירים אותן במגע עם הלוח"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"מעולה!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"השלמת את התנועה להצגת האפליקציות האחרונות."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"סיימת לתרגל את התנועה להצגת האפליקציות האחרונות."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"צפייה בכל האפליקציות"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"צריך להקיש על מקש הפעולה במקלדת"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"כל הכבוד!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"השלמת את התנועה להצגת כל האפליקציות"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"סיימת לתרגל את התנועה להצגת כל האפליקציות"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"‏רמה %1$d מתוך %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index e2ba375763c2..d6b9bc8950af 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"מצב מושבת"</item>
<item msgid="3028994095749238254">"מצב פעיל"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"לא זמין"</item>
+ <item msgid="6419996398343291862">"מושבת"</item>
+ <item msgid="5908720590832378783">"מופעל"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a23dac840796..c4fd62b355f6 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"入力"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"補聴器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ON にしています…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"明るさはトップ アプリによって\n制御されているため、調整できません"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動回転"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"画面を自動回転します"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"位置情報"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"クリックすると、新しいデバイスをペア設定できます"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"プリセットを更新できませんでした"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"プリセット"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"選択中"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ツール"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"自動字幕起こし"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"注"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"デバイスのマイクのブロックを解除しますか?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"デバイスのカメラのブロックを解除しますか?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"デバイスのカメラとマイクのブロックを解除しますか?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"分割画面の使用時に右側または下部のアプリに切り替える"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"分割画面の使用時に左側または上部のアプリに切り替える"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"分割画面中: アプリを順に置換する"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"アクティブなウィンドウをディスプレイ間で移動する"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"入力"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"次の言語に切り替える"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"前の言語に切り替える"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"使用できる文字数は <xliff:g id="LENGTH">%1$d</xliff:g> 文字未満です"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"会話ウィジェット"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"会話をタップするとホーム画面に追加されます"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"高解像度で撮るにはスマートフォンを裏返してください"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折りたたんだ状態"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"広げた状態"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットをカスタマイズする"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ショートカットを割り当てるキーを押してください"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"アクションキーまたはメタキーのアイコン"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"プラスアイコン"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"カスタマイズ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完了"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ドラッグ ハンドル"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"キーボードの設定"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ショートカットの設定"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"キャンセル"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"キーを押してください"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"このキーの組み合わせはすでに使用されています。別のキーを試してください。"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"キーボードを使用して移動する"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"キーボード ショートカットの詳細"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"タッチパッドを使用して移動する"</string>
@@ -1449,21 +1445,21 @@
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"最近使ったアプリを表示する"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完了"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"戻る"</string>
- <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"タッチパッドを 3 本の指で左右にスワイプします"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"タッチパッドを 3 本の指で左または右にスワイプします"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"その調子です!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"「戻る」操作を学習しました。"</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"「戻る」ジェスチャーを学習しました。"</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ホームに移動"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"タッチパッドを 3 本の指で上にスワイプします"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"よくできました!"</string>
- <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"「ホームに移動」操作を学習しました"</string>
+ <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"「ホームに移動」ジェスチャーを学習しました"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"最近使ったアプリを表示する"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"タッチパッドを 3 本の指で上にスワイプして長押しします"</string>
- <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"よくできました"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"「最近使ったアプリを表示する」操作を学習しました。"</string>
+ <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"よくできました!"</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"「最近使ったアプリを表示する」ジェスチャーを学習しました。"</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"すべてのアプリを表示"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"キーボードのアクションキーを押します"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"完了です!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"「すべてのアプリを表示する」操作を学習しました"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"「すべてのアプリを表示する」ジェスチャーを学習しました"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index 683a4e889fbb..81c10e7d0ab8 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"OFF"</item>
<item msgid="3028994095749238254">"ON"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"使用不可"</item>
+ <item msgid="6419996398343291862">"OFF"</item>
+ <item msgid="5908720590832378783">"ON"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index d0ff84296f3e..7cb3c8a99303 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"შეყვანა"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"სმენის მოწყობილობები"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ირთვება…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"სიკაშკაშის კორექტირება ვერ ხერხდება, რადგან ის\n იმართება გახსნილი აპის მიერ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ავტოროტაცია"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ეკრანის ავტომატური შეტრიალება"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"მდებარეობა"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"დააწკაპუნეთ ახალი მოწყობილობის დასაწყვილებლად"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"წინასწარ დაყენებული პარამეტრების განახლება ვერ მოხერხდა"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"წინასწარ დაყენებული"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"არჩეულია"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ხელსაწყოები"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ავტოსუბტიტრები"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ჩანიშვნა"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"გსურთ მოწყობილობის მიკროფონის განბლოკვა?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"გსურთ მოწყობილობის კამერის განბლოკვა?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"გსურთ მოწყობილობის კამერის და მიკროფონის განბლოკვა?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ეკრანის გაყოფის გამოყენებისას აპზე მარჯვნივ ან ქვემოთ გადართვა"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ეკრანის გაყოფის გამოყენებისას აპზე მარცხნივ ან ზემოთ გადართვა"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"აქტიური ფანჯრის გადატანა ეკრანებს შორის"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"შეყვანა"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"შემდეგ ენაზე გადართვა"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"წინა ენაზე გადართვა"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"გამოიყენეთ <xliff:g id="LENGTH">%1$d</xliff:g>-ზე ნაკლები სიმბოლო"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"საუბრის ვიჯეტები"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"შეეხეთ საუბარს მის თქვენს მთავარ ეკრანზე დასამატებლად"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"მაღალი გარჩევადობისთვის ამოაბრუნეთ ტელეფონი"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"დაკეცილი"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"გაშლილი"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"მალსახმობის მინიჭებისთვის დააჭირეთ კლავიშს"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"მოქმედების ან მეტა კლავიშის ხატულა"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"პლუსის ხატულა"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"მორგება"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"მზადაა"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ხატულის გაფართოება"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ან"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"სახელური ჩავლებისთვის"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"კლავიატურის პარამეტრები"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"მალსახმობის დაყენება"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"გაუქმება"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"დააჭირეთ კლავიშს"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"კლავიშების კომბინაცია უკვე გამოიყენება. ცადეთ სხვა კლავიში."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ნავიგაცია კლავიატურის გამოყენებით"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"კლავიატურის მალსახმობების სწავლა"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ნავიგაცია სენსორული პანელის გამოყენებით"</string>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 7c13eb53d5d8..6e62ed4ee74a 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"გამორთულია"</item>
<item msgid="3028994095749238254">"ჩართულია"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"მიუწვდომელია"</item>
+ <item msgid="6419996398343291862">"გამორთული"</item>
+ <item msgid="5908720590832378783">"ჩართული"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 94f8711cc7a0..4122eeef9d59 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Кіріс"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Есту аппараттары"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Қосылып жатыр…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Жарықтықты реттеу мүмкін емес, себебі ол\n жетекші қолданба арқылы басқарылады."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматты түрде бұру"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматты айналатын экран"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Локация"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңа құрылғыны жұптау үшін басыңыз."</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Параметрлер жинағын жаңарту мүмкін болмады."</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Параметрлер жинағы"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Таңдалды"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Құралдар"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ескертпе"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Құрылғы микрофонын блоктан шығару керек пе?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Құрылғы камерасын блоктан шығару керек пе?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Құрылғы камерасы мен микрофонын блоктан шығару керек пе?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңа хабарландырулар жоқ"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Хабарландыру дыбысын азайту параметрі енді қосулы"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Бір уақытта тым көп хабарландыру келсе, дыбыс деңгейі автоматты түрде азайтылып, хабарландырулар 2 минутқа кідіртіледі."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өшіру"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ескі хабарландырулар үшін құлыпты ашыңыз"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлінген экранда оң не төмен жақтағы қолданбаға ауысу"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлінген экранда сол не жоғары жақтағы қолданбаға ауысу"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлу кезінде: бір қолданбаны басқасымен алмастыру"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Дисплейлер арасында қосулы терезені ауыстыру"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Енгізу"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Келесі тілге ауысу"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Алдыңғы тілге ауысу"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Ең көбі <xliff:g id="LENGTH">%1$d</xliff:g> таңба пайдаланыңыз."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Әңгіме виджеттері"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Негізгі экранға қосқыңыз келетін әңгімені түртіңіз."</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жоғары ажыратымдылық үшін телефонды айналдырыңыз."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"жабық"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ашық"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Жылдам пәрменді тағайындау үшін пернені басыңыз."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Әрекет немесе Meta пернесінің белгішесі"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Қосу белгішесі"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Бейімдеу"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Дайын"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Сүйрейтін тетік"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Пернетақта параметрлері"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Жылдам пәрменді орнату"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Бас тарту"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Пернені басыңыз"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Бұл пернелер тіркесімі қазір қолданыста. Басқа пернені таңдаңыз."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Пернетақтамен жұмыс істеңіз"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Перне тіркесімдерін үйреніңіз."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Сенсорлық тақтамен жұмыс істеңіз"</string>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index 2b4c1ac355a2..66deff6d7135 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Өшірулі"</item>
<item msgid="3028994095749238254">"Қосулы"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Қолжетімді емес"</item>
+ <item msgid="6419996398343291862">"Өшірулі"</item>
+ <item msgid="5908720590832378783">"Қосулы"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2b178181aa3f..f9ec58f2fba8 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"បញ្ចូល"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ឧបករណ៍ជំនួយការស្ដាប់"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"កំពុង​បើក..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"មិនអាចកែតម្រូវកម្រិតពន្លឺបានទេ ដោយសារវាកំពុងស្ថិតក្រោម\nការគ្រប់គ្រងរបស់កម្មវិធីខាងលើគេ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"បង្វិល​ស្វ័យ​ប្រវត្តិ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ទី​តាំង​"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ចុច ដើម្បីផ្គូផ្គងឧបករណ៍ថ្មី"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"មិនអាច​ប្ដូរ​ការកំណត់ជាមុន​បានទេ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"កំណត់ជាមុន"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"បានជ្រើសរើស"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ឧបករណ៍"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"អក្សររត់ក្នុងពេលជាក់ស្ដែង"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"កំណត់ចំណាំ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ឈប់ទប់ស្កាត់​មីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ឈប់ទប់ស្កាត់​កាមេរ៉ា​របស់ឧបករណ៍ឬ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ឈប់ទប់ស្កាត់​កាមេរ៉ា និងមីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ប្ដូរទៅកម្មវិធីនៅខាងស្ដាំ ឬខាងក្រោម ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ប្ដូរទៅកម្មវិធីនៅខាងឆ្វេង ឬខាងលើ ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ក្នុងអំឡុងពេលប្រើមុខងារបំបែកអេក្រង់៖ ជំនួសកម្មវិធីពីមួយទៅមួយទៀត"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ផ្លាស់ទីវិនដូដែលសកម្មរវាងផ្ទាំងអេក្រង់"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"បញ្ចូល"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ប្ដូរទៅភាសាបន្ទាប់"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ប្ដូរទៅភាសាមុន"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ប្រើតិចជាង <xliff:g id="LENGTH">%1$d</xliff:g> តួអក្សរ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ធាតុ​ក្រាហ្វិកនៃការសន្ទនា"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ចុចការសន្ទនា ដើម្បីបញ្ចូលវាទៅក្នុងអេក្រង់ដើមរបស់អ្នក"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"សម្រាប់កម្រិតគុណភាពកាន់តែខ្ពស់ សូមត្រឡប់ទូរសព្ទ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"បត់"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"លា"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់​ក្ដារ​ចុច"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរ​ផ្លូវកាត់​ក្ដារ​ចុចតាម​បំណង"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ចុចគ្រាប់ចុច ដើម្បីកំណត់ផ្លូវ​កាត់"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ស្វែងរកផ្លូវ​កាត់"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មាន​លទ្ធផល​ស្វែងរក​ទេ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"រូបគ្រាប់ចុចសកម្មភាព ឬមេតា"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"រូបសញ្ញាបូក"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ប្ដូរ​តាម​បំណង"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"រួចរាល់"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"រូបតំណាង \"ពង្រីក\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ឬ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ដង​អូស"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ការកំណត់​ក្ដារចុច"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"កំណត់ផ្លូវ​កាត់"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"បោះបង់"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ចុចគ្រាប់ចុច"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"កំពុងប្រើបន្សំគ្រាប់ចុចស្រាប់ហើយ។ សាកល្បងប្រើគ្រាប់ចុចផ្សេង។"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"រុករកដោយប្រើក្ដារចុចរបស់អ្នក"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ស្វែងយល់អំពីផ្លូវកាត់​ក្ដារ​ចុច"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"រុករកដោយប្រើផ្ទាំងប៉ះរបស់អ្នក"</string>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 3c15fd3a35e4..71b12ca8ff62 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"បិទ"</item>
<item msgid="3028994095749238254">"បើក"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"មិនអាចប្រើបាន"</item>
+ <item msgid="6419996398343291862">"បិទ"</item>
+ <item msgid="5908720590832378783">"បើក"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b74a0535bdd4..f3155704c55f 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -270,7 +270,7 @@
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು."</string>
<string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಯ ಪರದೆ."</string>
<string name="accessibility_desc_lock_screen" msgid="409034672704273634">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
- <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಪರದೆ"</string>
+ <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
<string name="accessibility_desc_close" msgid="8293708213442107755">"ಮುಚ್ಚಿ"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"ಅಲಾರಮ್‌ಗಳು ಮಾತ್ರ"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ಇನ್‌ಪುಟ್"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ಆನ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ಬ್ರೈಟ್‌ನೆಸ್ ಅನ್ನು ಅಡ್ಜಸ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ,\n ಏಕೆಂದರೆ ಅದನ್ನು ಟಾಪ್ ಆ್ಯಪ್ ನಿಯಂತ್ರಿಸುತ್ತಿದೆ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ಸ್ವಯಂ-ತಿರುಗುವಿಕೆ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ಸ್ಥಳ"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ಪ್ರಿಸೆಟ್‌"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ಟೂಲ್‌ಗಳು"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ಲೈವ್ ಕ್ಯಾಪ್ಶನ್"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ಟಿಪ್ಪಣಿ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ಸಾಧನದ ಕ್ಯಾಮರಾ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ಸಾಧನದ ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಅನ್‍ಬ್ಲಾಕ್ ಮಾಡಬೇಕೇ?"</string>
@@ -560,8 +560,8 @@
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ಸ್ಕ್ರೀನ್‌ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಈ ಆಯ್ಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ಹಂಚಿಕೊಳ್ಳಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡಬೇಕೆ?"</string>
- <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡಿ"</string>
+ <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕಾಸ್ಟ್ ಮಾಡಬೇಕೆ?"</string>
+ <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ಕಾಸ್ಟ್ ಮಾಡಿ"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡಿ"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ನೀವು ಕ್ಯಾಸ್ಟ್ ಮಾಡುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಏನಾದರೂ ಗೋಚರಿಸುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಿರುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡಿರುವುದು ಗೋಚರಿಸುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
@@ -868,11 +868,10 @@
<string name="system_multitasking_rhs" msgid="8714224917276297810">"ಬಲಭಾಗದಲ್ಲಿ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string>
<string name="system_multitasking_lhs" msgid="8402954791206308783">"ಎಡಭಾಗದಲ್ಲಿ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string>
<string name="system_multitasking_full_screen" msgid="336048080383640562">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್‌ನಿಂದ ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಬದಲಿಸಿ"</string>
- <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
- <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
+ <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
+ <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್‌ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ಸಕ್ರಿಯ ವಿಂಡೋವನ್ನು ಡಿಸ್‌ಪ್ಲೇಗಳ ನಡುವೆ ಸರಿಸಿ"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ಇನ್‌ಪುಟ್"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ಮುಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ಹಿಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> ಕ್ಕಿಂತ ಕಡಿಮೆ ಅಕ್ಷರಗಳನ್ನು ಬಳಸಿ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ಸಂಭಾಷಣೆ ವಿಜೆಟ್‌ಗಳು"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ಸಂಭಾಷಣೆಯನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಸೇರಿಸಲು ಅದನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ಅಧಿಕ ರೆಸಲ್ಯೂಷನ್‌ಗಾಗಿ, ಫೋನ್ ಅನ್ನು ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ಫೋಲ್ಡ್ ಮಾಡಿರುವುದು"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿರುವುದು"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,33 +1418,26 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ಕೀಯನ್ನು ಒತ್ತಿರಿ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ಆ್ಯಕ್ಷನ್ ಅಥವಾ ಮೆಟಾ ಕೀ ಐಕಾನ್"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ಪ್ಲಸ್ ಐಕಾನ್"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ಮುಗಿದಿದೆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ಡ್ರ್ಯಾಗ್‌ ಹ್ಯಾಂಡಲ್‌"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ಕೀಬೋರ್ಡ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ಶಾರ್ಟ್‌ಕಟ್ ಸೆಟ್ ಮಾಡಿ"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ರದ್ದುಮಾಡಿ"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ಕೀ ಅನ್ನು ಒತ್ತಿರಿ"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ಕೀ ಸಂಯೋಜನೆಯು ಈಗಾಗಲೇ ಬಳಕೆಯಲ್ಲಿದೆ. ಮತ್ತೊಂದು ಕೀ ಬಳಸಿ ನೋಡಿ."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
- <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ಟಚ್‌ಪ್ಯಾಡ್ ಗೆಸ್ಚರ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
+ <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ಟಚ್‌ಪ್ಯಾಡ್ ಜೆಸ್ಚರ್‌ಗಳನ್ನು ಕಲಿಯಿರಿ"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಮತ್ತು ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"ಟಚ್‌ಪ್ಯಾಡ್ ಗೆಸ್ಚರ್‌ಗಳು, ಕೀಬೋರ್ಡ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ತಿಳಿಯಿರಿ"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"ಹಿಂದಿರುಗಿ"</string>
@@ -1459,11 +1455,11 @@
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ಭೇಷ್‌!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ನೀವು ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳ ಗೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ನೀವು ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ಭೇಷ್!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳ ಗೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್‌ಲೈಟ್"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 5a188f19a5ac..49c688abff72 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ಆಫ್"</item>
<item msgid="3028994095749238254">"ಆನ್"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ಲಭ್ಯವಿಲ್ಲ"</item>
+ <item msgid="6419996398343291862">"ಆಫ್ ಆಗಿದೆ"</item>
+ <item msgid="5908720590832378783">"ಆನ್ ಆಗಿದೆ"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cc2cb909058a..931066b3d749 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"입력"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"보청기"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"켜는 중..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"상위 앱에서 밝기를 제어하고 있으므로\n 밝기를 조절할 수 없습니다."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"자동 회전"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"화면 자동 회전"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"위치"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"새 기기와 페어링하려면 클릭하세요"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"사전 설정을 업데이트할 수 없음"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"미리 설정"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"선택됨"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"도구"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"실시간 자막"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"메모"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"기기 마이크를 차단 해제하시겠습니까?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"기기 카메라를 차단 해제하시겠습니까?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"기기 카메라 및 마이크를 차단 해제하시겠습니까?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"새로운 알림 없음"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"알림 쿨다운 사용 설정됨"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"한 번에 너무 많은 알림을 받으면 최대 2분간 자동으로 기기 볼륨이 줄어들고 알림이 최소화됩니다."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"사용 중지"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"잠금 해제하여 이전 알림 보기"</string>
@@ -699,7 +698,7 @@
<string name="volume_panel_noise_control_title" msgid="7413949943872304474">"소음 제어"</string>
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"공간 음향"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"사용 안함"</string>
- <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"수정됨"</string>
+ <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"고정됨"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"머리 추적"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"벨소리 장치 모드"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"화면 분할을 사용하는 중에 오른쪽 또는 아래쪽에 있는 앱으로 전환"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"화면 분할을 사용하는 중에 왼쪽 또는 위쪽에 있는 앱으로 전환하기"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"화면 분할 중: 다른 앱으로 바꾸기"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"디스플레이 간 활성 창 이동"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"입력"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"다음 언어로 전환"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"이전 언어로 전환"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>자 미만이어야 합니다."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"대화 위젯"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"대화를 탭하여 홈 화면에 추가하세요."</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"해상도를 높이려면 후면 카메라를 사용하세요."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"접은 상태"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"펼친 상태"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,33 +1418,26 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"키를 눌러 단축키 지정"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"작업 또는 메타 키 아이콘"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"더하기 아이콘"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"맞춤설정"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"완료"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"확장 아이콘"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"또는"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"드래그 핸들"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"키보드 설정"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"단축키 설정"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"취소"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"키를 누르세요."</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"이미 사용 중인 키 조합입니다. 다른 키를 사용해 보세요."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"키보드를 사용하여 이동"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"단축키에 관해 알아보세요."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"터치패드를 사용하여 이동"</string>
- <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"터치패드 동작 알아보기"</string>
+ <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"터치패드 동작을 알아보세요."</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"키보드와 터치패드를 사용하여 이동"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"터치패드 동작, 단축키 등 알아보기"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"뒤로 이동"</string>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index bfa11271bbab..002d38e71e96 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"사용 안함"</item>
<item msgid="3028994095749238254">"사용"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"사용할 수 없음"</item>
+ <item msgid="6419996398343291862">"사용 안함"</item>
+ <item msgid="5908720590832378783">"사용"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index bcf594db3ded..fc16164b6874 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -114,7 +114,7 @@
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтүндөй экранды жаздыруу"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Толук экранды жаздыруу: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүтүндөй экранды жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан этият болуп, сырсөздөр, төлөм ыкмалары, билдирүүлөр, сүрөттөр, аудио жана видео материалдар сыяктуу купуя нерселерди көрсөтүп албаңыз."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда ал колдонмодо көрсөтүлүп же ойнотулуп жаткан нерселер жаздырылат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видео сыяктуу нерселер менен этият болуңуз."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жаздыруу"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Жаздыруу үчүн колдонмо тандоо"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жаздыруу"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Киргизүү"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Угуу аппараттары"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Күйгүзүлүүдө…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Жарыктыкты тууралоого болбойт, анткени аны\n жогорку колдонмо көзөмөлдөйт"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авто буруу"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Экранды авто буруу"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Жайгашкан жер"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңы түзмөк кошуу үчүн басыңыз"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Алдын ала коюлган параметрлер жаңыртылган жок"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Алдын ала коюлган параметрлер"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Тандалды"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Куралдар"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ыкчам коштомо жазуулар"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Учкай маалымат"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Түзмөктүн микрофонун бөгөттөн чыгарасызбы?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Түзмөктүн камерасын бөгөттөн чыгарасызбы?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Түзмөктүн камерасы менен микрофону бөгөттөн чыгарылсынбы?"</string>
@@ -556,7 +556,7 @@
<!-- no translation found for media_projection_entry_app_permission_dialog_option_text_entire_screen (5100078808078139706) -->
<skip />
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="5504288438067851086">"Бүтүндөй экранды бөлүшкөндө андагы бардык нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
- <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Колдонмону бөлүшкөндө ал колдонмодо көрсөтүлүп же ойнотулуп жаткан нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+ <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Колдонмону бөлүшкөндө, андагы нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видеолор менен этият болуңуз."</string>
<string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Экранды бөлүшүү"</string>
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> бул параметрди өчүрүп койду"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Бөлүшүү үчүн колдонмо тандоо"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңы билдирмелер жок"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Азыр билдирмелердин үнүн басаңдатуу күйүк"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Өтө көп билдирме келсе, түзмөктүн үнү 2 мүнөткө басаңдап, эскертүүлөрдүн саны азаят."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өчүрүү"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Билдирмелерди көрүү үчүн кулпуну ачыңыз"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлүнгөн экранда сол же төмөн жактагы колдонмого которулуу"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлүнгөн экранды колдонуп жатканда сол же жогору жактагы колдонмого которулуңуз"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлүү режиминде бир колдонмону экинчисине алмаштыруу"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Активдүү терезени экрандардын ортосунда жылдыруу"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Киргизүү"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Кийинки тилге которулуу"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Мурунку тилге которулуу"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> символдон ашпашы керек"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Сүйлөшүүлөр виджеттери"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Сүйлөшүүнү башкы экранга кошуу үчүн таптап коюңуз"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жогорку дааналык үчүн телефондун арткы камерасын колдонуңуз"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"бүктөлгөн"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ачылган"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,34 +1418,27 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Ыкчам баскычты дайындоо үчүн баскычты басыңыз"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Аракет же Мета ачкыч сүрөтчөсү"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Кошуу сүрөтчөсү"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Ыңгайлаштыруу"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Бүттү"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жайып көрсөтүү сүрөтчөсү"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"же"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Cүйрөө маркери"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Баскычтоп параметрлери"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
- <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Нерселерге баскычтоп аркылуу өтүңүз"</string>
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ыкчам баскычты тууралоо"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Баскычты басыңыз"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ачкыч айкалышы колдонулууда. Башка ачкычты байкап көрүңүз."</string>
+ <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Керектүү нерселерге баскычтоп аркылуу өтүү"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ыкчам баскычтар тууралуу билип алыңыз"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Керектүү жерге сенсордук такта аркылуу өтөсүз"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Сенсордук тактадагы жаңсоолорду үйрөнүп алыңыз"</string>
- <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Нерселерге баскычтоп жана сенсордук такта аркылуу өтүңүз"</string>
+ <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Керектүү нерселерге баскычтоп жана сенсордук такта аркылуу өтүү"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Сенсордук тактадагы жаңсоолор, ыкчам баскычтар жана башкалар жөнүндө билип алыңыз"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Артка кайтуу"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Башкы бетке өтүү"</string>
@@ -1452,7 +1447,7 @@
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артка кайтуу"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Сенсордук тактаны үч манжаңыз менен солго же оңго сүрүңүз"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Сонун!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"\"Артка\" жаңсоосу боюнча үйрөткүчтү бүтүрдүңүз."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"\"Артка\" жаңсоосун үйрөндүңүз."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Башкы бетке өтүү"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Сенсордук тактаны үч манжаңыз менен жогору сүрүңүз"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Азаматсыз!"</string>
@@ -1496,6 +1491,6 @@
<string name="qs_edit_mode_category_providedByApps" msgid="8346112074897919019">"Колдонмолор сунуштады"</string>
<string name="qs_edit_mode_category_display" msgid="4749511439121053942">"Экран"</string>
<string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Белгисиз"</string>
- <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бардык карталарды баштапкы абалга келтиресизби?"</string>
- <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык Ыкчам параметрлер карталары түзмөктүн баштапкы параметрлерине кайтарылат"</string>
+ <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Бардык параметрлерди кайра коесузбу?"</string>
+ <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Бардык ыкчам параметрлер түзмөктүн баштапкы маанилерине кайтарылат"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index e9d9612a4e47..4834dbc69246 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Өчүк"</item>
<item msgid="3028994095749238254">"Күйүк"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Жеткиликсиз"</item>
+ <item msgid="6419996398343291862">"Өчүк"</item>
+ <item msgid="5908720590832378783">"Күйүк"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 235015b5286f..70ae5c1832af 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -91,7 +91,6 @@
<dimen name="notification_blocker_channel_list_height">128dp</dimen>
<dimen name="keyguard_indication_margin_bottom">8dp</dimen>
- <dimen name="lock_icon_margin_bottom">24dp</dimen>
<!-- Keyboard shortcuts helper -->
<dimen name="ksh_container_horizontal_margin">48dp</dimen>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 4898fa8d823a..3a8c682bce0e 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ການປ້ອນຂໍ້ມູນ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ເຄື່ອງຊ່ວຍຟັງ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ກຳລັງເປີດ..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ບໍ່ສາມາດປັບຄວາມແຈ້ງເນື່ອງຈາກມັນ\n ຖືກຄວບຄຸມໂດຍແອັບຍອດນິຍົມ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ໝຸນ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ສະຖານທີ່"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ຄລິກເພື່ອຈັບຄູ່ອຸປະກອນໃໝ່"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ບໍ່ສາມາດອັບເດດການຕັ້ງຄ່າລ່ວງໜ້າໄດ້"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ຄ່າທີ່ກຳນົດລ່ວງໜ້າ"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ເລືອກແລ້ວ"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ເຄື່ອງມື"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ຄຳບັນຍາຍສົດ"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ບັນທຶກ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ປົດບລັອກໄມໂຄຣໂຟນອຸປະກອນບໍ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ປົດບລັອກກ້ອງຖ່າຍຮູບອຸ​ປະ​ກອນບໍ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ຍົກເລີກການບລັອກກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນອຸ​ປະ​ກອນບໍ?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຂວາ ຫຼື ທາງລຸ່ມໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຊ້າຍ ຫຼື ທາງເທິງໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ໃຫ້ປ່ຽນຈາກແອັບໜຶ່ງເປັນອີກແອັບໜຶ່ງ"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ຍ້າຍໜ້າຈໍທີ່ເປີດຢູ່ໄປມາລະຫວ່າງຈໍສະແດງຜົນຕ່າງໆ"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ການປ້ອນຂໍ້ມູນ"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ສະຫຼັບເປັນພາສາຖັດໄປ"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ສະຫຼັບເປັນພາສາກ່ອນໜ້າ"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ໃຊ້ໜ້ອຍກວ່າ <xliff:g id="LENGTH">%1$d</xliff:g> ຕົວອັກສອນ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ວິດເຈັດການສົນທະນາ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ແຕະໃສ່ການສົນທະນາໃດໜຶ່ງເພື່ອເພີ່ມມັນໃສ່ໂຮມສະກຣີນຂອງທ່ານ"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ເພື່ອຄວາມລະອຽດທີ່ສູງຂຶ້ນ, ໃຫ້ປີ້ນໂທລະສັບ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ພັບແລ້ວ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ກາງອອກແລ້ວ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ປັບແຕ່ງຄີລັດ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ກົດປຸ່ມເພື່ອກໍານົດທາງລັດ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ທາງລັດການຊອກຫາ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ບໍ່ມີຜົນການຊອກຫາ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ໄອຄອນຫຍໍ້ລົງ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ໄອຄອນຄຳສັ່ງ ຫຼື ປຸ່ມ Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ໄອຄອນໝາຍບວກ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ປັບແຕ່ງ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ແລ້ວໆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ໄອຄອນຂະຫຍາຍ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ຫຼື"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ບ່ອນຈັບລາກ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ການຕັ້ງຄ່າແປ້ນພິມ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ຕັ້ງທາງລັດ"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ຍົກເລີກ"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ກົດປຸ່ມ"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ນໍາໃຊ້ປຸ່ມປະສົມຢູ່ແລ້ວ. ໃຫ້ລອງປຸ່ມອື່ນ."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ນຳທາງໂດຍໃຊ້ແປ້ນພິມຂອງທ່ານ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ສຶກສາຄີລັດ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ນຳທາງໂດຍໃຊ້ແຜ່ນສຳຜັດຂອງທ່ານ"</string>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 34af9aae31e3..bc63895f3bc6 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ປິດ"</item>
<item msgid="3028994095749238254">"ເປີດ"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+ <item msgid="6419996398343291862">"ປິດ"</item>
+ <item msgid="5908720590832378783">"ເປີດ"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index aff0d3085bfa..ae85ed2060c6 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Įvestis"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Klausos aparatai"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Įjungiama…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Negalima koreguoti ryškumo, nes jį valdo\n viršuje esanti programa"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatinis pasukimas"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatiškai sukti ekraną"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Vietovė"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Spustelėkite, kad susietumėte naują įrenginį"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Išankstinių nustatymų atnaujinti nepavyko"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Išankstiniai nustatymai"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Pasirinkta"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Įrankiai"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrai realiuoju laiku"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Pastaba"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Panaikinti įrenginio mikrofono blokavimą?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Panaikinti įrenginio fotoaparato blokavimą?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Panaikinti įrenginio fotoaparato ir mikrofono blokavimą?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Perjunkite į programą dešinėje arba apačioje išskaidyto ekrano režimu"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Perjunkite į programą kairėje arba viršuje išskaidyto ekrano režimu"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Aktyvaus lango perkėlimas iš vieno ekrano į kitą"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Įvestis"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Perjungti į kitą kalbą"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Perjungti į ankstesnę kalbą"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Naudokite daugiausia <xliff:g id="LENGTH">%1$d</xliff:g> simb."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Pokalbio valdikliai"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Palieskite pokalbį, kad pridėtumėte jį prie pagrindinio ekrano"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kad raiška būtų geresnė, apverskite telefoną"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"sulenkta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"nesulenkta"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sparčiųjų klavišų tinkinimas"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Paspauskite klavišą, kad priskirtumėte spartųjį klavišą"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ieškoti sparčiųjų klavišų"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nėra jokių paieškos rezultatų"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sutraukimo piktograma"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Veiksmo arba metaduomenų klavišo piktograma"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pliuso piktograma"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tinkinti"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Atlikta"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Išskleidimo piktograma"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"arba"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkimo rankenėlė"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatūros nustatymai"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nustatyti spartųjį klavišą"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Atšaukti"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paspauskite klavišą"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Klavišų derinys jau naudojamas. Bandykite naudoti kitą klavišą."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naršykite naudodamiesi klaviatūra"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Sužinokite apie sparčiuosius klavišus"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naršykite naudodamiesi jutikline dalimi"</string>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 124f49c7d22e..12f8b6ce02cf 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Išjungta"</item>
<item msgid="3028994095749238254">"Įjungta"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nepasiekiama"</item>
+ <item msgid="6419996398343291862">"Išjungta"</item>
+ <item msgid="5908720590832378783">"Įjungta"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b0b417675c1c..b20ab36a3896 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ievade"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Dzirdes aparāti"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Notiek ieslēgšana…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nevar mainīt spilgtumu, jo to kontrolē\n aktīvā lietotne."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automātiska pagriešana"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automātiska ekrāna pagriešana"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Atrašanās vieta"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Noklikšķiniet, lai savienotu pārī jaunu ierīci"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pirmsiestatījums"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Atlasīts"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Rīki"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitri reāllaikā"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Piezīme"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vai atbloķēt ierīces kameru un mikrofonu?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nav jaunu paziņojumu"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Nogaidīšanas periods paziņojumiem ir ieslēgts"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Saņemot par daudz paziņojumu uzreiz, skaļums un brīdinājumi tiek automātiski samazināti līdz 2 min."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izslēgt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atbloķējiet vecāku paziņojumu skatīšanai"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pāriet uz lietotni pa labi/lejā, kamēr izmantojat sadalīto ekrānu."</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pāriet uz lietotni pa kreisi/augšā, kamēr izmantojat sadalīto ekrānu."</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena ekrāna uz otru"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Pārvietot aktīvo logu starp displejiem"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ievade"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Pārslēgt uz nākamo valodu"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Pārslēgt uz iepriekšējo valodu"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Izmantojiet mazāk nekā <xliff:g id="LENGTH">%1$d</xliff:g> rakstzīmes."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Sarunu logrīki"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Pieskarieties kādai sarunai, lai pievienotu to savam sākuma ekrānam."</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Lai izmantotu augstāku izšķirtspēju, apvērsiet tālruni"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"aizvērta"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"atvērta"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Īsinājumtaustiņu pielāgošana"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Lai piešķirtu īsinājumtaustiņu, nospiediet taustiņu"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēt saīsnes"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nav meklēšanas rezultātu"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sakļaušanas ikona"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Darbību jeb meta taustiņa ikona"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pluszīmes ikona"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Pielāgot"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gatavs"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Izvēršanas ikona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vai"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkšanas turis"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastatūras iestatījumi"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Iestatīt īsinājumtaustiņu"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Atcelt"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nospiediet taustiņu"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Taustiņu kombinācija jau tiek izmantota. Izmēģiniet citu taustiņu."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pārvietošanās, izmantojot tastatūru"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Uzziniet par īsinājumtaustiņiem."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pārvietošanās, izmantojot skārienpaliktni"</string>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index e5cb1758b783..14948360d102 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Izslēgts"</item>
<item msgid="3028994095749238254">"Ieslēgts"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nav pieejams"</item>
+ <item msgid="6419996398343291862">"Izslēgts"</item>
+ <item msgid="5908720590832378783">"Ieslēgts"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index e30cf21fceec..f8bfcf9296ca 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Влез"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слушни помагала"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Се вклучува…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не може да се приспособи осветленоста бидејќи е\n контролирана од горната апликација"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматско ротирање"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматско ротирање на екранот"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за да спарите нов уред"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатки"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматски титлови"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се одблокира пристапот до микрофонот на уредот?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се одблокира пристапот до камерата на уредот?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Да се одблокира пристапот до камерата и микрофонот на уредот?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нови известувања"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"„Подискретни известувања“ сега е вклучена"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Јачината на звукот и известувањата на уредот се намалуваат автоматски до 2 минути кога добивате премногу известувања одеднаш."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Исклучи"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отклучете за да ги видите старите известувања"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Префрлете се на апликацијата десно или долу при користењето поделен екран"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Префрлете се на апликацијата лево или горе при користењето поделен екран"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"При поделен екран: префрлете ги аплик. од едната на другата страна"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Движете го активниот прозорец меѓу екраните"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Внесување"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Префрлете на следниот јазик"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Префрлете на претходниот јазик"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Употребете помалку од <xliff:g id="LENGTH">%1$d</xliff:g> знаци"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Виџети за разговор"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Допрете разговор за да го додадете на почетниот екран"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Отворете го телефонот за да добиете повисока резолуција"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворен"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворен"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Приспособете ги кратенките од тастатурата"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Притиснете го копчето за да доделите кратенка"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пребарувајте кратенки"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултати од пребарување"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за собирање"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Икона за дејство или копче за дејство"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Икона плус"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Приспособете"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширување"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Рачка за влечење"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Поставки за тастатурата"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Поставете кратенка"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притиснете го копчето"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбинацијата на копчиња веќе се користи. Обидете се со друго копче."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Движете се со користење на тастатурата"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете ги кратенките од тастатурата"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Движете се со користење на допирната подлога"</string>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 61539d62baf7..17545c332b63 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Исклучено"</item>
<item msgid="3028994095749238254">"Вклучено"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Недостапно"</item>
+ <item msgid="6419996398343291862">"Исклучено"</item>
+ <item msgid="5908720590832378783">"Вклучено"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 42f67c6558c2..54364c804581 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ഇൻപുട്ട്"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ശ്രവണ സഹായികൾ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ഓണാക്കുന്നു…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"തെളിച്ചം അഡ്‌ജസ്റ്റ് ചെയ്യാനാകില്ല, അത്\n നിയന്ത്രിക്കുന്നത് ഏറ്റവും മുകളിലുള്ള ആപ്പാണ്"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"സ്‌ക്രീൻ സ്വയമേവ തിരിയൽ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"സ്‌ക്രീൻ സ്വയമേവ തിരിക്കുക"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ലൊക്കേഷൻ"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"പുതിയ ഉപകരണം ജോടിയാക്കാൻ ക്ലിക്ക് ചെയ്യുക"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"പ്രീസെറ്റ് അപ്ഡേറ്റ് ചെയ്യാനായില്ല"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"പ്രീസെറ്റ്"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"തിരഞ്ഞെടുത്തു"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ടൂളുകൾ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"തത്സമയ ക്യാപ്ഷൻ"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"കുറിപ്പ്"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ഉപകരണ മൈക്രോഫോൺ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ഉപകരണ ക്യാമറ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ഉപകരണ ക്യാമറയോ മൈക്രോഫോണോ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"പുതിയ അറിയിപ്പുകളൊന്നുമില്ല"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"അറിയിപ്പിന്റെ ശബ്ദം കുറയ്ക്കൽ ഇപ്പോൾ ഓണാണ്"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"നിരവധി അറിയിപ്പ് ഒരുമിച്ച് ലഭിക്കുമ്പോൾ, ഉപകരണത്തിന്റെ ശബ്‌ദവും മുന്നറിയിപ്പും 2 മിനിറ്റ് വരെ സ്വയമേവ കുറയ്ക്കും."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ഓഫാക്കുക"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"പഴയ അറിയിപ്പുകൾ കാണാൻ അൺലോക്ക് ചെയ്യുക"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറുക"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ ഇടതുവശത്തെ/മുകളിലെ ആപ്പിലേക്ക് മാറൂ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"സ്‌ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"സജീവ വിൻഡോകൾ ഡിസ്‌പ്ലേകൾക്ക് ഇടയിൽ നീക്കുക"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ഇൻപുട്ട്"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"അടുത്ത ഭാഷയിലേക്ക് മാറുക"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"മുമ്പത്തെ ഭാഷയിലേക്ക് മാറുക"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>-ൽ കുറവ് പ്രതീകങ്ങൾ ഉപയോഗിക്കുക"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"സംഭാഷണ വിജറ്റുകൾ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിൽ ചേർക്കാൻ സംഭാഷണത്തിൽ ടാപ്പ് ചെയ്യുക"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ഉയർന്ന റെസല്യൂഷന്, ഫോൺ ഫ്ലിപ്പ് ചെയ്യുക"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ഫോൾഡ് ചെയ്തത്"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"അൺഫോൾഡ് ചെയ്തത്"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"കുറുക്കുവഴി അസൈൻ ചെയ്യാൻ കീ അമർത്തുക"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ആക്ഷൻ/മെറ്റാ കീ ഐക്കൺ"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"പ്ലസ് ഐക്കൺ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"പൂർത്തിയായി"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"വികസിപ്പിക്കൽ ഐക്കൺ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"അല്ലെങ്കിൽ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"കീബോർഡ് ക്രമീകരണം"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"കുറുക്കുവഴി സജ്ജീകരിക്കുക"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"റദ്ദാക്കുക"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"കീ അമർത്തുക"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"കീ കോമ്പിനേഷൻ ഇതിനകം ഉപയോഗത്തിലുണ്ട്. മറ്റൊരു കീ പരീക്ഷിക്കുക."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"നിങ്ങളുടെ കീബോർഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"കീബോർഡ് കുറുക്കുവഴികൾ മനസ്സിലാക്കുക"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"നിങ്ങളുടെ ടച്ച്‌പാഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index c1278d46440f..689fe85bf3e6 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ഓഫാണ്"</item>
<item msgid="3028994095749238254">"ഓണാണ്"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ലഭ്യമല്ല"</item>
+ <item msgid="6419996398343291862">"ഓഫാണ്"</item>
+ <item msgid="5908720590832378783">"ഓണാണ്"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index c87f98acd3e9..0e2dc23e88c1 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Оролт"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Сонсголын төхөөрөмж"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Асааж байна…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Гэрэлтүүлгийг\nдавуу эрхтэй аппаас хянаж байгаа тул тохируулах боломжгүй"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматаар эргэх"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Дэлгэцийг автоматаар эргүүлэх"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Байршил"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Шинэ төхөөрөмж хослуулахын тулд товшино уу"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Урьдчилсан тохируулгыг шинэчилж чадсангүй"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Урьдчилсан тохируулга"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Сонгосон"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Хэрэгсэл"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Шууд тайлбар"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Тэмдэглэл"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Төхөөрөмжийн микрофоныг блокоос гаргах уу?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Төхөөрөмжийн камерыг блокоос гаргах уу?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Төхөөрөмжийн камер болон микрофоныг блокоос гаргах уу?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Шинэ мэдэгдэл алга"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Мэдэгдлийн хөргөлт одоо асаалттай байна"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Таныг хэт олон мэдэгдэл нэг дор авахад таны төхөөрөмжийн дууны түвшин болон дохиог 2 хүртэлх минутын турш автоматаар багасгадаг."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Унтраах"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Хуучин мэдэгдлийг харах бол түгжээг тайл"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Дэлгэц хуваахыг ашиглаж байхдаа баруун талд эсвэл доор байх апп руу сэлгэ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Дэлгэц хуваахыг ашиглаж байхдаа зүүн талд эсвэл дээр байх апп руу сэлгэ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Дэлгэц хуваах үеэр: аппыг нэгээс нөгөөгөөр солих"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Идэвхтэй цонхыг дэлгэц хооронд зөөх"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Оролт"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Дараагийн хэл рүү сэлгэх"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Өмнөх хэл рүү сэлгэх"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>-с цөөн тэмдэгт ашиглана уу"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Харилцан ярианы виджетүүд"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Үндсэн нүүрэндээ нэмэх харилцан яриаг товшино уу"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Илүү өндөр нягтрал авах бол утсыг хөнтөрнө үү"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"эвхсэн"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"дэлгэсэн"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Товчлуурын шууд холбоосыг өөрчлөх"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Товчлол оноохын тулд товч дарна уу"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Товчлолууд хайх"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ямар ч хайлтын илэрц байхгүй"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Хураах дүрс тэмдэг"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Үйлдлийн товч буюу өөрөөр Мета товчийн дүрс тэмдэг"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Нэмэх дүрс тэмдэг"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Өөрчлөх"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Болсон"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Гарын тохиргоо"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Товчлол тохируулах"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Цуцлах"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Товч дарна уу"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Товчийн хослолыг аль хэдийн ашиглаж байна. Өөр товч туршиж үзнэ үү."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Гараа ашиглан шилжих"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Товчлуурын шууд холбоосыг мэдэж аваарай"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Мэдрэгч самбараа ашиглан шилжээрэй"</string>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index da890cc5a157..94e393961988 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Унтраалттай"</item>
<item msgid="3028994095749238254">"Асаалттай"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Боломжгүй"</item>
+ <item msgid="6419996398343291862">"Унтраалттай"</item>
+ <item msgid="5908720590832378783">"Асаалттай"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 204399c77b96..cd9062252425 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"श्रवणयंत्रे"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सुरू करत आहे…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ब्राइटनेस ॲडजस्ट करू शकत नाही, कारण तो\n टॉप ॲपद्वारे नियंत्रित केला जात आहे"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ऑटो-रोटेट स्क्रीन"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"स्थान"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नवीन डिव्हाइस पेअर करण्यासाठी क्लिक करा"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट करता आले नाही"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"निवडला आहे"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव्ह कॅप्शन"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"टीप"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिव्हाइसचा मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिव्हाइसचा कॅमेरा अनब्लॉक करायचा आहे का?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"डिव्हाइसचा कॅमेरा आणि मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन वापरताना उजवीकडील किंवा खालील अ‍ॅपवर स्विच करा"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन वापरताना डावीकडील किंवा वरील अ‍ॅपवर स्विच करा"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीनदरम्यान: एक अ‍ॅप दुसऱ्या अ‍ॅपने बदला"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ॲक्टिव्ह विंडो डिस्प्लेदरम्यान हलवा"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"पुढील भाषेवर स्विच करा"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"मागील भाषेवर स्विच करा"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वर्णांपेक्षा कमी वर्ण वापरा"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"संभाषण विजेट"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"तुमच्या होम स्क्रीन वर संभाषण जोडण्यासाठी त्यावर टॅप करा"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रेझोल्यूशनसाठी, फोन फ्लिप करा"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड केलेले"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"फोल्ड न केलेले"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अ‍ॅक्सेसिबिलिटी"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"शॉर्टकट असाइन करण्यासाठी की प्रेस करा"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"कृती किंवा मेटा की आयकन"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"अधिक आयकन"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"कस्टमाइझ करा"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"पूर्ण झाले"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"विस्तार करा आयकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"किंवा"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्रॅग हॅंडल"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग्ज"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करा"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करा"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की प्रेस करा"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"की कॉम्बिनेशन आधीपासून वापरले जात आहे. दुसरी की वापरून पहा."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"तुमचा कीबोर्ड वापरून नेव्हिगेट करा"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट जाणून घ्या"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"तुमचा टचपॅड वापरून नेव्हिगेट करा"</string>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index 3ea25a68922b..cbaefb9367c2 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"बंद आहे"</item>
<item msgid="3028994095749238254">"सुरू आहे"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"उपलब्ध नाही"</item>
+ <item msgid="6419996398343291862">"बंद आहे"</item>
+ <item msgid="5908720590832378783">"सुरू आहे"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index ce2b3f07c547..c108fc476da0 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Alat bantu pendengaran"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Menghidupkan…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Tidak dapat melaraskan kecerahan kerana peranti\n dikawal oleh apl popular"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoputar"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoputar skrin"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menggandingkan peranti baharu"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat mengemaskinikan pratetapan"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pratetapan"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatan"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sari Kata Langsung"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Nyahsekat mikrofon peranti?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Nyahsekat kamera peranti?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Nyahsekat kamera dan mikrofon peranti?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Tukar kepada apl di sebelah kanan/bawah semasa menggunakan skrin pisah"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Tukar kepada apl di sebelah kiri/atas semasa menggunakan skrin pisah"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Semasa skrin pisah: gantikan apl daripada satu apl kepada apl lain"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Alihkan tetingkap aktif antara paparan"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih kepada bahasa seterusnya"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Beralih kepada bahasa sebelumnya"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gunakan kurang daripada <xliff:g id="LENGTH">%1$d</xliff:g> aksara"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widget perbualan"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Ketik perbualan untuk menambahkan perbualan itu pada skrin Utama anda"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk peleraian lebih tinggi, balikkan telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"terlipat"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"tidak terlipat"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tekan kekunci untuk menetapkan pintasan"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon kekunci tindakan atau Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikon tambah"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Pemegang seret"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tetapan Papan Kekunci"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tetapkan pintasan"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan kekunci"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Gabungan kekunci sudah digunakan. Cuba kekunci lain."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ketahui pintasan papan kekunci"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigasi menggunakan pad sentuh anda"</string>
@@ -1449,17 +1445,17 @@
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Lihat apl terbaharu"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
- <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Leret ke kiri atau ke kanan menggunakan tiga jari pada pad sentuh anda"</string>
+ <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Leret ke kiri atau ke kanan menggunakan tiga jari pada pad sentuh"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bagus!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah melengkapkan gerak isyarat undur."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah melengkapkan gerak isyarat kembali."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Akses laman utama"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Leret ke atas dengan tiga jari pada pad sentuh anda"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bagus!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Anda telah melengkapkan gerak isyarat akses laman utama"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Lihat apl terbaharu"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh anda"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Syabas!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda melengkapkan gerak isyarat lihat apl terbaharu."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah melengkapkan gerak isyarat lihat apl terbaharu."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua apl"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan kekunci tindakan pada papan kekunci anda"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Syabas!"</string>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 51f215b31931..3c78bccfef53 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Mati"</item>
<item msgid="3028994095749238254">"Hidup"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Tidak tersedia"</item>
+ <item msgid="6419996398343291862">"Mati"</item>
+ <item msgid="5908720590832378783">"Hidup"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index a3568f2b56bb..ce52f4e4e024 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"အဝင်"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"နားကြားကိရိယာ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ဖွင့်နေသည်…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"၎င်းကို ထိပ်ဆုံးရှိအက်ပ်က\n ထိန်းချုပ်နေသဖြင့် တောက်ပမှုကို ပြင်ဆင်၍မရပါ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"စက်အသစ် တွဲချိတ်ရန် နှိပ်ပါ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"အသင့်သုံးကို အပ်ဒိတ်လုပ်၍မရပါ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ကြိုတင်သတ်မှတ်ချက်"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ရွေးထားသည်"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"တူးလ်များ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"တိုက်ရိုက်စာတန်း"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"မှတ်စု"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"စက်၏မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"စက်၏ကင်မရာကို ပြန်ဖွင့်မလား။"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"စက်၏ကင်မရာနှင့် မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက် မရှိပါ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"အကြောင်းကြားချက် သတိပေးမှု လျှော့ချခြင်း ဖွင့်လိုက်ပြီ"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"အကြောင်းကြားချက်များစွာ တစ်ပြိုင်နက်ရပါက သင့်စက်၏ အသံနှင့် သတိပေးချက်ကို ၂ မိနစ်ကြာသည်အထိ အလိုအလျောက်လျှော့ချသည်။"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ပိတ်ရန်"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"မျက်နှာပြင်ခွဲ၍ပြသခြင်း သုံးစဉ် ညာ (သို့) အောက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသုံးစဉ် ဘယ် (သို့) အထက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"လက်ရှိဝင်းဒိုးကို ပြကွက်များအကြား ရွှေ့ခြင်း"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"စာရိုက်ခြင်း"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"နောက်ဘာသာစကားသို့ ပြောင်းရန်"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ယခင်ဘာသာစကားသို့ ပြောင်းရန်"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"အက္ခရာ <xliff:g id="LENGTH">%1$d</xliff:g> လုံးအောက် သုံးရန်"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်ပုံအမှတ်"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"စကားဝိုင်း ဝိဂျက်များ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"စကားဝိုင်းကို သင်၏ ‘ပင်မစာမျက်နှာ’ သို့ထည့်ရန် တို့ပါ"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ပုံရိပ် ပိုမိုပြတ်သားစေရန် ဖုန်းကို တစ်ဖက်သို့ လှန်လိုက်ပါ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ခေါက်ထားသည်"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ဖြန့်ထားသည်"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"လက်ကွက်ဖြတ်လမ်းများကို စိတ်ကြိုက်လုပ်ခြင်း"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ဖြတ်လမ်းသတ်မှတ်ရန် ကီးကို နှိပ်ပါ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ဖြတ်လမ်းများ ရှာရန်"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ရှာဖွေမှုရလဒ် မရှိပါ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"လျှော့ပြရန် သင်္ကေတ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"လုပ်ဆောင်ချက် (သို့) Meta ကီးသင်္ကေတ"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"အပေါင်းသင်္ကေတ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"စိတ်ကြိုက်လုပ်ရန်"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ပြီးပြီ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ပိုပြရန် သင်္ကေတ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"သို့မဟုတ်"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ဖိဆွဲအထိန်း"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ကီးဘုတ်ဆက်တင်များ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ဖြတ်လမ်း သတ်မှတ်ရန်"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"မလုပ်တော့"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ကီးကို နှိပ်ပါ"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ကီးပေါင်းစပ်ခြင်းကို သုံးနေပြီးဖြစ်သည်။ အခြားကီးကို စမ်းကြည့်ပါ။"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"သင့်ကီးဘုတ်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"လက်ကွက်ဖြတ်လမ်းများကို လေ့လာပါ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"သင့်တာ့ချ်ပက်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string>
@@ -1461,7 +1456,7 @@
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"သင့်တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"တော်ပါပေသည်။"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ။"</string>
- <string name="tutorial_action_key_title" msgid="8172535792469008169">"အက်ပ်အားလုံးကို ကြည့်ရန်"</string>
+ <string name="tutorial_action_key_title" msgid="8172535792469008169">"အက်ပ်အားလုံးကို ကြည့်ခြင်း"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ကီးဘုတ်တွင် လုပ်ဆောင်ချက်ကီး နှိပ်ပါ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"အလွန်ကောင်းပါသည်။"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"အက်ပ်အားလုံးကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ"</string>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 7af75166de11..9675cb5b46b4 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ပိတ်"</item>
<item msgid="3028994095749238254">"ဖွင့်"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"မရနိုင်ပါ"</item>
+ <item msgid="6419996398343291862">"ပိတ်"</item>
+ <item msgid="5908720590832378783">"ဖွင့်"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 38b267332f47..db352a5fc4b0 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Innenhet"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Høreapparater"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Slår på …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kan ikke justere lysstyrken, fordi den\n kontrolleres av appen på toppen"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotér automatisk"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotér skjermen automatisk"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Sted"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klikk for å koble til en ny enhet"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kunne ikke oppdatere forhåndsinnstillingen"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forhåndsinnstilling"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktøy"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Direkteteksting"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Merknad"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du oppheve blokkeringen av enhetsmikrofonen?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du oppheve blokkeringen av enhetskameraet?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du oppheve blokkeringen av enhetskameraet og -mikrofonen?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye varsler"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Nå er varseldempingen slått på"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enhetsvolumet og varsler reduseres automatisk i opptil 2 min når du får for mange varsler samtidig."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slå av"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås opp for å se eldre varsler"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bytt til appen til høyre eller under mens du bruker delt skjerm"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bytt til appen til venstre eller over mens du bruker delt skjerm"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"I delt skjerm: Bytt ut en app"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Flytt det aktive vinduet mellom skjermer"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Skrivespråk"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Bytt til neste språk"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Bytt til forrige språk"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Bruk færre enn <xliff:g id="LENGTH">%1$d</xliff:g> tegn"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Samtalemoduler"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Trykk på en samtale for å legge den til på startskjermen"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En foldbar enhet blir brettet ut"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En foldbar enhet blir snudd"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"lagt sammen"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"åpen"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpass hurtigtastene"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Trykk på tasten for å tilordne hurtigtasten"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ingen søkeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Handlings- eller Meta-tast-ikon"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plussikon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tilpass"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Ferdig"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vis-ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtak"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tastaturinnstillinger"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Angi hurtigtast"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Avbryt"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Trykk på tasten"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tastekombinasjonen brukes allerede. Prøv en annen tast."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger med tastaturet"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lær deg hurtigtaster"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger med styreflaten"</string>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index 3ed1a4e4aa7a..bd5b69279714 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Av"</item>
<item msgid="3028994095749238254">"På"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Utilgjengelig"</item>
+ <item msgid="6419996398343291862">"Av"</item>
+ <item msgid="5908720590832378783">"På"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 82f9aca68198..2c1d7271ac19 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -73,7 +73,7 @@
<string name="learn_more" msgid="4690632085667273811">"थप जान्नुहोस्"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"स्क्रिनसट"</string>
<string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"एक्स्टेन्ड अनलक अफ गरिएको छ"</string>
- <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै छवि पठाइयो"</string>
+ <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै फोटो पठाइयो"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रिनसट बचत गर्दै…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ…"</string>
<string name="screenshot_saving_private_profile" msgid="8934706048497093297">"निजी प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ"</string>
@@ -116,7 +116,7 @@
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तपाईंले आफ्नो पूरै स्क्रिन रेकर्ड गरिरहेका बेला तपाईंको स्क्रिनमा देखाइने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तपाईंले यो एप रेकर्ड गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रिन रेकर्ड गर्नुहोस्"</string>
- <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रेकर्ड गर्न छनौट गर्नुहोस्"</string>
+ <string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रेकर्ड गर्न एप छनौट गर्नुहोस्"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="screenrecord_device_audio_label" msgid="9016927171280567791">"डिभाइसको अडियो"</string>
<string name="screenrecord_device_audio_description" msgid="4922694220572186193">"तपाईंको डिभाइसका सङ्गीत, कल र रिङटोन जस्ता साउन्ड"</string>
@@ -311,7 +311,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"डिस्कनेक्ट गर्नुहोस्"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"एक्टिभेट गर्नुहोस्"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"भोलि स्वतः अन गर्नुहोस्"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ चाहिन्छ"</string>
+ <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ अन गर्नु पर्ने हुन्छ"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लुटुथ भोलि बिहान अन हुने छ"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"अडियो सेयर गर्नुहोस्"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"अडियो सेयर गरिँदै छ"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"हियरिङ डिभाइसहरू"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"सक्रिय गर्दै…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"टप एपले चमक नियन्त्रण गरिरहेकाले\n चमक मिलाउन मिल्दैन"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"लोकेसन"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नयाँ डिभाइसमा कनेक्ट गर्न क्लिक गर्नुहोस्"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रिसेट अपडेट गर्न सकिएन"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"पूर्वनिर्धारित"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चयन गरिएको छ"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टुल"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइभ क्याप्सन"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिभाइसको माइक्रोफोन अनब्लक गर्ने हो?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिभाइसको क्यामेरा अनब्लक गर्ने हो?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"डिभाइसको क्यामेरा र माइक्रोफोन अनब्लक गर्ने हो?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा दायाँ वा तलको एप चलाउनुहोस्"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा बायाँ वा माथिको एप चलाउनुहोस्"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रिन प्रयोग गरिएका बेला: एउटा स्क्रिनमा भएको एप अर्कोमा लैजानुहोस्"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"सक्रिय विन्डोलाई एउटा डिस्प्लेबाट सारेर अर्को डिस्प्लेमा लैजानुहोस्"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"अर्को भाषा प्रयोग गर्नुहोस्"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"अघिल्लो भाषा प्रयोग गर्नुहोस्"</string>
@@ -1006,7 +1005,7 @@
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="5389597396308001471">"Wi‑Fi अफ छ"</string>
<string name="bt_is_off" msgid="7436344904889461591">"ब्लुटुथ अफ छ"</string>
- <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प निष्क्रिय छ"</string>
+ <string name="dnd_is_off" msgid="3185706903793094463">"बाधा नपुर्‍याउनुहोस् नामक विकल्प अफ छ"</string>
<string name="dnd_is_on" msgid="7009368176361546279">"Do Not Disturb अन छ"</string>
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"कुनै स्वचालित नियमले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रियो गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
<string name="qs_dnd_prompt_app" msgid="4027984447935396820">"कुनै एपले बाधा नपुऱ्याउनुहोस् नामक विकल्पलाई सक्रिय गऱ्यो (<xliff:g id="ID_1">%s</xliff:g>)।"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> वटा भन्दा कम वर्ण प्रयोग गर्नुहोस्"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"वार्तालापसम्बन्धी विजेटहरू"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"कुनै वार्तालाप होम स्क्रिनमा हाल्न उक्त वार्तालापमा ट्याप गर्नुहोस्"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रिजोल्युसनको सेल्फी खिच्न फोन फ्लिप गर्नुहोस्"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"फोल्ड गरिएको"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"अनफोल्ड गरिएको"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"किबोर्डका सर्टकटहरू कस्टमाइज गर्नुहोस्"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"सर्टकट असाइन गर्न की थिच्नुहोस्"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कुनै पनि खोज परिणाम भेटिएन"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"एक्सन वा Meta कीको आइकन"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"प्लस आइकन"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"कस्टमाइज गर्नुहोस्"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"पूरा भयो"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\"एक्स्पान्ड गर्नुहोस्\" आइकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"वा"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्र्याग ह्यान्डल"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"किबोर्डसम्बन्धी सेटिङ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"सर्टकट सेट गर्नुहोस्"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द गर्नुहोस्"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की थिच्नुहोस्"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"यो की कम्बिनेसन प्रयोग गरिसकिएको छ। अर्कै की प्रयोग गरी हेर्नुहोस्।"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"किबोर्ड प्रयोग गरी नेभिगेट गर्नुहोस्"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"किबोर्डका सर्टकटहरू प्रयोग गर्न सिक्नुहोस्"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचप्याड प्रयोग गरी नेभिगेट गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 2350c67d2bcf..2dd209d8565b 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"अफ छ"</item>
<item msgid="3028994095749238254">"अन छ"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"उपलब्ध छैन"</item>
+ <item msgid="6419996398343291862">"अफ छ"</item>
+ <item msgid="5908720590832378783">"अन छ"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3e0b5d9d144d..0d195a3b40d7 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hoortoestellen"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aanzetten…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Kan de helderheid niet aanpassen omdat deze wordt\n beheerd door de bovenste app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Scherm automatisch draaien"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Locatie"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nieuw apparaat te koppelen"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Kan voorinstelling niet updaten"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorinstelling"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Geselecteerd"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live ondertiteling"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notitie"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Microfoon van apparaat niet meer blokkeren?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Apparaatcamera niet meer blokkeren?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blokkeren van apparaatcamera en -microfoon opheffen?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Naar de app rechts of onderaan gaan als je een gesplitst scherm gebruikt"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Naar de app links of bovenaan gaan als je een gesplitst scherm gebruikt"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Tijdens gesplitst scherm: een app vervangen door een andere"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Actief venster verplaatsen tussen schermen"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Overschakelen naar volgende taal"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Overschakelen naar vorige taal"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gebruik minder dan <xliff:g id="LENGTH">%1$d</xliff:g> tekens"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Draai de telefoon om voor een hogere resolutie"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"dichtgevouwen"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"opengevouwen"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Druk op de toets om de sneltoets toe te wijzen"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sneltoetsen zoeken"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icoon voor actie- of metatoets"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusicoon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Aanpassen"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klaar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icoon voor uitvouwen"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handgreep voor slepen"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Toetsenbordinstellingen"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Sneltoets instellen"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuleren"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk op een toets"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Toetsencombinatie is al in gebruik. Probeer een andere toets."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeren met je toetsenbord"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer sneltoetsen die je kunt gebruiken"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeren met je touchpad"</string>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index 4193463cae8e..221749c2c90b 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Uit"</item>
<item msgid="3028994095749238254">"Aan"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Niet beschikbaar"</item>
+ <item msgid="6419996398343291862">"Uit"</item>
+ <item msgid="5908720590832378783">"Aan"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 980c47d13883..181315ba045c 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ଇନପୁଟ୍"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ଅନ୍ ହେଉଛି…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ଟପ ଆପ ଦ୍ୱାରା ଉଜ୍ଜ୍ୱଳତା ନିୟନ୍ତ୍ରିତ\nହେଉଥିବା ଯୋଗୁଁ ଏହାକୁ ଆଡଜଷ୍ଟ କରିପାରିବେ ନାହିଁ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ ସ୍କ୍ରିନ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ଲୋକେସନ"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ନୂଆ ଡିଭାଇସ ପେୟାର କରିବାକୁ କ୍ଲିକ କରନ୍ତୁ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ପ୍ରିସେଟକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ପ୍ରିସେଟ"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ଚୟନ କରାଯାଇଛି"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ଟୁଲ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ଲାଇଭ କେପ୍ସନ"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ନୋଟ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ କରିବେ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ଡିଭାଇସର କେମେରାକୁ ଅନବ୍ଲକ କରିବେ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ଡିଭାଇସର କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ୍ କରିବେ?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"କୌଣସି ନୂଆ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ନାହିଁ"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"ବିଜ୍ଞପ୍ତି କୁଲଡାଉନ ବର୍ତ୍ତମାନ ଚାଲୁ ଅଛି"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ଆପଣ ଥରକେ ଏକାଧିକ ବିଜ୍ଞପ୍ତି ପ୍ରାପ୍ତ କଲେ ଆପଣଙ୍କ ଡିଭାଇସର ଭଲ୍ୟୁମ ଓ ଆଲର୍ଟ ସ୍ୱତଃ 2 ମିନିଟ ପର୍ଯ୍ୟନ୍ତ କମ ହୁଏ।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ପୁରୁଣା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
@@ -699,7 +698,7 @@
<string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ନଏଜ କଣ୍ଟ୍ରୋଲ"</string>
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"ସ୍ପାସିଅଲ ଅଡିଓ"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"ବନ୍ଦ ଅଛି"</string>
- <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ନିଶ୍ଚିତ ହୋଇଛି"</string>
+ <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ଠିକ ହୋଇଯାଇଛି"</string>
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ହେଡ ଟ୍ରାକିଂ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ରିଂଗର ମୋଡ"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ସକ୍ରିୟ ୱିଣ୍ଡୋକୁ ଡିସପ୍ଲେଗୁଡ଼ିକ ମଧ୍ୟରେ ମୁଭ କରନ୍ତୁ"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ପରବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ପୂର୍ବବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g>ଟିରୁ କମ କେରେକ୍ଟର ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ବାର୍ତ୍ତାଳାପ ୱିଜେଟଗୁଡ଼ିକ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ଏକ ବାର୍ତ୍ତାଳାପକୁ ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରିବା ପାଇଁ ସେଥିରେ ଟାପ କରନ୍ତୁ"</string>
@@ -1291,7 +1291,7 @@
<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_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_message" msgid="2670045017200730076">"ଆପଣ ଏହି ଆପ୍ସକୁ ବ୍ୟବହାର କରୁନଥିଲେ ମଧ୍ୟ ସେଗୁଡ଼ିକ ସକ୍ରିୟ ରହିଥାଏ ଏବଂ ଚାଲୁଥାଏ। ଏହା ସେଗୁଡ଼ିକର କାର୍ଯ୍ୟକ୍ଷମତାକୁ ଉନ୍ନତ କରେ, କିନ୍ତୁ ଏହା ମଧ୍ୟ ବେଟେରୀ ଲାଇଫକୁ ପ୍ରଭାବିତ କରିପାରେ।"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ପାଇଁ ଫୋନକୁ ଫ୍ଲିପ କରନ୍ତୁ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ଫୋଲ୍ଡେଡ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ଅନଫୋଲ୍ଡେଡ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ସର୍ଟକଟ ଆସାଇନ କରିବା ପାଇଁ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ସର୍ଚ୍ଚ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"କୌଣସି ସର୍ଚ୍ଚ ଫଳାଫଳ ନାହିଁ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ଆଇକନକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ଆକ୍ସନ କିମ୍ବା ମେଟା କୀ ଆଇକନ"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ପ୍ଲସ ଆଇକନ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ହୋଇଗଲା"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ଆଇକନକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"କିମ୍ବା"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ଡ୍ରାଗ ହେଣ୍ଡେଲ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"କୀବୋର୍ଡ ସେଟିଂ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ସର୍ଟକଟ ସେଟ କରନ୍ତୁ"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ବାତିଲ କରନ୍ତୁ"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"କୀ ଦବାନ୍ତୁ"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"କୀ କମ୍ବିନେସନ ପୂର୍ବରୁ ବ୍ୟବହାର କରାଯାଉଛି। ଅନ୍ୟ ଏକ କୀ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ।"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ଆପଣଙ୍କ କୀବୋର୍ଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକ ବିଷୟରେ ଜାଣନ୍ତୁ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ଆପଣଙ୍କ ଟଚପେଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string>
@@ -1457,11 +1452,11 @@
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ବଢ଼ିଆ କାମ!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ଆପଣ \'ହୋମକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
- <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରନ୍ତୁ"</string>
+ <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ବର୍ତ୍ତମାନର ଆପ୍ସକୁ ଭ୍ୟୁ କରନ୍ତୁ"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିକୁ ବ୍ୟବହାର କରି ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ବଢ଼ିଆ କାମ!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ଆପଣ ବର୍ତ୍ତମାନର ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
- <string name="tutorial_action_key_title" msgid="8172535792469008169">"ସମସ୍ତ ଆପ ଭ୍ୟୁ କରନ୍ତୁ"</string>
+ <string name="tutorial_action_key_title" msgid="8172535792469008169">"ସବୁ ଆପ ଭ୍ୟୁ କରନ୍ତୁ"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ବହୁତ ବଢ଼ିଆ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ଆପଣ ସମସ୍ତ ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index 35afd612e6b6..8d230739caf7 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ବନ୍ଦ ଅଛି"</item>
<item msgid="3028994095749238254">"ଚାଲୁ ଅଛି"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ଅନୁପଲବ୍ଧ"</item>
+ <item msgid="6419996398343291862">"ବନ୍ଦ ଅଛି"</item>
+ <item msgid="5908720590832378783">"ଚାଲୁ ଅଛି"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 8cc9f6e57939..5b9919ef97b6 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ਇਨਪੁੱਟ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ਸੁਣਨ ਦੇ ਸਾਧਨ"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ਚਮਕ ਨੂੰ ਵਿਵਸਥਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਕਿਉਂਕਿ ਇਹ ਪਹਿਲਾਂ ਚੱਲ ਰਹੀ ਐਪ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕਰਨ ਕਰਕੇ \n ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁਮਾਓ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ਟਿਕਾਣਾ"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"\'ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ\' \'ਤੇ ਕਲਿੱਕ ਕਰੋ"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ਪ੍ਰੀਸੈੱਟ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ਪ੍ਰੀਸੈੱਟ"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ਚੁਣਿਆ ਗਿਆ"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ਟੂਲ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ਲਾਈਵ ਸੁਰਖੀਆਂ"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"ਨੋਟ-ਕਥਨ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"ਨੋਟੀਫ਼ਿਕੇਸ਼ਨ ਕੂਲਡਾਊਨ ਹੁਣ ਚਾਲੂ ਹੈ"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ਇੱਕ ਵਾਰ \'ਚ ਕਈ ਸੂਚਨਾਵਾਂ ਮਿਲਣ \'ਤੇ, ਡੀਵਾਈਸ ਦੀ ਅਵਾਜ਼ ਅਤੇ ਅਲਰਟ ਵੱਧੋ-ਵੱਧ 2 ਮਿੰਟਾਂ ਲਈ ਆਪਣੇ-ਆਪ ਘੱਟ ਜਾਂਦੇ ਹਨ।"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ਬੰਦ ਕਰੋ"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ਪੁਰਾਣੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਸੱਜੇ ਜਾਂ ਹੇਠਾਂ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਖੱਬੇ ਜਾਂ ਉੱਪਰ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਨੂੰ ਬਦਲੋ"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ਕਿਰਿਆਸ਼ੀਲ ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਤੋਂ ਦੂਜੇ ਡਿਸਪਲੇ \'ਤੇ ਲਿਜਾਓ"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ਇਨਪੁੱਟ"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"ਅਗਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"ਪਿਛਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> ਤੋਂ ਘੱਟ ਅੱਖਰ-ਚਿੰਨ੍ਹ ਵਰਤੋ"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"ਗੱਲਬਾਤ ਵਿਜੇਟ"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਕਿਸੇ ਗੱਲਬਾਤ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਲਈ, ਫ਼ੋਨ ਨੂੰ ਫਲਿੱਪ ਕਰੋ"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"ਫੋਲਡਯੋਗ ਡੀਵਾਈਸ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"ਅਣਫੋਲਡਯੋਗ ਡੀਵਾਈਸ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,31 +1418,24 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ਸ਼ਾਰਟਕੱਟ ਨਿਰਧਾਰਿਤ ਕਰਨ ਲਈ ਕੁੰਜੀ ਦਬਾਓ"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਸ਼ਾਰਟਕੱਟ ਖੋਜੋ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ਕੋਈ ਖੋਜ ਨਤੀਜਾ ਨਹੀਂ ਮਿਲਿਆ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ਪ੍ਰਤੀਕ ਨੂੰ ਸਮੇਟੋ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ਕਾਰਵਾਈ ਜਾਂ Meta ਕੁੰਜੀ ਪ੍ਰਤੀਕ"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ਜੋੜ-ਚਿੰਨ੍ਹ ਦਾ ਪ੍ਰਤੀਕ"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ਹੋ ਗਿਆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ਪ੍ਰਤੀਕ ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ਜਾਂ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ਘਸੀਟਣ ਵਾਲਾ ਹੈਂਡਲ"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ਕੀ-ਬੋਰਡ ਸੈਟਿੰਗਾਂ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ਸ਼ਾਰਟਕੱਟ ਸੈੱਟ ਕਰੋ"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ਰੱਦ ਕਰੋ"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ਕੁੰਜੀ ਦਬਾਓ"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"ਕੁੰਜੀ ਸੁਮੇਲ ਪਹਿਲਾਂ ਹੀ ਵਰਤੋਂ ਵਿੱਚ ਹੈ। ਕੋਈ ਹੋਰ ਕੁੰਜੀ ਨੂੰ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
- <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਬਾਰੇ ਜਾਣੋ"</string>
+ <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਦੇ ਸ਼ਾਰਟਕੱਟਾਂ ਬਾਰੇ ਜਾਣੋ"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"ਟੱਚਪੈਡ ਇਸ਼ਾਰਿਆਂ ਬਾਰੇ ਜਾਣੋ"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਅਤੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index ab2f8abdd739..0f53e5d933df 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ਬੰਦ ਹੈ"</item>
<item msgid="3028994095749238254">"ਚਾਲੂ ਹੈ"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ਉਪਲਬਧ ਨਹੀਂ"</item>
+ <item msgid="6419996398343291862">"ਬੰਦ"</item>
+ <item msgid="5908720590832378783">"ਚਾਲੂ"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c183116e3528..e41d16f82785 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Wejście"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparaty słuchowe"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Włączam…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nie można dostosować jasności, ponieważ jest ona\nkontrolowana przez aplikację na pierwszym planie"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoobracanie"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoobracanie ekranu"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokalizacja"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Gotowe ustawienie"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Wybrano"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Narzędzia"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Napisy na żywo"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notatka"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokować aparat i mikrofon urządzenia?"</string>
@@ -561,8 +561,8 @@
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Wybieranie aplikacji do udostępniania"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Włączyć przesyłanie treści wyświetlanych na ekranie?"</string>
- <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z jednej aplikacji"</string>
- <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Przesyłanie obrazu z całego ekranu"</string>
+ <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z 1 aplikacji"</string>
+ <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Przesyłanie całego ekranu"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Kiedy przesyłasz treści z całego ekranu, widoczny jest cały obraz z wyświetlacza. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Kiedy przesyłasz obraz z aplikacji, widoczne jest wszystko to, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Prześlij ekran"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Przełącz się na aplikację po prawej lub poniżej na podzielonym ekranie"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Przełącz się na aplikację po lewej lub powyżej na podzielonym ekranie"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Podczas podzielonego ekranu: zastępowanie aplikacji"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Przenieś aktywne okno na inny ekran"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Wprowadzanie"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Przełącz na następny język"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Przełącz na poprzedni język"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Wpisz mniej znaków niż <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widżety rozmów"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Kliknij rozmowę, aby dodać ją do ekranu głównego"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Odwróć telefon, aby uzyskać wyższą rozdzielczość"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"po zamknięciu"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"po otwarciu"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Naciśnij klawisz, aby przypisać skrót"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona klawisza działania/meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona plusa"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Dostosuj"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gotowe"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozwijania"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"lub"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Uchwyt do przeciągania"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ustawienia klawiatury"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ustaw skrót"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anuluj"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Naciśnij klawisz"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacja klawiszy jest już używana. Użyj innego klawisza."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nawiguj za pomocą klawiatury"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Dowiedz się więcej o skrótach klawiszowych"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nawiguj za pomocą touchpada"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index d3191b0f6631..c9eb500c3e9c 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Wyłączono"</item>
<item msgid="3028994095749238254">"Włączone"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Niedostępny"</item>
+ <item msgid="6419996398343291862">"Wyłączony"</item>
+ <item msgid="5908720590832378783">"Włączony"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index f1dd9a4b27b1..72e593c06718 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ativando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Não é possível ajustar o brilho, porque ele está sendo\n controlado pelo app principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Desativado"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Não definido"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gerenciar nas configurações"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}one{# modo está ativo}many{# de modos estão ativos}other{# modos estão ativos}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum ativo}=1{{mode} ativo}one{# modo ativo}many{# de modos ativos}other{# modos ativos}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Você não será perturbado por sons e vibrações, exceto alarmes. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -563,8 +563,8 @@
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmitir tela inteira"</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Quando você está transmitindo a tela inteira, tudo nela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele ficam visíveis. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Durante a transmissão, tudo que está na sua tela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele vão aparecer. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmitir tela"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Escolha um app para transmitir"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Começar a compartilhar?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"O recurso de atenuar notificações está ativado"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e alertas são reduzidos por até 2 min quando você recebe muitas notificações juntas."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover janela ativa entre telas"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para o idioma anterior"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pressione a tecla para atribuir o atalho"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configurações do teclado"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atalho"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pressione a tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Essa combinação de teclas já está em uso. Tente outra tecla."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string>
@@ -1458,7 +1453,7 @@
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Muito bem!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Você concluiu o gesto para acessar a tela inicial"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver os apps recentes"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima e pressione com 3 dedos no touchpad"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima com 3 dedos e mantenha"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index e315bad6bf80..9ddc41ca4b24 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desativar"</item>
<item msgid="3028994095749238254">"Ativar"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Indisponível"</item>
+ <item msgid="6419996398343291862">"Desativado"</item>
+ <item msgid="5908720590832378783">"Ativado"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 03c32a834721..460d55304e1e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"A ativar..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Não é possível ajustar o brilho porque está a ser\n controlado pela app principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para sincronizar um novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legendas instantâneas"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmara do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Quer desbloquear a câmara e o microfone?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Desativado"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Não definido"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gerir nas definições"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}many{# modos estão ativos}other{# modos estão ativos}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} ativo}many{# modos ativos}other{# modos ativos}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Não é incomodado por sons e vibrações, exceto de alarmes. Continua a ouvir tudo o que optar por reproduzir, incluindo música, vídeos e jogos."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para a app à direita ou abaixo enquanto usa o ecrã dividido"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mude para a app à esquerda ou acima enquanto usa o ecrã dividido"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Durante o ecrã dividido: substituir uma app por outra"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mova a janela ativa entre ecrãs"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para idioma seguinte"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para idioma anterior"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> carateres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque numa conversa para a adicionar ao ecrã principal"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução superior, inverta o telemóvel"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Prima a tecla para atribuir o atalho"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla Meta ou de ação"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de mais"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Indicador para arrastar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Definições do teclado"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configurar atalho"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prima a tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue com o teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos de teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue com o touchpad"</string>
@@ -1457,7 +1453,7 @@
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"É assim mesmo!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Concluiu o gesto para aceder ao ecrã principal"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver apps recentes"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize rapidamente para cima e mantenha premido com 3 dedos no touchpad"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize rapidamente para cima sem soltar com 3 dedos no touchpad"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Concluiu o gesto para ver as apps recentes."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas as apps"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index deb6783e1b23..5baa61c136dc 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desativados"</item>
<item msgid="3028994095749238254">"Ativados"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Indisponível"</item>
+ <item msgid="6419996398343291862">"Desativado"</item>
+ <item msgid="5908720590832378783">"Ativado"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index f1dd9a4b27b1..72e593c06718 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Entrada"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparelhos auditivos"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ativando…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Não é possível ajustar o brilho, porque ele está sendo\n controlado pelo app principal"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Desativado"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Não definido"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Gerenciar nas configurações"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum modo ativo}=1{{mode} está ativo}one{# modo está ativo}many{# de modos estão ativos}other{# modos estão ativos}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Nenhum ativo}=1{{mode} ativo}one{# modo ativo}many{# de modos ativos}other{# modos ativos}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Você não será perturbado por sons e vibrações, exceto alarmes, lembretes, eventos e chamadas de pessoas especificadas. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Você não será perturbado por sons e vibrações, exceto alarmes. No entanto, você ouvirá tudo o que decidir reproduzir, como músicas, vídeos e jogos."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Personalizar"</string>
@@ -563,8 +563,8 @@
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
<string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Transmitir tela inteira"</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Quando você está transmitindo a tela inteira, tudo nela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
- <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele ficam visíveis. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Durante a transmissão, tudo que está na sua tela fica visível. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
+ <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Quando você transmite um app, todas as informações visíveis ou abertas nele vão aparecer. Por isso, tenha cuidado com senhas, detalhes da forma de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Transmitir tela"</string>
<string name="media_projection_entry_cast_app_selector_title" msgid="6323062146661922387">"Escolha um app para transmitir"</string>
<string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Começar a compartilhar?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"O recurso de atenuar notificações está ativado"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volume e alertas são reduzidos por até 2 min quando você recebe muitas notificações juntas."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mover janela ativa entre telas"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Mudar para o idioma anterior"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Use menos de <xliff:g id="LENGTH">%1$d</xliff:g> caracteres"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"fechado"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"aberto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pressione a tecla para atribuir o atalho"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configurações do teclado"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Definir atalho"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pressione a tecla"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Essa combinação de teclas já está em uso. Tente outra tecla."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string>
@@ -1458,7 +1453,7 @@
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Muito bem!"</string>
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Você concluiu o gesto para acessar a tela inicial"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver os apps recentes"</string>
- <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima e pressione com 3 dedos no touchpad"</string>
+ <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima com 3 dedos e mantenha"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
<string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index e315bad6bf80..9ddc41ca4b24 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Desativar"</item>
<item msgid="3028994095749238254">"Ativar"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Indisponível"</item>
+ <item msgid="6419996398343291862">"Desativado"</item>
+ <item msgid="5908720590832378783">"Ativado"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5b3190fef48c..42fd14b1b9c2 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Intrare"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparate auditive"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Se activează..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Nu se poate ajusta luminozitatea deoarece este\n controlată de aplicația de top"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotire automată"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotirea automată a ecranului"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Locație"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Dă clic pentru a asocia un nou dispozitiv"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Nu s-a putut actualiza presetarea"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Presetare"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selectat"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Instrumente"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrări live"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notă"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblochezi microfonul dispozitivului?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblochezi camera dispozitivului?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblochezi camera și microfonul dispozitivului?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nicio notificare nouă"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Reducerea sunetului notificărilor este activată"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volumul și alertele dispozitivului sunt reduse automat timp de până la 2 min. când primești prea multe notificări odată"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Dezactivează"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Deblochează ca să vezi notificări vechi"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Treci la aplicația din dreapta sau de mai jos cu ecranul împărțit"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Treci la aplicația din stânga sau de mai sus cu ecranul împărțit"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Mută fereastra activă de pe un ecran pe altul"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Introducere"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Comută la următoarea limbă"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Comută la limba anterioară"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Folosește maximum <xliff:g id="LENGTH">%1$d</xliff:g> caractere"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Deschide conversația"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgeturi pentru conversație"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Atinge o conversație ca să o adaugi pe ecranul de pornire"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pentru o rezoluție mai mare, deschide telefonul"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"închis"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"deschis"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizează comenzile rapide de la tastatură"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Apasă tasta pentru a atribui comanda rapidă"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Comenzi directe de căutare"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Niciun rezultat al căutării"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Pictograma de restrângere"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Pictograma pentru acțiune sau tastă Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Pictograma plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizează"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Gata"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Pictograma de extindere"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"sau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ghidaj de tragere"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Setările tastaturii"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setează o comandă rapidă"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anulează"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Apasă tasta"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Combinația de taste este deja folosită. Încearcă altă tastă."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navighează folosind tastatura"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Învață comenzile rapide de la tastatură"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navighează folosind touchpadul"</string>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index fa950c30850a..528b112c72a6 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Dezactivat"</item>
<item msgid="3028994095749238254">"Activat"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Indisponibil"</item>
+ <item msgid="6419996398343291862">"Dezactivat"</item>
+ <item msgid="5908720590832378783">"Activat"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 665bd26a386e..866cb5e8f602 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -113,8 +113,8 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записывать одно приложение"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записывать весь экран"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записывать весь экран: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Во время записи всего экрана все данные и действия, которые на нем показываются, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Во время записи приложения все данные и действия, которые показываются в его окне, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"На видео попадет все, что будет происходить на экране. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"На видео попадет все, что происходит в выбранном приложении. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запись экрана"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Выбор приложения для записи экрана"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Записывать аудио"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Устройство ввода"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слуховые аппараты"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Включение…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Невозможно изменить яркость,\nтак как она регулируется общими настройками."</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоповорот"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоповорот экрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Геолокация"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Нажмите, чтобы подключить новое устройство"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрано"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменты"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматические субтитры"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Заметка"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблокировать камеру и микрофон устройства?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"Отключено"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"Не задано"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"Открыть настройки"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{Включено 0 режимов}=1{Включен режим \"{mode}\"}one{Включен # режим}few{Включено # режима}many{Включено # режимов}other{Включено # режима}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{0 режимов}=1{Режим \"{mode}\"}one{# режим}few{# режима}many{# режимов}other{# режима}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника, напоминаний, уведомлений о мероприятиях и звонков от помеченных контактов. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"Вас не будут отвлекать звуки и вибрация, за исключением сигналов будильника. Вы по-прежнему будете слышать включенную вами музыку, видео, игры и т. д."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"Настроить"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений."</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Новых уведомлений нет"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Снижение громкости уведомлений включено"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Если придет слишком много уведомлений, на две минуты громкость и количество оповещений уменьшатся."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Отключить"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблокируйте, чтобы увидеть уведомления"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти к приложению справа или внизу на разделенном экране"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Перейти к приложению слева или вверху на разделенном экране"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"В режиме разделения экрана заменить одно приложение другим"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Переместить активное окно между экранами"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ввод"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Выбрать следующий язык"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Выбрать предыдущий язык"</string>
@@ -1006,7 +1004,7 @@
<string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="5389597396308001471">"Модуль Wi-Fi отключен"</string>
- <string name="bt_is_off" msgid="7436344904889461591">"Модуль Bluetooth отключен."</string>
+ <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth отключен"</string>
<string name="dnd_is_off" msgid="3185706903793094463">"Режим \"Не беспокоить\" отключен"</string>
<string name="dnd_is_on" msgid="7009368176361546279">"Режим \"Не беспокоить\" включен"</string>
<string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Режим \"Не беспокоить\" был включен специальным правилом (<xliff:g id="ID_1">%s</xliff:g>)."</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Максимальное количество символов – <xliff:g id="LENGTH">%1$d</xliff:g>."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Виджеты разговоров"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Нажмите на разговор, чтобы добавить его на главный экран"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Переверните телефон и используйте основную камеру, чтобы делать снимки с более высоким разрешением."</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"устройство сложено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"устройство разложено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Как настроить быстрые клавиши"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Нажмите клавишу, чтобы назначить быструю команду."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Значок клавиши Meta для выполнения действия"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Значок плюса"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Настроить"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Развернуть\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перемещения"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки клавиатуры"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задать сочетание клавиш"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отмена"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Нажмите клавишу"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Это сочетание клавиш уже используется. Попробуйте другое."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигация с помощью клавиатуры"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Узнайте о сочетаниях клавиш."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигация с помощью сенсорной панели"</string>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index cd12baeadbb2..43d3e2ac31ed 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Отключены"</item>
<item msgid="3028994095749238254">"Включены"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Недоступно"</item>
+ <item msgid="6419996398343291862">"Отключено"</item>
+ <item msgid="5908720590832378783">"Включено"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 0df5d4494e67..0ccd61c41905 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ආදානය"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"ශ්‍රවණාධාරක"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ක්‍රියාත්මක කරමින්…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ඉහළ යෙදුම මඟින් එය පාලනය වන නිසා\nදීප්තිය ගැළපුම් කළ නොහැක"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ස්වයංක්‍රීය කරකැවීම"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ස්වයංක්‍රීයව-භ්‍රමණය වන තිරය"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ස්ථානය"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"නව උපාංගය යුගල කිරීමට ක්ලික් කරන්න"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"පෙර සැකසීම යාවත්කාලීන කළ නොහැකි විය"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"පෙරසැකසුම"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"තෝරන ලදි"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"මෙවලම්"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"සජීවී සිරස්තල"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"සටහන"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"උපාංග මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"උපාංග කැමරාව අවහිර කිරීම ඉවත් කරන්නද?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"උපාංග කැමරාව සහ මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"දැනුම්දීම් නැත"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"නව දැනුම්දීම් නැත"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"දැනුම්දීම් සිසිල් කිරීම දැන් ක්‍රියාත්මකයි"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"ඔබට එකවර දැනුම්දීම් වැඩි ප්‍රමාණයක් ලැබෙන විට ඔබේ උපාංග පරිමාව සහ ඇඟවීම් මිනිත්තු 2ක් දක්වා ස්වයංක්‍රීයව අඩු වේ."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ක්‍රියාවිරහිත කරන්න"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"පැරණි දැනුම්දීම් බැලීමට අගුළු හරින්න"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"බෙදුම් තිරය භාවිත කරන අතරතුර දකුණේ හෝ පහළින් ඇති යෙදුමට මාරු වන්න"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"බෙදුම් තිරය භාවිත කරන අතරතුර වමේ හෝ ඉහළ ඇති යෙදුමට මාරු වන්න"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්‍රතිස්ථාපනය කරන්න"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"සක්‍රිය කවුළුව සංදර්ශක අතර ගෙන යන්න"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ආදානය"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"මීළඟ භාෂාවට මාරු වන්න"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"පෙර භාෂාවට මාරු වන්න"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"අනුලකුණු <xliff:g id="LENGTH">%1$d</xliff:g>කට වඩා අඩුවෙන් භාවිතා කරන්න"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"සංවාද විජට්"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ඔබගේ මුල් තිරයට එය එක් කිරීමට සංවාදයක් තට්ටු කරන්න"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ඉහළ විභේදනය සඳහා, දුරකථනය හරවන්න"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"නැවූ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"නොනැවූ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"යතුරුපුවරු කෙටිමං අභිරුචිකරණය කරන්න"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"කෙටි මග පැවරීමට යතුර ඔබන්න"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"කෙටි මං සොයන්න"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"සෙවීම් ප්‍රතිඵල නැත"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"හැකුළුම් නිරූපකය"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ක්‍රියාව හෝ Meta යතුරු නිරූපකය"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ධන නිරූපකය"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"අභිරුචිකරණය කරන්න"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"නිමයි"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"දිගහැරීම් නිරූපකය"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"හෝ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ඇදීම් හැඬලය"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"යතුරු පුවරු සැකසීම්"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"කෙටිමඟ සකසන්න"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"අවලංගු කරන්න"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"යතුර ඔබන්න"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"යතුරු සංයෝජනය දැනටමත් භාවිත වේ. වෙනත් යතුරක් උත්සාහ කරන්න."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ඔබේ යතුරු පුවරුව භාවිතයෙන් සංචාලනය කරන්න"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"යතුරුපුවරු කෙටිමං ඉගෙන ගන්න"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ඔබේ ස්පර්ශ පෑඩ් භාවිතයෙන් සංචාලනය කරන්න"</string>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 595575d7eebc..91280e1e00bd 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ක්‍රියාවිරහිතයි"</item>
<item msgid="3028994095749238254">"ක්‍රියාත්මකයි"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ලබා ගත නොහැක"</item>
+ <item msgid="6419996398343291862">"ක්‍රියාවිරහිතයි"</item>
+ <item msgid="5908720590832378783">"ක්‍රියාත්මකයි"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7331ba015726..cc59beafe025 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vstup"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Načúvadlá"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Zapína sa…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Jas sa nedá upraviť, pretože ho \n ovláda horná aplikácia"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčanie"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčanie obrazovky"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zariadenie"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predvoľba"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybrané"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Živý prepis"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Chcete odblokovať kameru zariadenia?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Chcete odblokovať fotoaparát a mikrofón zariadenia?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Žiadne nové upozornenia"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Stlmenie upozornení je zapnuté"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Keď dostanete priveľa upozornení naraz, až na dve minúty sa zníži hlasitosť zariadenia a upozornenia sa obmedzia."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnúť"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odomknutím zobrazíte staršie upozornenia"</string>
@@ -700,7 +699,7 @@
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Priestorový zvuk"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Vypnuté"</string>
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Pevné"</string>
- <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sled. polohy hlavy"</string>
+ <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledovanie hlavy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"režim zvonenia"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prechod na aplikáciu vpravo alebo dole pri rozdelenej obrazovke"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prechod na aplikáciu vľavo alebo hore pri rozdelenej obrazovke"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Presun aktívneho okna medzi obrazovkami"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Prepnutie na ďalší jazyk"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Prepnutie na predchádzajúci jazyk"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Použite menej znakov než <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikácie konverzácií"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Klepnite na konverzáciu a pridajte ju tak na plochu"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ak chcete vyššie rozlíšenie, prevráťte telefón"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zložené"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"rozložené"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,55 +1418,48 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Stlačením klávesa priraďte skratku"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona akčného klávesa alebo metaklávesa"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prispôsobiť"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Hotovo"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalenia"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"alebo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Presúvadlo"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavenia klávesnice"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
- <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Prechádzajte pomocou klávesnice"</string>
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastaviť skratku"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušiť"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stlačte kláves"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinácia klávesov sa už používa. Skúste iný kláves."</string>
+ <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pohybujte sa v systéme pomocou klávesnice"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte sa klávesové skratky"</string>
- <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Prechádzajte pomocou touchpadu"</string>
+ <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pohybujte sa v systéme pomocou touchpadu"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Naučte sa gestá touchpadu"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Prechádzajte pomocou klávesnice a touchpadu"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Naučte sa gestá touchpadu, klávesové skratky a ďalšie funkcie"</string>
- <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Prejsť späť"</string>
+ <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Prechod späť"</string>
<string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Prejsť na plochu"</string>
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Zobrazenie nedávnych aplikácií"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejsť späť"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Potiahnite troma prstami na touchpade doľava alebo doprava"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Výborne!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Dokončili ste gesto na prechod späť."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Použili ste gesto na prechod späť."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Prechod na plochu"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Potiahnite troma prstami na touchpade nahor"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Skvelé!"</string>
- <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Dokončili ste gesto na prechod na plochu"</string>
+ <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Použili ste gesto na prechod na plochu."</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Zobrazenie nedávnych aplikácií"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Potiahnite troma prstami na touchpade nahor a pridržte"</string>
<string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Skvelé!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Dokončili ste gesto na zobrazenie nedávnych aplikácií."</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Použili ste gesto na zobrazenie nedávnych aplikácií."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"Zobrazenie všetkých aplikácií"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stlačte na klávesnici akčný kláves"</string>
- <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Výborne!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Dokončili ste gesto na zobrazenie všetkých aplikácií"</string>
+ <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Dobre!"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Použili ste gesto na zobrazenie všetkých aplikácií."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 607c2215642b..0b0b89483188 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Vypnuté"</item>
<item msgid="3028994095749238254">"Zapnuté"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nedostupné"</item>
+ <item msgid="6419996398343291862">"Vypnuté"</item>
+ <item msgid="5908720590832378783">"Zapnuté"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index d0b0a9ddd0a3..38f1e5a1fb6d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vhodna naprava"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Slušni aparati"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Vklapljanje …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Svetlosti ni mogoče prilagoditi, ker jo\n nadzoruje aplikacija na vrhu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Samodejno sukanje"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Samodejno sukanje zaslona"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite za seznanitev nove naprave"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Prednastavljenih vrednosti ni bilo mogoče posodobiti"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Prednastavljeno"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izbrano"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Orodja"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Samodejni podnapisi"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Opomba"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite odblokirati mikrofon v napravi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite odblokirati fotoaparat v napravi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite odblokirati fotoaparat in mikrofon v napravi?"</string>
@@ -561,8 +561,8 @@
<string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočila to možnost"</string>
<string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Izbira aplikacije za deljenje"</string>
<string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite predvajati vsebino zaslona?"</string>
- <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Predvajanje vsebine ene aplikacije"</string>
- <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Predvajanje vsebine celotnega zaslona"</string>
+ <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Predvajanje ene aplikacije"</string>
+ <string name="media_projection_entry_cast_permission_dialog_option_text_entire_screen" msgid="8389508187954155307">"Predvajanje celotnega zaslona"</string>
<string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="4040447861037324017">"Pri predvajanju vsebine celotnega zaslona je vidno vse na zaslonu. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="7487834861348460736">"Pri predvajanju vsebine aplikacije je vidno vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="media_projection_entry_cast_permission_dialog_continue_entire_screen" msgid="3261124185304676483">"Predvajanje zaslona"</string>
@@ -699,7 +699,7 @@
<string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Prostorski zvok"</string>
<string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Izklopljeno"</string>
<string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
- <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje premikov glave"</string>
+ <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"način zvonjenja"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Preklop na aplikacijo desno ali spodaj med uporabo razdeljenega zaslona"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Preklop na aplikacijo levo ali zgoraj med uporabo razdeljenega zaslona"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Pri razdeljenem zaslonu: medsebojna zamenjava aplikacij"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Premikanje aktivnega okna med zasloni"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vnos"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Preklop na naslednji jezik"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Preklop na prejšnji jezik"</string>
@@ -1202,8 +1201,8 @@
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvočniki in zasloni"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predlagane naprave"</string>
- <string name="media_input_group_title" msgid="2057057473860783021">"Vhodno"</string>
- <string name="media_output_group_title" msgid="6789001895863332576">"Izhodno"</string>
+ <string name="media_input_group_title" msgid="2057057473860783021">"Vhod"</string>
+ <string name="media_output_group_title" msgid="6789001895863332576">"Izhod"</string>
<string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Ustavi deljeno sejo za premik predstavnosti v drugo napravo."</string>
<string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Ustavi"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Uporabite manj kot <xliff:g id="LENGTH">%1$d</xliff:g> znakov."</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Pripomočki za pogovore"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dotaknite se pogovora, da ga dodate na začetni zaslon."</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višjo ločljivost obrnite telefon"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"zaprto"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"razprto"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pritisnite tipko za dodelitev bližnjice"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Iskanje po bližnjicah"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke za dejanje ali metapodatke"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Končano"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ročica za vlečenje"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavitve tipkovnice"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavite bližnjico"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Prekliči"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipko"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinacija tipk je že v uporabi. Poskusite z drugo tipko."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krmarjenje s tipkovnico"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Učenje bližnjičnih tipk"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krmarjenje s sledilno ploščico"</string>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index fddaea615bab..f9ccbb1fde86 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Izklopljeno"</item>
<item msgid="3028994095749238254">"Vklopljeno"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Ni na voljo"</item>
+ <item msgid="6419996398343291862">"Izklopljeno"</item>
+ <item msgid="5908720590832378783">"Vklopljeno"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 428caf08c81d..9ed8bf29d630 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Hyrja"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Aparatet e dëgjimit"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Po aktivizohet…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ndriçimi nuk mund të rregullohet pasi\n po kontrollohet nga aplikacioni i sipërm"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rrotullim automatik"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rrotullimi automatik i ekranit"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Vendndodhja"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliko për të çiftuar një pajisje të re"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Paravendosja nuk mund të përditësohej"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Paravendosja"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Zgjedhur"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Veglat"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titrat në çast"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Shënim"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Të zhbllokohet mikrofoni i pajisjes?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Të zhbllokohet kamera e pajisjes?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Të zhbllokohen kamera dhe mikrofoni i pajisjes?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Nuk ka njoftime të reja"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Reduktimi i njoftimeve është aktiv tani"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Volumi i pajisjes dhe sinjalizimet zvogëlohen automatikisht për deri në 2 minuta kur merr shumë njoftime në të njëjtën kohë."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Çaktivizo"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Shkyç për të parë njoftimet e vjetra"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Kalo tek aplikacioni djathtas ose poshtë kur përdor ekranin e ndarë"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Kalo tek aplikacioni në të majtë ose sipër kur përdor ekranin e ndarë"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Gjatë ekranit të ndarë: zëvendëso një aplikacion me një tjetër"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Zhvendose dritaren aktive mes ekraneve"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Hyrja"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Kalo te gjuha tjetër"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Kalo te gjuha e mëparshme"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Përdor më pak se <xliff:g id="LENGTH">%1$d</xliff:g> karaktere"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikacionet e bisedave"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Trokit te një bisedë dhe shtoje në ekranin bazë"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Për rezolucion më të lartë, përmbys telefonin"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"palosur"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"shpalosur"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizo shkurtoret e tastierës"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Shtyp tastin për të caktuar shkurtoren"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kërko për shkurtoret"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Asnjë rezultat kërkimi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona e palosjes"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona e tastit të veprimit ose tastit Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona e plusit"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizo"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"U krye"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona e zgjerimit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ose"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Doreza e zvarritjes"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Cilësimet e tastierës"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Cakto shkurtoren"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anulo"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Shtyp tastin"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Kombinimi i tasteve është tashmë në përdorim. Provo një tast tjetër."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigo duke përdorur tastierën tënde"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Mëso shkurtoret e tastierës"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigo duke përdorur bllokun me prekje"</string>
@@ -1450,7 +1445,7 @@
<string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Shiko aplikacionet e fundit"</string>
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"U krye"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kthehu prapa"</string>
- <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta në bllokun me prekje."</string>
+ <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta në bllokun me prekje"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bukur!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"E ke përfunduar gjestin e kthimit prapa."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Shko tek ekrani bazë"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index b30c8e7847de..1ab4f01c56e2 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Joaktive"</item>
<item msgid="3028994095749238254">"Aktive"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Nuk ofrohen"</item>
+ <item msgid="6419996398343291862">"Joaktive"</item>
+ <item msgid="5908720590832378783">"Aktive"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 63b3e9a4f38d..102c452fc54a 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Унос"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слушни апарати"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Укључује се..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не можете да прилагодите осветљеност јер је\n контролише апликација у врху"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликните да бисте упарили нов уређај"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Унапред одређена подешавања"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Изабрано"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатке"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Титл уживо"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Желите да одблокирате камеру и микрофон уређаја?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пређи у апликацију здесна или испод док је подељен екран"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пређите у апликацију слева или изнад док користите подељени екран"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"У режиму подељеног екрана: замена једне апликације другом"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Премести активан прозор на следећи екран"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Унос"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Пређи на следећи језик"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Пређи на претходни језик"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Користите мањи број знакова од <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За већу резолуцију обрните телефон"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"затворено"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"отворено"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Притисните тастер да бисте доделили пречицу"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Претражите пречице"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Икона тастера за радњу или мета тастера"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Икона знака плус"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Прилагоди"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширивање"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер за превлачење"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Подешавања тастатуре"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Подеси пречицу"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притисните тастер"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбинација тастера се већ користи. Пробајте са другим тастером."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Крећите се помоћу тастатуре"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Сазнајте више о тастерским пречицама"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Крећите се помоћу тачпеда"</string>
@@ -1450,7 +1446,7 @@
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Превуците улево или удесно са три прста на тачпеду"</string>
- <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Свака част!"</string>
+ <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Супер!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Довршили сте покрет за повратак."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Иди на почетни екран"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Превуците нагоре са три прста на тачпеду"</string>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index 2a2e07459243..ec5f10f63e1a 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Искључено"</item>
<item msgid="3028994095749238254">"Укључено"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Недоступно"</item>
+ <item msgid="6419996398343291862">"Искључено"</item>
+ <item msgid="5908720590832378783">"Укључено"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index bffd40b6c5fe..c2ac21691aa1 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Ingång"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Hörapparater"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Aktiverar …"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Det går inte att justera ljusstyrkan eftersom den\n styrs av den översta appen"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotera automatiskt"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotera skärmen automatiskt"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Plats"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicka för att parkoppla en ny enhet"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Det gick inte att uppdatera förinställningen"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Förinställning"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Markerad"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktyg"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Anteckning"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vill du återaktivera enhetens mikrofon?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vill du återaktivera enhetens kamera?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vill du återaktivera enhetens kamera och mikrofon?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Det finns inga nya aviseringar"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Nu är dämpning av aviseringar på"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Enheten sänker volymen och minimerar aviseringar i upp till två minuter när du får för många aviseringar samtidigt."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Inaktivera"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås upp för att se äldre aviseringar"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Byt till appen till höger eller nedanför när du använder delad skärm"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Byt till appen till vänster eller ovanför när du använder delad skärm"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Med delad skärm: ersätt en app med en annan"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Flytta det aktiva fönstret mellan skärmar"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inmatning"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Byt till nästa språk"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Byt till föregående språk"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Använd färre än <xliff:g id="LENGTH">%1$d</xliff:g> tecken"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Konversationswidgetar"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Tryck på en konversation för att lägga till den på startskärmen"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vänd telefonen för högre upplösning"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"hopvikt"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"uppvikt"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Anpassa kortkommandon"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tryck på tangenten för att ange kortkommando"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Inga sökresultat"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon för åtgärdstangent"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassa"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handtag"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tangentbordsinställningar"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ange kortkommando"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Avbryt"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tryck på tangenten"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tangentkombinationen används redan. Testa en annan tangent."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigera med tangentbordet"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lär dig kortkommandon"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigera med styrplattan"</string>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index b72f404c710f..e9da8053759d 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Av"</item>
<item msgid="3028994095749238254">"På"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Inte tillgängligt"</item>
+ <item msgid="6419996398343291862">"Av"</item>
+ <item msgid="5908720590832378783">"På"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 2140a8ae06bb..3418907ea44c 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Vifaa vya kuingiza sauti"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Visaidizi vya kusikia"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Inawasha..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Imeshindwa kurekebisha mwangaza kwa sababu\n inadhibitiwa na programu inayotumika"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Zungusha kiotomatiki"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Skrini ijizungushe kiotomatiki"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Mahali"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Mipangilio iliyowekwa mapema"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Umechagua"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Zana"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Manukuu Papo Hapo"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Dokezo"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Ungependa kuwacha kuzuia kamera na maikrofoni ya kifaa?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Hakuna arifa mpya"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Mipangilio ya kutuliza arifa imewashwa"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Arifa na sauti hupunguzwa kiotomatiki kwenye kifaa chako kwa hadi dakika 2 unapopokea arifa nyingi kwa wakati mmoja."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Zima"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Fungua ili uone arifa za zamani"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Badilisha ili uende kwenye programu iliyo kulia au chini unapotumia hali ya kugawa skrini"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Badilisha uende kwenye programu iliyo kushoto au juu unapotumia hali ya kugawa skrini"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Ukigawanya skrini: badilisha kutoka programu moja hadi nyingine"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Hamisha dirisha linalotumika kati ya skrini moja na nyingine"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vifaa vya kuingiza data"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Badilisha utumie lugha inayofuata"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Badilisha utumie lugha iliyotangulia"</string>
@@ -1203,7 +1201,7 @@
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Spika na Skrini"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vifaa Vilivyopendekezwa"</string>
- <string name="media_input_group_title" msgid="2057057473860783021">"Vifaa vya kuingiza data"</string>
+ <string name="media_input_group_title" msgid="2057057473860783021">"Vifaa vya kuingiza maudhui"</string>
<string name="media_output_group_title" msgid="6789001895863332576">"Vifaa vya kutoa maudhui"</string>
<string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Simamisha kipindi unachoshiriki ili uhamishie maudhui kwenye kifaa kingine"</string>
<string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Simamisha"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Hupaswi kuzidi herufi <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Wijeti za mazungumzo"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Gusa mazungumzo ili uyaweke kwenye Skrini yako ya kwanza"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kwa ubora wa juu, geuza simu"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kimekunjwa"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kimefunguliwa"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,31 +1418,24 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Weka mapendeleo ya mikato ya kibodi"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Bonyeza kitufe ukabidhi njia ya mkato"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Njia mkato za kutafutia"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hamna matokeo ya utafutaji"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kunja aikoni"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Aikoni ya kitufe cha Vitendo au cha Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Aikoni ya alama ya kujumlisha"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Weka mapendeleo"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Nimemaliza"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Panua aikoni"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"au"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Aikoni ya buruta"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mipangilio ya Kibodi"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Weka njia ya mkato"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Acha"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Bonyeza kitufe"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tayari unatumia mchanganyiko huu wa vitufe. Jatibu kitufe kingine."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Kusogeza kwa kutumia kibodi yako"</string>
- <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Jifunze kuhusu mikato ya kibodi"</string>
+ <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Fahamu kuhusu mikato ya kibodi"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Kusogeza kwa kutumia padi yako ya kugusa"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Fahamu miguso ya padi ya kugusa"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Kusogeza kwa kutumia kibodi na padi yako ya kugusa"</string>
@@ -1452,7 +1447,7 @@
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Rudi nyuma"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Telezesha vidole vitatu kushoto au kulia kwenye padi yako ya kugusa"</string>
<string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Safi!"</string>
- <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Umekamilisha ishara ya kurudi nyuma."</string>
+ <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Umekamilisha mafunzo ya miguso ya kurudi nyuma."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Nenda kwenye skrini ya kwanza"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Telezesha vidole vitatu juu kwenye padi yako ya kugusa"</string>
<string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Kazi nzuri!"</string>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 4de75caf05ae..702af458652a 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Vimezimwa"</item>
<item msgid="3028994095749238254">"Vimewashwa"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Halipatikani"</item>
+ <item msgid="6419996398343291862">"Limezimwa"</item>
+ <item msgid="5908720590832378783">"Limewashwa"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 75bee9f9266a..055c3a641d1b 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -20,7 +20,6 @@
<!-- keyguard-->
<dimen name="keyguard_indication_margin_bottom">25dp</dimen>
<dimen name="ambient_indication_margin_bottom">115dp</dimen>
- <dimen name="lock_icon_margin_bottom">60dp</dimen>
<!-- margin from keyguard status bar to clock. For split shade it should be
keyguard_split_shade_top_margin - status_bar_header_height_keyguard = 8dp -->
<dimen name="keyguard_clock_top_margin">8dp</dimen>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 639bc394972a..99c912ca072a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -310,7 +310,7 @@
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"இணைப்பு நீக்கும்"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"செயல்படுத்தும்"</string>
- <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"தானாகவே நாளை இயக்கப்படும்"</string>
+ <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"தானாகவே நாளை இயங்குதல்"</string>
<string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்கள் புளூடூத்தைப் பயன்படுத்துகின்றன"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"நாளை காலை புளூடூத் இயக்கப்படும்"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ஆடியோவைப் பகிர்"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"உள்ளீடு"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"செவித்துணைக் கருவி"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ஆன் செய்கிறது…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"சிறந்த ஆப்ஸால் ஒளிர்வு கட்டுப்படுத்தப்படுவதால்\n இதைச் சரிசெய்ய முடியவில்லை"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"தானாகச் சுழற்று"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"திரையைத் தானாகச் சுழற்று"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"இருப்பிடம்"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"புதிய சாதனத்தை இணைக்க கிளிக் செய்யலாம்"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"முன்னமைவைப் புதுப்பிக்க முடியவில்லை"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"முன்னமைவு"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"தேர்ந்தெடுக்கப்பட்டது"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"கருவிகள்"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"உடனடி வசனம்"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"குறிப்பு"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"சாதனத்தின் மைக்ரோஃபோனுக்கான தடுப்பை நீக்கவா?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"சாதனத்தின் கேமராவுக்கான தடுப்பை நீக்கவா?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"சாதனத்தின் கேமராவுக்கும் மைக்ரோஃபோனுக்குமான தடுப்பை நீக்கவா?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது வலது/கீழ் உள்ள ஆப்ஸுக்கு மாறுதல்"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது இடது/மேலே உள்ள ஆப்ஸுக்கு மாறுதல்"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"திரைப் பிரிப்பின்போது: ஓர் ஆப்ஸுக்குப் பதிலாக மற்றொன்றை மாற்றுதல்"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"காட்சிகளுக்கு இடையே செயலில் உள்ள சாளரத்தை நகர்த்துதல்"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"உள்ளீடு"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"அடுத்த மொழிக்கு மாற்றுதல்"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"முந்தைய மொழிக்கு மாற்றுதல்"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> எழுத்துகளுக்குக் குறைவாகப் பயன்படுத்துங்கள்"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"உரையாடல் விட்ஜெட்டுகள்"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ஓர் உரையாடலை உங்கள் முகப்புத் திரையில் சேர்க்க அந்த உரையாடலைத் தட்டுங்கள்"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"உயர் தெளிவுத்திறனுக்கு, மொபைலை ஃபிளிப் செய்யுங்கள்"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"மடக்கப்பட்டது"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"விரிக்கப்பட்டது"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"கீபோர்டு ஷார்ட்கட்களைப் பிரத்தியேகப்படுத்துதல்"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"ஷார்ட்கட்டை அமைக்க பட்டனை அழுத்துங்கள்"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ஷார்ட்கட்களைத் தேடுக"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"தேடல் முடிவுகள் இல்லை"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"சுருக்குவதற்கான ஐகான்"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ஆக்‌ஷன்/மெட்டா பட்டன் ஐகான்"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"பிளஸ் ஐகான்"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"பிரத்தியேகப்படுத்தும்"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"முடிந்தது"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"விரிவாக்குவதற்கான ஐகான்"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"அல்லது"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"இழுப்பதற்கான ஹேண்டில்"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"கீபோர்டு அமைப்புகள்"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ஷார்ட்கட்டை அமையுங்கள்"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ரத்துசெய்"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"பட்டனை அழுத்துங்கள்"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"பட்டன் சேர்க்கை ஏற்கெனவே பயன்பாட்டில் உள்ளது. வேறொரு பட்டனைப் பயன்படுத்திப் பார்க்கவும்."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"கீபோர்டைப் பயன்படுத்திச் செல்லுதல்"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"கீபோர்டு ஷார்ட்கட்கள் குறித்துத் தெரிந்துகொள்ளுங்கள்"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"டச்பேடைப் பயன்படுத்திச் செல்லுதல்"</string>
@@ -1463,7 +1459,7 @@
<string name="tutorial_action_key_title" msgid="8172535792469008169">"அனைத்து ஆப்ஸையும் காட்டு"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"உங்கள் கீபோர்டில் ஆக்‌ஷன் பட்டனை அழுத்தவும்"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"அருமை!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸுக்கான சைகை பயிற்சியையும் நிறைவுசெய்துவிட்டீர்கள்"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸையும் பார்ப்பதற்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 66cdeec01991..17cc570f6b0d 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"முடக்கப்பட்டுள்ளது"</item>
<item msgid="3028994095749238254">"இயக்கப்பட்டுள்ளது"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"கிடைக்கவில்லை"</item>
+ <item msgid="6419996398343291862">"முடக்கப்பட்டுள்ளது"</item>
+ <item msgid="5908720590832378783">"இயக்கப்பட்டுள்ளது"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2834196437d5..5a088231c945 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ఇన్‌పుట్"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"వినికిడి పరికరాలు"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ఆన్ చేస్తోంది…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ఇది టాప్ యాప్ ద్వారా\n కంట్రోల్ చేయబడుతున్నందున బ్రైట్‌నెస్‌ను సర్దుబాటు చేయడం సాధ్యం కాదు"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ఆటో-రొటేట్‌"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"స్క్రీన్ ఆటో-రొటేట్‌"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"లొకేషన్"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"కొత్త పరికరాన్ని పెయిర్ చేయడానికి క్లిక్ చేయండి"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ప్రీసెట్‌ను అప్‌డేట్ చేయడం సాధ్యపడలేదు"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ప్రీసెట్"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ఎంచుకోబడింది"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"టూల్స్"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"లైవ్ క్యాప్షన్"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"గమనిక"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"పరికరం మైక్రోఫోన్‌ను అన్‌బ్లాక్ చేయమంటారా?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"పరికరంలోని కెమెరాను అన్‌బ్లాక్ చేయమంటారా?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"పరికరంలోని కెమెరా, మైక్రోఫోన్‌లను అన్‌బ్లాక్ చేయమంటారా?"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"ఆఫ్‌లో ఉంది"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"సెట్ చేసి లేదు"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"సెట్టింగ్‌లలో మేనేజ్ చేయండి"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{మోడ్స్ ఏవీ యాక్టివ్‌గా లేవు}=1{{mode} యాక్టివ్‌గా ఉంది}other{# మోడ్స్ యాక్టివ్‌గా ఉన్నాయి}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{యాక్టివ్ మోడ్స్ లేవు}=1{{mode} యాక్టివ్‌గా ఉంది}other{# మోడ్స్ యాక్టివ్‌గా ఉన్నాయి}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"మీరు పేర్కొనే అలారాలు, రిమైండర్‌లు, ఈవెంట్‌లు మరియు కాలర్‌ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"అలారాలు నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్‌లతో మీకు అంతరాయం కలగదు. మీరు ఇప్పటికీ సంగీతం, వీడియోలు మరియు గేమ్‌లతో సహా మీరు ప్లే చేయడానికి ఎంచుకున్నవి ఏవైనా వింటారు."</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"అనుకూలంగా మార్చండి"</string>
@@ -584,7 +584,7 @@
<string name="notification_settings_button_description" msgid="2441994740884163889">"నోటిఫికేషన్ సెట్టింగ్‌లు"</string>
<string name="notification_history_button_description" msgid="1578657591405033383">"నోటిఫికేషన్ హిస్టరీ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"కొత్తవి"</string>
- <string name="notification_section_header_gentle" msgid="6804099527336337197">"నిశ్శబ్దం"</string>
+ <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>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు కుడి లేదా కింద యాప్‌నకు మారండి"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు ఎడమ లేదా పైన యాప్‌నకు మారండి"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"స్ప్లిట్ స్క్రీన్ సమయంలో: ఒక దాన్నుండి మరో దానికి యాప్ రీప్లేస్ చేయండి"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"యాక్టివ్ విండోను డిస్‌ప్లేల మధ్య తరలించండి"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ఇన్‌పుట్"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"తర్వాత భాషకు స్విచ్ అవ్వండి"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"మునుపటి భాషకు స్విచ్ అవ్వండి"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> కంటే తక్కువ అక్షరాలను ఉపయోగించండి"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"సంభాషణ విడ్జెట్‌లు"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"ఏదైనా సంభాషణను మీ మొదటి స్క్రీన్‌కు జోడించడానికి దానిని ట్యాప్ చేయండి"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"అధిక రిజల్యూషన్ కోసం, ఫోన్‌ను తిప్పండి"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"మడిచే సదుపాయం గల పరికరం"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"మడిచే సదుపాయం లేని పరికరం"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,33 +1418,26 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్‌కట్‌లను అనుకూలంగా మార్చండి"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"షార్ట్‌కట్‌ను కేటాయించడానికి కీని నొక్కండి"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"షార్ట్‌కట్‌లను వెతకండి"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"యాక్షన్ లేదా మెటా కీ చిహ్నం"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ప్లస్ చిహ్నం"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"అనుకూలంగా మార్చండి"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"పూర్తయింది"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"విస్తరించండి చిహ్నం"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"లేదా"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"లాగే హ్యాండిల్"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"కీబోర్డ్ సెట్టింగ్‌లు"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"షార్ట్‌కట్‌ను సెట్ చేయండి"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"రద్దు చేయండి"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"కీని నొక్కండి"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"కీ కాంబినేషన్ ఇప్పటికే వినియోగంలో ఉంది. వేరొక కీని ట్రై చేయండి."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"మీ కీబోర్డ్ ఉపయోగించి నావిగేట్ చేయండి"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"కీబోర్డ్ షార్ట్‌కట్‌ల గురించి తెలుసుకోండి"</string>
- <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"మీ టచ్‌ప్యాడ్‌ని ఉపయోగించి నావిగేట్ చేయండి"</string>
- <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"టచ్‌ప్యాడ్ సంజ్ఞ గురించి తెలుసుకోండి"</string>
+ <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"మీ టచ్‌ప్యాడ్‌ను ఉపయోగించి నావిగేట్ చేయండి"</string>
+ <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"టచ్‌ప్యాడ్ సంజ్ఞల గురించి తెలుసుకోండి"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"మీ కీబోర్డ్, టచ్‌ప్యాడ్‌ను ఉపయోగించి నావిగేట్ చేయండి"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"టచ్‌ప్యాడ్ సంజ్ఞలు, కీబోర్డ్ షార్ట్‌కట్‌లు, అలాగే మరిన్నింటిని గురించి తెలుసుకోండి"</string>
<string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"వెనుకకు వెళ్లండి"</string>
@@ -1450,7 +1446,7 @@
<string name="touchpad_tutorial_done_button" msgid="176168488821755503">"పూర్తయింది"</string>
<string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"వెనుకకు"</string>
<string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి ఎడమ వైపునకు లేదా కుడి వైపునకు స్వైప్ చేయండి"</string>
- <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"పనితీరు బాగుంది!"</string>
+ <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"సూపర్!"</string>
<string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"తిరిగి వెనుకకు వెళ్ళడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు."</string>
<string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"మొదటి ట్యాబ్‌కు వెళ్లండి"</string>
<string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"మీ టచ్‌ప్యాడ్‌పై మూడు వేళ్లతో పైకి స్వైప్ చేయండి"</string>
@@ -1458,12 +1454,12 @@
<string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"మీరు మొదటి స్క్రీన్‌కు వెళ్లే సంజ్ఞను పూర్తి చేశారు"</string>
<string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ఇటీవలి యాప్‌లను చూడండి"</string>
<string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string>
- <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"పనితీరు అద్భుతంగా ఉంది!"</string>
- <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"మీరు ఇటీవలి యాప్‌ల వీక్షణ సంజ్ఞను పూర్తి చేశారు."</string>
+ <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"చక్కగా పూర్తి చేశారు!"</string>
+ <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ఇటీవలి యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు."</string>
<string name="tutorial_action_key_title" msgid="8172535792469008169">"అన్ని యాప్‌లను చూడండి"</string>
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"చక్కగా చేశారు!"</string>
- <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"మీరు అన్ని యాప్‌ల వీక్షణ సంజ్ఞను పూర్తి చేశారు"</string>
+ <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"అన్ని యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు"</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్‌లైట్"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 42ee13d8cc57..8a0ab4848f60 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ఆఫ్‌లో ఉంది"</item>
<item msgid="3028994095749238254">"ఆన్‌లో ఉంది"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"అందుబాటులో లేదు"</item>
+ <item msgid="6419996398343291862">"ఆఫ్‌లో ఉంది"</item>
+ <item msgid="5908720590832378783">"ఆన్‌లో ఉంది"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index fcfc4e2364e0..816514a9797f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"อินพุต"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"เครื่องช่วยฟัง"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"กำลังเปิด..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"ปรับความสว่างไม่ได้เนื่องจาก\nควบคุมโดยแอปที่อยู่ด้านบน"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"หมุนอัตโนมัติ"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"หมุนหน้าจออัตโนมัติ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ตำแหน่ง"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"คลิกเพื่อจับคู่อุปกรณ์ใหม่"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"ไม่สามารถอัปเดตค่าที่กำหนดล่วงหน้า"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"ค่าที่กำหนดล่วงหน้า"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"เลือกแล้ว"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"เครื่องมือ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"คำบรรยายสด"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"จดบันทึก"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"เลิกบล็อกไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"เลิกบล็อกกล้องของอุปกรณ์ใช่ไหม"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"เลิกบล็อกกล้องและไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
@@ -454,7 +454,7 @@
<string name="zen_mode_off" msgid="1736604456618147306">"ปิด"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"ไม่ได้ตั้งค่า"</string>
<string name="zen_mode_no_manual_invocation" msgid="1769975741344633672">"จัดการในการตั้งค่า"</string>
- <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ไม่มีโหมดที่ใช้งานอยู่}=1{ใช้งานอยู่ {mode} โหมด}other{ใช้งานอยู่ # โหมด}}"</string>
+ <string name="zen_mode_active_modes" msgid="1625850411578488856">"{count,plural, =0{ไม่มีโหมดที่ใช้งานอยู่}=1{{mode} ทำงานอยู่}other{ใช้งานอยู่ # โหมด}}"</string>
<string name="zen_priority_introduction" msgid="3159291973383796646">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก การช่วยเตือน กิจกรรม และผู้โทรที่ระบุไว้ คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
<string name="zen_alarms_introduction" msgid="3987266042682300470">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นเสียงนาฬิกาปลุก คุณจะยังคงได้ยินสิ่งที่คุณเลือกเล่น เช่น เพลง วิดีโอ และเกม"</string>
<string name="zen_priority_customize_button" msgid="4119213187257195047">"กำหนดค่า"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"เปลี่ยนไปใช้แอปทางด้านขวาหรือด้านล่างขณะใช้โหมดแยกหน้าจอ"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"เปลี่ยนไปใช้แอปทางด้านซ้ายหรือด้านบนขณะใช้โหมดแยกหน้าจอ"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"ระหว่างใช้โหมดแยกหน้าจอ: เปลี่ยนแอปหนึ่งเป็นอีกแอปหนึ่ง"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"ย้ายหน้าต่างที่ใช้งานไปยังหน้าจอต่างๆ"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"อินพุต"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"เปลี่ยนเป็นภาษาถัดไป"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"เปลี่ยนเป็นภาษาก่อนหน้า"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"ใช้อักขระไม่เกิน <xliff:g id="LENGTH">%1$d</xliff:g> ตัว"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"วิดเจ็ตการสนทนา"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"แตะการสนทนาเพื่อเพิ่มไปยังหน้าจอหลัก"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"พลิกด้านโทรศัพท์เพื่อให้ได้ภาพที่มีความละเอียดมากขึ้น"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"พับ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"กางออก"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"กดแป้นเพื่อกำหนดแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ไอคอนการดำเนินการหรือแป้น Meta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ไอคอนเครื่องหมายบวก"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ปรับแต่ง"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"เสร็จสิ้น"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ไอคอนขยาย"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"หรือ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"แฮนเดิลการลาก"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"การตั้งค่าแป้นพิมพ์"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ตั้งค่าแป้นพิมพ์ลัด"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ยกเลิก"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"กดแป้น"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"มีการใช้แป้นที่กดร่วมกันนี้แล้ว โปรดลองใช้แป้นอื่น"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ไปยังส่วนต่างๆ โดยใช้แป้นพิมพ์"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ดูข้อมูลเกี่ยวกับแป้นพิมพ์ลัด"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ไปยังส่วนต่างๆ โดยใช้ทัชแพด"</string>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index d249057be4da..4db59c0677c4 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"ปิด"</item>
<item msgid="3028994095749238254">"เปิด"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"ไม่พร้อมใช้งาน"</item>
+ <item msgid="6419996398343291862">"ปิด"</item>
+ <item msgid="5908720590832378783">"เปิด"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 68cc6d2fb872..3845fcd314a4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Input"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Mga hearing aid"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Ino-on…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Hindi ma-adjust ang liwanag dahil\n kinokontrol ito ng nangingibabaw na app"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"I-auto rotate"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Awtomatikong i-rotate ang screen"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasyon"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"I-click para magpares ng bagong device"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hindi ma-update ang preset"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Napili"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Mga Tool"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Instant Caption"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Tala"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"I-unblock ang mikropono ng device?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"I-unblock ang camera ng device?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"I-unblock ang camera at mikropono ng device?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Lumipat sa app sa kanan o ibaba habang ginagamit ang split screen"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Lumipat sa app sa kaliwa o itaas habang ginagamit ang split screen"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Habang nasa split screen: magpalit-palit ng app"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Ilipat ang aktibong window sa pagitan ng mga display"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Lumipat sa susunod na wika"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Lumipat sa dating wika"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Gumamit ng mas kaunti sa <xliff:g id="LENGTH">%1$d</xliff:g> (na) character"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Mga widget ng pag-uusap"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Mag-tap sa isang pag-uusap para idagdag ito sa iyong Home screen"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para sa mas mataas na resolution, i-flip ang telepono"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"naka-fold"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"hindi naka-fold"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Pindutin ang key para magtalaga ng shortcut"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Icon ng Action o Meta key"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Icon na plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"I-customize"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tapos na"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"I-expand ang icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handle sa pag-drag"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mga Setting ng Keyboard"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Magtakda ng shortcut"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselahin"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pindutin ang key"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Ginagamit na ang kumbinasyon ng key. Sumubok ng ibang key."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Mag-navigate gamit ang iyong keyboard"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Matuto ng mga keyboard shortcut"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Mag-navigate gamit ang iyong touchpad"</string>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 0e43fafd1a04..4832d1d1b0de 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Naka-off"</item>
<item msgid="3028994095749238254">"Naka-on"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Hindi available"</item>
+ <item msgid="6419996398343291862">"Naka-off"</item>
+ <item msgid="5908720590832378783">"Naka-on"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index fd4bb451f024..45d8b4605c29 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -111,7 +111,7 @@
<string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekranınız kaydedilsin mi?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir uygulamayı kaydet"</string>
- <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydedin"</string>
+ <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydet"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tüm ekranı kaydet: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Tüm ekranınızı kaydettiğinizde ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Bir uygulamayı kaydettiğinizde o uygulamada gösterilen veya oynatılan her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
@@ -311,7 +311,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"bağlantıyı kes"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"etkinleştir"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Yarın otomatik olarak aç"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır"</string>
+ <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır."</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth yarın sabah açılacak"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sesi paylaş"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ses paylaşılıyor"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Giriş"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"İşitme cihazları"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Açılıyor…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Parlaklık ayarlanamıyor, çünkü bu özellik\n en üstteki uygulama tarafından kontrol ediliyor"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Otomatik döndür"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranı otomatik döndür"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Konum"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz eşlemek için tıklayın"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncellenemedi"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçili"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Araçlar"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Not"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonunun engellemesi kaldırılsın mı?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerasının engellemesi kaldırılsın mı?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası ile mikrofonunun engellemesi kaldırılsın mı?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildirim yok"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Bildirim şiddetini düşürme etkin"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Aynı anda çok sayıda bildirim aldığınızda 2 dakika boyunca otomatik olarak cihazınızın sesi kısılır ve uyarıları azaltılır."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Kapat"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eski bildirimler için kilidi açın"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yap"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran kullanırken soldaki veya üstteki uygulamaya geçiş yapın"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Etkin pencereyi ekranlar arasında taşıma"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Giriş"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Sonraki dile geç"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Önceki dile geç"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"En fazla <xliff:g id="LENGTH">%1$d</xliff:g> karakter kullanın"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Görüşme widget\'ları"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Ana ekranınıza eklemek için bir görüşmeye dokunun"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksek çözünürlük için telefonu çevirin"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"katlanmış"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"katlanmamış"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klavye kısayollarını özelleştirin"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Kısayol atamak için tuşa basın"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Arama sonucu yok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"İşlem veya Meta tuşu simgesi"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Artı simgesi"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Özelleştir"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Bitti"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Genişlet simgesi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"veya"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sürükleme tutamacı"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klavye Ayarları"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Kısayol ayarla"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"İptal"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tuşa basın"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tuş kombinasyonu zaten kullanılıyor. Başka bir tuş deneyin."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klavyenizi kullanarak gezinin"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klavye kısayollarını öğrenin"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Dokunmatik alanınızı kullanarak gezinin"</string>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 1e30c6d3a5c1..1c0c110baab1 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Kapalı"</item>
<item msgid="3028994095749238254">"Açık"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Yok"</item>
+ <item msgid="6419996398343291862">"Kapalı"</item>
+ <item msgid="5908720590832378783">"Açık"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index ab5f8a42697a..4c4c80ea31a3 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -311,7 +311,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"від’єднати"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"активувати"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Автоматично ввімкнути завтра"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як швидкий обмін і \"Знайти пристрій\", використовують Bluetooth"</string>
+ <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як \"Швидкий обмін\" і \"Знайти пристрій\", використовують Bluetooth"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth увімкнеться завтра вранці"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Поділитись аудіо"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Надсилання аудіо"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Джерело сигналу"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Слухові апарати"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Увімкнення…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Не вдається змінити яскравість, оскільки\n нею керує основний додаток"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автообертання"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично обертати екран"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Геодані"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Натисніть, щоб підключити новий пристрій"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Не вдалось оновити набір налаштувань"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набір налаштувань"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Вибрано"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменти"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Живі субтитри"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нотатка"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Надати доступ до камери пристрою?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Надати доступ до камери й мікрофона?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Немає нових сповіщень"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Зниження гучності сповіщень увімкнено"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Коли ви отримуєте забагато сповіщень за раз, пристрій автоматично знижує їх гучність і кількість на період до 2 хвилин."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Вимкнути"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Розблокуйте, щоб переглянути старіші"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти до додатка праворуч або внизу на розділеному екрані"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Під час розділення екрана перемикатися на додаток ліворуч або вгорі"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Перемістити активне вікно між дисплеями"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Метод введення"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Вибрати наступну мову"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Вибрати попередню мову"</string>
@@ -1203,8 +1201,8 @@
<string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
<string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки й екрани"</string>
<string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Пропоновані пристрої"</string>
- <string name="media_input_group_title" msgid="2057057473860783021">"Введення"</string>
- <string name="media_output_group_title" msgid="6789001895863332576">"Виведення"</string>
+ <string name="media_input_group_title" msgid="2057057473860783021">"Ввід"</string>
+ <string name="media_output_group_title" msgid="6789001895863332576">"Вивід"</string>
<string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Зупиніть сеанс спільного доступу, щоб перенести медіаконтент на інший пристрій"</string>
<string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Зупинити"</string>
<string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Кількість символів має бути менше ніж <xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Віджети розмов"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Натисніть розмову, щоб додати її на головний екран"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Для вищої роздільної здатності переверніть телефон"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"складений"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"розкладений"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Налаштуйте комбінації клавіш"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Натисніть клавішу, щоб призначити комбінацію клавіш"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Комбінації клавіш для пошуку"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нічого не знайдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок згортання"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Значок клавіші дії або метаклавіші"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Значок \"плюс\""</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Налаштувати"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Готово"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок розгортання"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер переміщення"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налаштування клавіатури"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Налаштувати комбінацію клавіш"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасувати"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Натисніть клавішу"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Комбінація клавіш уже використовується. Спробуйте іншу клавішу."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігація за допомогою клавіатури"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Дізнайтеся більше про комбінації клавіш"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігація за допомогою сенсорної панелі"</string>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 6c03aea7b3af..656ccd439244 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Вимкнено"</item>
<item msgid="3028994095749238254">"Увімкнено"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Недоступно"</item>
+ <item msgid="6419996398343291862">"Вимкнено"</item>
+ <item msgid="5908720590832378783">"Увімкнено"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 39aa5d1ccfcc..109f43eb5632 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ان پٹ"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"سماعتی آلات"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"آن ہو رہا ہے…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"چمک کو ایڈجسٹ نہیں کیا جا سکتا کیونکہ اسے سرفہرست ایپ کے ذریعے \n کنٹرول کیا جا رہا ہے"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"خود کار طور پر گھمائیں"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"اسکرین کو خود کار طور پر گھمائیں"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"مقام"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"نئے آلے کا جوڑا بنانے کے لیے کلک کریں"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"پہلے سے ترتیب شدہ کو اپ ڈیٹ نہیں کیا جا سکا"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"پہلے سے ترتیب شدہ"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"منتخب کردہ"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ٹولز"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"لائیو کیپشن"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"نوٹ"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"آلے کا مائیکروفون غیر مسدود کریں؟"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"آلے کا کیمرا غیر مسدود کریں؟"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"آلے کا کیمرا اور مائیکروفون غیر مسدود کریں؟"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"کوئی اطلاعات نہیں ہیں"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"کوئی نئی اطلاعات نہیں"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"ںوٹیفیکیشن کول ڈاؤن اب آن ہے"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"جب آپ کو ایک ساتھ بہت زیادہ اطلاعات موصول ہوتی ہیں تو آپ کے آلے کا والیوم اور الرٹس خودکار طور پر 2 منٹ تک کم ہو جاتے ہیں۔"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"آف کریں"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"پرانی اطلاعات دیکھنے کیلئے غیر مقفل کریں"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"اسپلٹ اسکرین کا استعمال کرتے ہوئے دائیں یا نیچے ایپ پر سوئچ کریں"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"اسپلٹ اسکرین کا استعمال کرتے ہوئے بائیں یا اوپر ایپ پر سوئچ کریں"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"اسپلٹ اسکرین کے دوران: ایک ایپ کو دوسرے سے تبدیل کریں"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"فعال ونڈو کو ڈسپلیز کے مابین منتقل کریں"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ان پٹ"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"اگلی زبان پر سوئچ کریں"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"پچھلی زبان پر سوئچ کریں"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"<xliff:g id="LENGTH">%1$d</xliff:g> حروف سے کم استعمال کریں"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"گفتگو ویجیٹس"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"اسے اپنی ہوم اسکرین پر شامل کرنے کے لیے گفتگو پر تھپتھپائیں"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"زیادہ ریزولوشن کے لیے، فون پلٹائیں"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"فولڈ کردہ"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"اَن فولڈ کردہ"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"شارٹ کٹ تفویض کرنے کے لیے کلید کو دبائیں"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"‏کارروائی یا Meta کلید کا آئیکن"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"پلس کا آئیکن"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"حسب ضرورت بنائیں"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ہو گیا"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"آئیکن پھیلائیں"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"گھسیٹنے کا ہینڈل"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"کی بورڈ کی ترتیبات"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"شارٹ کٹ سیٹ کریں"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"منسوخ کریں"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید کو دبائیں"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"کلیدی مجموعہ پہلے سے استعمال میں ہے۔ دوسری کلید آزمائیں۔"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"اپنے کی بورڈ کا استعمال کر کے نیویگیٹ کریں"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"کی بورڈ شارٹ کٹس جانیں"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"اپنے ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں"</string>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index a213f00e496d..4aa490d927b1 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"آف ہے"</item>
<item msgid="3028994095749238254">"آن ہے"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"دستیاب نہیں ہے"</item>
+ <item msgid="6419996398343291862">"آف"</item>
+ <item msgid="5908720590832378783">"آن"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 67cc8b638a92..1c27a0055cce 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -114,7 +114,7 @@
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Butun ekranni yozib olish"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Butun ekranni yozib olish: %s"</string>
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Butun ekranni yozib olishda ekranda koʻrsatilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
- <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilova koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
+ <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilovada koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranni yozib olish"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"Yozib olinadigan ilovani tanlash"</string>
<string name="screenrecord_audio_label" msgid="6183558856175159629">"Audio yozib olish"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Kirish"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Eshitish moslamalari"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Yoqilmoqda…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Yorqinlik umumiy sozlamalar orqali boshqariladi.\nUni moslash imkonsiz"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avto-burilish"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranning avtomatik burilishi"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Andoza"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Tanlangan"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Vositalar"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Jonli izoh"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qayd"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Qurilma kamerasi va mikrofoni blokdan chiqarilsinmi?"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ajratilgan ekranda oʻngdagi yoki pastdagi ilovaga almashish"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ajratilgan ekranda chapdagi yoki yuqoridagi ilovaga almashish"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Faol oynani ekranlararo koʻchirish"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Kiritish"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Keyingi tilga almashtirish"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Avvalgi tilga almashtirish"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Kiritiladigan belgilar <xliff:g id="LENGTH">%1$d</xliff:g> tadan oshmasin"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Suhbat vidjetlari"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Bosh ekranga chiqariladigan suhbat ustiga bosing"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Yuqori aniqlik uchun telefonni aylantiring"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"buklangan"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"buklanmagan"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Tezkor tugma sozlash uchun tugmani bosing"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Amal bajarish uchun Meta tugmasi belgisi"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus belgisi"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Moslash"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tayyor"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Surish dastagi"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura sozlamalari"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tezkor tugma sozlash"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Bekor qilish"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tugmani bosing"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Bu tugmalar birikmasi band. Boshqasini ishlating."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviatura yordamida kezing"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tezkor tugmalar haqida"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Sensorli panel yordamida kezing"</string>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 5e6611c3c1d5..1c32e9fbd53b 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Oʻchiq"</item>
<item msgid="3028994095749238254">"Yoniq"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Mavjud emas"</item>
+ <item msgid="6419996398343291862">"Yoqilmagan"</item>
+ <item msgid="5908720590832378783">"Yoniq"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 6752ceb27e97..d8e3bc0c1ffd 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Thiết bị đầu vào"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Thiết bị trợ thính"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Đang bật…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Không điều chỉnh được độ sáng vì độ sáng đang được\n ứng dụng trên cùng điều khiển"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Tự động xoay"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Tự động xoay màn hình"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Vị trí"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Nhấp để ghép nối thiết bị mới"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Không cập nhật được giá trị đặt trước"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Chế độ đặt sẵn"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Đã chọn"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Công cụ"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Phụ đề trực tiếp"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ghi chú"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Bỏ chặn micrô của thiết bị?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn camera của thiết bị?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Bỏ chặn máy ảnh và micrô của thiết bị?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Không có thông báo mới"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Chế độ Giảm dần âm lượng thông báo đang bật"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Khi bạn nhận quá nhiều thông báo cùng lúc, âm lượng và cảnh báo tự động giảm trong tối đa 2 phút."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Tắt"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Mở khoá để xem thông báo cũ"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Chuyển sang ứng dụng bên phải hoặc ở dưới khi đang chia đôi màn hình"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Chuyển sang ứng dụng bên trái hoặc ở trên khi đang chia đôi màn hình"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Trong chế độ chia đôi màn hình: thay một ứng dụng bằng ứng dụng khác"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Di chuyển cửa sổ đang hoạt động giữa các màn hình"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Đầu vào"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Chuyển sang ngôn ngữ tiếp theo"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Chuyển về ngôn ngữ trước"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Hãy dùng ít hơn <xliff:g id="LENGTH">%1$d</xliff:g> ký tự"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Tiện ích trò chuyện"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Nhấn vào một cuộc trò chuyện để thêm cuộc trò chuyện đó vào Màn hình chính"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Để có độ phân giải cao hơn, hãy lật điện thoại"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"gập"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"mở"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tuỳ chỉnh phím tắt"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Nhấn phím để chỉ định phím tắt"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tìm lối tắt"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Không có kết quả tìm kiếm nào"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Biểu tượng Thu gọn"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Biểu tượng phím Meta (phím hành động)"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Biểu tượng dấu cộng"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Tuỳ chỉnh"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Xong"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Biểu tượng Mở rộng"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"hoặc"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Nút kéo"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Cài đặt bàn phím"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Đặt phím tắt"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Huỷ"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Nhấn phím"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Tổ hợp phím đã được sử dụng. Hãy thử một phím khác."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Di chuyển bằng bàn phím"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tìm hiểu về phím tắt"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Di chuyển bằng bàn di chuột"</string>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 8aa360bbeaf7..466eb3d6017c 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Đang tắt"</item>
<item msgid="3028994095749238254">"Đang bật"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Không có"</item>
+ <item msgid="6419996398343291862">"Đang tắt"</item>
+ <item msgid="5908720590832378783">"Đang bật"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6e76bb7dbe4e..d9a974aad94a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -311,7 +311,7 @@
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"断开连接"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"启用"</string>
<string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"明天自动开启"</string>
- <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"快速分享、查找我的设备等功能会使用蓝牙"</string>
+ <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"“快速分享”“查找我的设备”等功能会使用蓝牙"</string>
<string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"蓝牙将在明天早上开启"</string>
<string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音频"</string>
<string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"正在分享音频"</string>
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"输入"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助听器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"正在开启…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"亮度无法调整,因为它正在被\n顶层应用控制"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自动屏幕旋转"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自动旋转屏幕"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"位置信息"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"点击即可与新设备配对"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"无法更新预设"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"预设"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已选择"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"实时字幕"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"记事"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解锁设备麦克风吗?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解锁设备摄像头吗?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解锁设备摄像头和麦克风吗?"</string>
@@ -449,7 +449,7 @@
<string name="zen_modes_dialog_title" msgid="8854640808100096934">"模式"</string>
<string name="zen_modes_dialog_done" msgid="6654130880256438950">"完成"</string>
<string name="zen_modes_dialog_settings" msgid="2310248023728936697">"设置"</string>
- <string name="zen_mode_on" msgid="9085304934016242591">"开启"</string>
+ <string name="zen_mode_on" msgid="9085304934016242591">"已开启"</string>
<string name="zen_mode_on_with_details" msgid="7416143430557895497">"已开启 • <xliff:g id="TRIGGER_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="zen_mode_off" msgid="1736604456618147306">"已关闭"</string>
<string name="zen_mode_set_up" msgid="8231201163894922821">"未设置"</string>
@@ -871,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分屏模式时,切换到右侧或下方的应用"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分屏模式时,切换到左侧或上方的应用"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"在分屏期间:将一个应用替换为另一个应用"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"在各个显示屏之间移动活动窗口"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"输入"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"切换到下一种语言"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"切换到上一种语言"</string>
@@ -1221,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"必须少于 <xliff:g id="LENGTH">%1$d</xliff:g> 个字符"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build 号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已将 Build 号复制到剪贴板。"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"对话微件"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"点按对话即可将其添加到主屏幕"</string>
@@ -1356,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"若要获得更高的分辨率,请翻转手机"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"折叠状态"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"展开状态"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1415,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按下按键即可指定快捷键"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"操作键或元键图标"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"加号图标"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自定义"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展开图标"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖动手柄"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"键盘设置"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"设置快捷键"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按键"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"按键组合已被使用,请尝试使用其他按键。"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用键盘导航"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"了解键盘快捷键"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用触控板导航"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 2259076341cf..65415f615ceb 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"已关闭"</item>
<item msgid="3028994095749238254">"已开启"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"不可用"</item>
+ <item msgid="6419996398343291862">"关闭"</item>
+ <item msgid="5908720590832378783">"开启"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 32fe2a100b69..443b8556fe18 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"輸入"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助聽器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"正在開啟…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"無法調整亮度,因為\n目前是由上層應用程式控制亮度"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"位置"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"㩒一下就可以配對新裝置"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"揀咗"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解除封鎖裝置相機和麥克風嗎?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"通知緩和功能現已啟用"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"當你在短時間內收到太多通知時,裝置就會調低音量並減少通知數量最多兩分鐘。"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割螢幕時,切換至右邊或下方的應用程式"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割螢幕時,切換至左邊或上方的應用程式"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割螢幕期間:更換應用程式"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"在不同畫面間移動使用中的視窗"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"輸入"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"切換至下一個語言"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換至上一個語言"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"請使用少於 <xliff:g id="LENGTH">%1$d</xliff:g> 個字元"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"輕按對話即可新增至主畫面"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解像度,請切換至手機後置鏡頭"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已打開"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按鍵即可指派快速鍵"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"沒有相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"快捷操作鍵或修飾鍵圖示"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"加號圖示"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自訂"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"鍵盤設定"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"設定快速鍵"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按鍵"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"此按鍵組合已在使用,請改用其他按鍵。"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤導覽"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"瞭解鍵盤快速鍵"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板導覽"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index c5e05c91e5f1..0882be746b06 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"關閉"</item>
<item msgid="3028994095749238254">"開啟"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"無法使用"</item>
+ <item msgid="6419996398343291862">"關閉"</item>
+ <item msgid="5908720590832378783">"開啟"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9778e7022725..4b84f25fca1b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"輸入"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"助聽器"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"開啟中…"</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"無法調整亮度,因為\n目前是由上層應用程式控制亮度"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"定位"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"按一下即可配對新裝置"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設設定"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已選取"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"解除封鎖裝置相機?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要將裝置的相機和麥克風解除封鎖嗎?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"「通知冷卻」設定已開啟"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"如果一次收到過多通知,裝置就會自動降低音量並減少通知數量,持續時間最多 2 分鐘。"</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割畫面時,切換到右邊或上方的應用程式"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割畫面時,切換到左邊或上方的應用程式"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割畫面期間:更換應用程式"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"在不同畫面間移動使用中的視窗"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"輸入"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"切換到下一個語言"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換到上一個語言"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"不得超過 <xliff:g id="LENGTH">%1$d</xliff:g> 個半形字元"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"輕觸對話即可新增至主畫面"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解析度,請切換至手機後置鏡頭"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"已摺疊"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"已展開"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"按下按鍵即可指派快速鍵"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"找不到相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"快捷操作鍵或修飾鍵圖示"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"加號圖示"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"自訂"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完成"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"鍵盤設定"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"設定快速鍵"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按鍵"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"這個按鍵組合已在使用中,請改用其他按鍵。"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤操作"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"學習鍵盤快速鍵"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板操作"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 2d34b380af52..f94b0449c598 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"已關閉"</item>
<item msgid="3028994095749238254">"已開啟"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"無法使用"</item>
+ <item msgid="6419996398343291862">"關閉"</item>
+ <item msgid="5908720590832378783">"開啟"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9f8cf1fe2610..4afb67d2af8f 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -326,8 +326,7 @@
<string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Okokufaka"</string>
<string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Imishini yendlebe"</string>
<string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Iyavula..."</string>
- <!-- no translation found for quick_settings_brightness_unable_adjust_msg (786478497970492300) -->
- <skip />
+ <string name="quick_settings_brightness_unable_adjust_msg" msgid="786478497970492300">"Ayikwazi ukulungisa ukukhanya ngoba ilawulwa\n yi-app ephezulu"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ukuphenduka okuzenzakalelayo"</string>
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Phendula iskrini ngokuzenzakalela"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Indawo"</string>
@@ -415,9 +414,10 @@
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Chofoza ukuze ubhangqe idivayisi entsha"</string>
<string name="hearing_devices_presets_error" msgid="350363093458408536">"Ayikwazanga ukubuyekeza ukusetha ngaphambilini"</string>
<string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ukusetha ngaphambilini"</string>
+ <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Okukhethiwe"</string>
+ <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Amathuluzi"</string>
<string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okushuthwe Bukhoma"</string>
- <!-- no translation found for quick_settings_notes_label (1028004078001002623) -->
- <skip />
+ <string name="quick_settings_notes_label" msgid="1028004078001002623">"Inothi"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vulela imakrofoni yedivayisi?"</string>
<string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vulela ikhamera yedivayisi?"</string>
<string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vulela ikhamera yedivayisi nemakrofoni?"</string>
@@ -593,8 +593,7 @@
<string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
<string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
<string name="no_unseen_notif_text" msgid="395512586119868682">"Azikho izaziso ezintsha"</string>
- <!-- no translation found for adaptive_notification_edu_hun_title (2594042455998795122) -->
- <skip />
+ <string name="adaptive_notification_edu_hun_title" msgid="2594042455998795122">"Ukwehlisa umsindo wezaziso manje kuvuliwe"</string>
<string name="adaptive_notification_edu_hun_text" msgid="7743367744129536610">"Ivolumu yedivayisi yakho kanye nezexwayiso kuncishiswa ngokuzenzakalelayo imizuzu efika kwemi-2 lapho uthola izaziso eziningi kakhulu ngesikhathi esisodwa."</string>
<string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vala"</string>
<string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vula ukuze ubone izaziso ezindala"</string>
@@ -872,8 +871,7 @@
<string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Shintshela ku-app ngakwesokudla noma ngezansi ngenkathi usebenzisa uhlukanisa isikrini"</string>
<string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Shintshela ku-app ngakwesokunxele noma ngaphezulu ngenkathi usebenzisa ukuhlukanisa isikrini"</string>
<string name="system_multitasking_replace" msgid="7410071959803642125">"Ngesikhathi sokuhlukaniswa kwesikrini: shintsha i-app ngenye"</string>
- <!-- no translation found for system_multitasking_move_to_next_display (6169737557526976997) -->
- <skip />
+ <string name="system_multitasking_move_to_next_display" msgid="6169737557526976997">"Hambisa iwindi elisebenzayo phakathi kwezibonisi"</string>
<string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Okokufaka"</string>
<string name="input_switch_input_language_next" msgid="3782155659868227855">"Shintshela olimini olulandelayo"</string>
<string name="input_switch_input_language_previous" msgid="6043341362202336623">"Shintshela olimini lwangaphambili"</string>
@@ -1222,6 +1220,8 @@
<string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"Sebenzisa isinhlamvu ezimbalwa kuneziyi-<xliff:g id="LENGTH">%1$d</xliff:g>"</string>
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
+ <!-- no translation found for copy_to_clipboard_a11y_action (4312789069718446749) -->
+ <skip />
<string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Amawijethi wengxoxo"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Thepha ingxoxo ukuyengeza Kusikrini sakho sasekhaya"</string>
@@ -1357,6 +1357,8 @@
<string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ukuze uthole ukulungiswa okuphezulu, phendula ifoni"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
+ <!-- no translation found for rear_display_unfolded_front_screen_on (5946436677205643170) -->
+ <skip />
<string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"kugoqiwe"</string>
<string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"kuvuliwe"</string>
<string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
@@ -1416,29 +1418,22 @@
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Hlela izinqamuleli zekhibhodi ngendlela oyifisayo"</string>
- <!-- no translation found for shortcut_helper_customize_mode_sub_title (2479732335876820286) -->
- <skip />
+ <string name="shortcut_helper_customize_mode_sub_title" msgid="2479732335876820286">"Cindezela ukhiye ukuze unikeze isinqamuleli"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sesha izinqamuleli"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ayikho imiphumela yosesho"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Goqa isithonjana"</string>
- <!-- no translation found for shortcut_helper_content_description_meta_key (3989315044342124818) -->
- <skip />
- <!-- no translation found for shortcut_helper_content_description_plus_icon (6152683734278299020) -->
- <skip />
+ <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Isithonjana sesenzo noma seMeta"</string>
+ <string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Isithonjana sesengezo"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Enza ngendlela oyifisayo"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Kwenziwe"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Nweba isithonjana"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"noma"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Hudula isibambi"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Amasethingi Ekhibhodi"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_set_shortcut_button_label (4754492225010429382) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_cancel_button_label (5595546460431741178) -->
- <skip />
- <!-- no translation found for shortcut_helper_add_shortcut_dialog_placeholder (9154297849458741995) -->
- <skip />
- <!-- no translation found for shortcut_helper_customize_dialog_error_message (5954264095841845768) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Setha isinqamuleli"</string>
+ <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Khansela"</string>
+ <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Cindezela ukhiye"</string>
+ <string name="shortcut_helper_customize_dialog_error_message" msgid="5954264095841845768">"Inhlanganisela yokhiye isiyasetshenziswa kakade. Zama omunye ukhiye."</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Funa usebenzisa ikhibhodi yakho"</string>
<string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Funda izinqamuleli zamakhibhodi"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Funa usebenzisa iphedi yokuthinta"</string>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index 1a7ce57601e3..be5c6d89b03c 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -191,7 +191,9 @@
<item msgid="3079622119444911877">"Kuvaliwe"</item>
<item msgid="3028994095749238254">"Kuvuliwe"</item>
</string-array>
- <!-- no translation found for tile_states_notes:0 (5894333929299989301) -->
- <!-- no translation found for tile_states_notes:1 (6419996398343291862) -->
- <!-- no translation found for tile_states_notes:2 (5908720590832378783) -->
+ <string-array name="tile_states_notes">
+ <item msgid="5894333929299989301">"Ayitholakali"</item>
+ <item msgid="6419996398343291862">"Valiwe"</item>
+ <item msgid="5908720590832378783">"Vuliwe"</item>
+ </string-array>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 48af82ad7943..42e909244f84 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -506,6 +506,12 @@
icon will be shown. -->
<string name="config_screenshotFilesApp" translatable="false"></string>
+ <!-- Recommends a UI mode for the default note-taking app when launched with
+ android.content.Intent#ACTION_CREATE_NOTE
+ 0: No UI recommendation. The note app should use its default mode
+ 1: Recommend a UI optimized for stylus input. -->
+ <integer name="config_preferredNotesMode">1</integer>
+
<!-- The component name of the screenshot editing activity that provides the App Clips flow.
The App Clips flow includes taking a screenshot, showing user screenshot cropping activity
and finally letting user send the screenshot to the calling notes app. This activity
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 580f6d302b37..411f36b73802 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -368,6 +368,9 @@
<!-- The vertical space between items in the alert selections in the inline settings -->
<dimen name="notification_guts_option_vertical_padding">16dp</dimen>
+ <!-- Extra space for guts bundle feedback button -->
+ <dimen name="notification_guts_bundle_feedback_size">48dp</dimen>
+
<dimen name="notification_importance_toggle_size">48dp</dimen>
<dimen name="notification_importance_button_separation">8dp</dimen>
<dimen name="notification_importance_drawable_padding">8dp</dimen>
@@ -948,7 +951,6 @@
<dimen name="keyguard_translate_distance_on_swipe_up">-200dp</dimen>
<dimen name="keyguard_indication_margin_bottom">32dp</dimen>
- <dimen name="lock_icon_margin_bottom">74dp</dimen>
<dimen name="ambient_indication_margin_bottom">71dp</dimen>
@@ -2057,6 +2059,9 @@
<!-- UDFPS view attributes -->
<!-- UDFPS icon size in microns/um -->
<dimen name="udfps_icon_size" format="float">6000</dimen>
+ <!-- Limits the updates to at most one update per debounce duration to avoid too many
+ updates due to quick changes to padding. -->
+ <integer name="udfps_padding_debounce_duration">100</integer>
<!-- Microns/ums (1000 um = 1mm) per pixel for the given device. If unspecified, UI that
relies on this value will not be sized correctly. -->
<item name="pixel_pitch" format="float" type="dimen">-1</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 245ba0aca876..3dd49bfed385 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1336,6 +1336,10 @@
<string name="communal_widgets_disclaimer_text">To open an app using a widget, you\u2019ll need to verify it\u2019s you. Also, keep in mind that anyone can view them, even when your tablet\u2019s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here.</string>
<!-- Button for user to verify they understand the information presented. [CHAR LIMIT=50] -->
<string name="communal_widgets_disclaimer_button">Got it</string>
+ <!-- Lockscreen affordance to open glanceable hub. [CHAR LIMIT=20] -->
+ <string name="glanceable_hub_lockscreen_affordance_label">Widgets</string>
+ <!-- Text explaining that the glanceable hub affordance is disabled. [CHAR LIMIT=NONE] -->
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text">To add Widgets on the lock screen as a shortcut, make sure it is enabled in settings.</string>
<!-- Related to user switcher --><skip/>
@@ -2034,6 +2038,9 @@
<!-- Text shown in notification guts for conversation notifications that don't implement the full feature -->
<string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> doesn\u2019t support conversation features</string>
+ <!-- [CHAR LIMIT=80] Text shown in feedback button in notification guts for a bundled notification -->
+ <string name="notification_guts_bundle_feedback">Provide Bundle Feedback</string>
+
<!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
<string name="notification_unblockable_desc">These notifications can\'t be modified.</string>
@@ -3214,6 +3221,9 @@
<!-- Text to display when copying the build number off QS [CHAR LIMIT=NONE]-->
<string name="build_number_copy_toast">Build number copied to clipboard.</string>
+ <!-- Text for accessibility action for copying content to clipboard [CHAR LIMIT=NONE]-->
+ <string name="copy_to_clipboard_a11y_action">copy to clipboard.</string>
+
<!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
<string name="basic_status">Open conversation</string>
<!--Title text for Conversation widget set up screen [CHAR LIMIT=180] -->
@@ -3823,8 +3833,16 @@
<!-- Error message displayed when the user select a key combination that is already in use while
assigning a new custom key combination to a shortcut in shortcut helper. The helper is a
component that shows the user which keyboard shortcuts they can use. [CHAR LIMIT=NONE] -->
- <string name="shortcut_helper_customize_dialog_error_message">Key combination already in use. Try another key.</string>
-
+ <string name="shortcut_customizer_key_combination_in_use_error_message">Key combination already in use. Try another key.</string>
+ <!-- Generic error message displayed when the user selected key combination cannot be used as
+ custom keyboard shortcut in shortcut helper. The helper is a component that shows the user
+ which keyboard shortcuts they can use and allows users to customize their keyboard
+ shortcuts. [CHAR LIMIT=NONE] -->
+ <string name="shortcut_customizer_generic_error_message">Shortcut cannot be set.</string>
+ <!-- Plus sign, used in keyboard shortcut helper to combine keys for shortcut. E.g. Ctrl + A
+ The helper is a component that shows the user which keyboard shortcuts they can use.
+ [CHAR LIMIT=NONE] -->
+ <string name="shortcut_helper_plus_symbol">+</string>
<!-- Keyboard touchpad tutorial scheduler-->
<!-- Notification title for launching keyboard tutorial [CHAR_LIMIT=100] -->
diff --git a/packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml b/packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml
new file mode 100644
index 000000000000..877637e0b0d8
--- /dev/null
+++ b/packages/SystemUI/res/xml/volume_dialog_ringer_drawer_motion_scene.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <Transition
+ android:id="@+id/transition"
+ app:constraintSetEnd="@+id/volume_dialog_ringer_drawer_open"
+ app:constraintSetStart="@+id/volume_dialog_ringer_drawer_close"
+ app:transitionEasing="path(0.05f, 0.7f, 0.1f, 1f)"
+ app:duration="400">
+ </Transition>
+
+ <ConstraintSet android:id="@+id/volume_dialog_ringer_drawer_close">
+ <Constraint
+ android:id="@+id/volume_ringer_drawer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+ </ConstraintSet>
+
+ <ConstraintSet android:id="@+id/volume_dialog_ringer_drawer_open">
+ <Constraint
+ android:id="@+id/volume_ringer_drawer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+ </ConstraintSet>
+
+</MotionScene> \ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 76af813fe2f8..7d220b505aa0 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -18,9 +18,11 @@ package com.android.systemui.shared.system;
import android.os.RemoteException;
import android.util.Log;
+import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
+import android.window.WindowAnimationState;
import com.android.internal.os.IResultReceiver;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -107,6 +109,17 @@ public class RecentsAnimationControllerCompat {
}
/**
+ * @see IRecentsAnimationController#handOffAnimation
+ */
+ public void handOffAnimation(RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+ try {
+ mAnimationController.handOffAnimation(targets, states);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to hand off animation", e);
+ }
+ }
+
+ /**
* @see IRecentsAnimationController#detachNavigationBarFromApp
*/
public void detachNavigationBarFromApp(boolean moveHomeToTop) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index e91bb6aefeec..4723ab958f86 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -305,7 +305,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
}
if (mMagnificationMode != mode) {
mMagnificationMode = mode;
- mImageView.setImageResource(getIconResId(mMagnificationMode));
+ mImageView.setImageResource(getIconResId());
}
if (!mIsVisible) {
onConfigurationChanged(mContext.getResources().getConfiguration());
@@ -455,7 +455,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
}
@VisibleForTesting
- static int getIconResId(int mode) { // TODO(b/242233514): delete non used param
+ static int getIconResId() {
return R.drawable.ic_open_in_new_window;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
index 60d80efe6426..3f717e282a61 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.accessibility.extradim
+import android.os.Handler
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
@@ -32,18 +33,21 @@ constructor(
private val extraDimDialogDelegateProvider: Provider<ExtraDimDialogDelegate>,
private val mActivityStarter: ActivityStarter,
private val dialogTransitionAnimator: DialogTransitionAnimator,
+ private val mainHandler: Handler,
) {
private var dialog: SystemUIDialog? = null
@JvmOverloads
fun dismissKeyguardIfNeededAndShowDialog(expandable: Expandable? = null) {
- mActivityStarter.executeRunnableDismissingKeyguard(
- { showRemoveExtraDimShortcutsDialog(expandable) },
- /* cancelAction= */ null,
- /* dismissShade= */ false,
- /* afterKeyguardGone= */ true,
- /* deferred= */ false,
- )
+ mainHandler.post {
+ mActivityStarter.executeRunnableDismissingKeyguard(
+ { showRemoveExtraDimShortcutsDialog(expandable) },
+ /* cancelAction= */ null,
+ /* dismissShade= */ true,
+ /* afterKeyguardGone= */ true,
+ /* deferred= */ false,
+ )
+ }
}
/** Show the dialog for removing all Extra Dim shortcuts. */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
index abbbd730c47e..976329580c60 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
@@ -36,8 +36,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
+import kotlin.math.max
/** Encapsulates business logic for interacting with the UDFPS overlay. */
@SysUISingleton
@@ -124,8 +126,9 @@ constructor(
udfpsOverlayParams.map { params ->
val sensorWidth = params.nativeSensorBounds.right - params.nativeSensorBounds.left
val nativePadding = (sensorWidth - iconSize) / 2
- (nativePadding * params.scaleFactor).toInt()
- }
+ // padding can be negative when udfpsOverlayParams has not been initialized yet.
+ max(0, (nativePadding * params.scaleFactor).toInt())
+ }.distinctUntilChanged()
companion object {
private const val TAG = "UdfpsOverlayInteractor"
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index 4f9443efd857..db9a7f5e81ae 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -18,6 +18,7 @@ package com.android.systemui.communal
import android.os.UserHandle
import android.provider.Settings
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
import com.android.internal.logging.UiEventLogger
@@ -28,6 +29,7 @@ import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.log.CommunalUiEvent
import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalScenes.isCommunal
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.communal.shared.model.EditModeState
import com.android.systemui.dagger.SysUISingleton
@@ -35,7 +37,6 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dock.DockManager
-import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -62,7 +63,6 @@ import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.withContext
/**
@@ -83,7 +83,6 @@ constructor(
private val systemSettings: SystemSettings,
centralSurfacesOpt: Optional<CentralSurfaces>,
private val notificationShadeWindowController: NotificationShadeWindowController,
- private val featureFlagsClassic: FeatureFlagsClassic,
@Application private val applicationScope: CoroutineScope,
@Background private val bgScope: CoroutineScope,
@Main private val mainDispatcher: CoroutineDispatcher,
@@ -168,7 +167,7 @@ constructor(
communalInteractor.userActivity.emitOnStart(),
) { scene, _ ->
// Only timeout if we're on the hub is open.
- scene == CommunalScenes.Communal
+ scene.isCommunal()
}
.collectLatest { shouldTimeout ->
cancelHubTimeout()
@@ -182,7 +181,7 @@ constructor(
.sample(communalSceneInteractor.currentScene, ::Pair)
.collectLatest { (isDreaming, scene) ->
this@CommunalSceneStartable.isDreaming = isDreaming
- if (scene == CommunalScenes.Communal && isDreaming && timeoutJob == null) {
+ if (scene.isCommunal() && isDreaming && timeoutJob == null) {
// If dreaming starts after timeout has expired, ex. if dream restarts under
// the hub, just close the hub immediately.
communalSceneInteractor.changeScene(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
index 428b83ddbb3a..ae08f2b8c45e 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -98,16 +98,17 @@ constructor(
transitionKey: TransitionKey? = null,
keyguardState: KeyguardState? = null,
) {
- if (SceneContainerFlag.isEnabled) {
- return sceneInteractor.changeScene(
- toScene = newScene.toSceneContainerSceneKey(),
- loggingReason = loggingReason,
- transitionKey = transitionKey,
- sceneState = keyguardState,
- )
- }
-
applicationScope.launch("$TAG#changeScene") {
+ if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.changeScene(
+ toScene = newScene.toSceneContainerSceneKey(),
+ loggingReason = loggingReason,
+ transitionKey = transitionKey,
+ sceneState = keyguardState,
+ )
+ return@launch
+ }
+
if (currentScene.value == newScene) return@launch
logger.logSceneChangeRequested(
from = currentScene.value,
@@ -125,16 +126,17 @@ constructor(
newScene: SceneKey,
loggingReason: String,
delayMillis: Long = 0,
- keyguardState: KeyguardState? = null
+ keyguardState: KeyguardState? = null,
) {
- if (SceneContainerFlag.isEnabled) {
- return sceneInteractor.snapToScene(
- toScene = newScene.toSceneContainerSceneKey(),
- loggingReason = loggingReason,
- )
- }
-
applicationScope.launch("$TAG#snapToScene") {
+ if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.snapToScene(
+ toScene = newScene.toSceneContainerSceneKey(),
+ loggingReason = loggingReason,
+ )
+ return@launch
+ }
+
delay(delayMillis)
if (currentScene.value == newScene) return@launch
logger.logSceneChangeRequested(
@@ -161,10 +163,7 @@ constructor(
} else {
repository.currentScene
.pairwiseBy(initialValue = repository.currentScene.value) { from, to ->
- logger.logSceneChangeCommitted(
- from = from,
- to = to,
- )
+ logger.logSceneChangeCommitted(from = from, to = to)
to
}
.stateIn(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
index e562dfcbbc74..7f15944f61e7 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalScenes.kt
@@ -18,9 +18,16 @@ package com.android.systemui.communal.shared.model
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
/** Definition of the possible scenes for the communal UI. */
+@Deprecated(
+ "CommunalScenes are deprecated when SceneContainerFlag is enabled. " +
+ "Use com.android.systemui.scene.shared.model.Scenes instead. " +
+ "Use SceneKey.toSceneContainerSceneKey() to map legacy scenes to scene container scenes. " +
+ "Use SceneKey.isCommunal() to check whether a scene is a communal scene."
+)
object CommunalScenes {
/** The default scene, shows nothing and is only there to allow swiping to communal. */
@JvmField val Blank = SceneKey("blank")
@@ -40,9 +47,8 @@ object CommunalScenes {
* The rules are simple:
* - A legacy communal scene maps to a communal scene in the Scene Transition Framework (STF).
* - A legacy blank scene means that the communal scene layout does not render anything so
- * whatever is beneath the layout is shown. That usually means lockscreen or dream, both of
- * which are represented by the lockscreen scene in STF (but different keyguard states in
- * KTF).
+ * whatever is beneath the layout is shown. That usually means lockscreen or dream, both in
+ * STL are represented by the home scene family.
*/
fun SceneKey.toSceneContainerSceneKey(): SceneKey {
if (!isCommunalScene() || !SceneContainerFlag.isEnabled) {
@@ -51,8 +57,13 @@ object CommunalScenes {
return when (this) {
Communal -> Scenes.Communal
- Blank -> Scenes.Lockscreen
+ Blank -> SceneFamilies.Home
else -> throw Throwable("Unrecognized communal scene: $this")
}
}
+
+ /** Checks whether this is a communal scene based on whether [SceneContainerFlag] is enabled. */
+ fun SceneKey.isCommunal(): Boolean {
+ return if (SceneContainerFlag.isEnabled) this == Scenes.Communal else this == Communal
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 4cdf28670eab..7b91eaecd33a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -29,6 +29,7 @@ import com.android.systemui.controls.dagger.StartControlsStartableModule
import com.android.systemui.dagger.qualifiers.PerUser
import com.android.systemui.dreams.AssistantAttentionMonitor
import com.android.systemui.dreams.DreamMonitor
+import com.android.systemui.dreams.DreamOverlayRegistrant
import com.android.systemui.dreams.homecontrols.system.HomeControlsDreamStartable
import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.haptics.msdl.MSDLCoreStartable
@@ -328,4 +329,12 @@ abstract class SystemUICoreStartableModule {
@IntoMap
@ClassKey(MSDLCoreStartable::class)
abstract fun bindMSDLCoreStartable(impl: MSDLCoreStartable): CoreStartable
+
+ /** Inject into DreamOverlay. */
+ @Binds
+ @IntoMap
+ @ClassKey(DreamOverlayRegistrant::class)
+ abstract fun bindDreamOverlayRegistrant(
+ dreamOverlayRegistrant: DreamOverlayRegistrant
+ ): CoreStartable
}
diff --git a/packages/SystemUI/src/com/android/systemui/development/data/repository/DevelopmentSettingRepository.kt b/packages/SystemUI/src/com/android/systemui/development/data/repository/DevelopmentSettingRepository.kt
new file mode 100644
index 000000000000..a8fa9797ebfd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/development/data/repository/DevelopmentSettingRepository.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.data.repository
+
+import android.content.pm.UserInfo
+import android.os.Build
+import android.os.UserManager
+import android.provider.Settings
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.kotlin.emitOnStart
+import com.android.systemui.util.settings.GlobalSettings
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.withContext
+
+@SysUISingleton
+class DevelopmentSettingRepository
+@Inject
+constructor(
+ private val globalSettings: GlobalSettings,
+ private val userManager: UserManager,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+) {
+ private val settingFlow = globalSettings.observerFlow(SETTING)
+
+ /**
+ * Indicates whether development settings is enabled for this user. The conditions are:
+ * * Setting is enabled (defaults to true in eng builds)
+ * * User is an admin
+ * * User is not restricted from Debugging features.
+ */
+ fun isDevelopmentSettingEnabled(userInfo: UserInfo): Flow<Boolean> {
+ return settingFlow
+ .emitOnStart()
+ .map { checkDevelopmentSettingEnabled(userInfo) }
+ .flowOn(backgroundDispatcher)
+ }
+
+ private suspend fun checkDevelopmentSettingEnabled(userInfo: UserInfo): Boolean {
+ val hasUserRestriction =
+ withContext(backgroundDispatcher) {
+ userManager.hasUserRestrictionForUser(
+ UserManager.DISALLOW_DEBUGGING_FEATURES,
+ userInfo.userHandle,
+ )
+ }
+ val isSettingEnabled =
+ withContext(backgroundDispatcher) {
+ globalSettings.getInt(SETTING, DEFAULT_ENABLED) != 0
+ }
+ val isAdmin = userInfo.isAdmin
+ return isAdmin && !hasUserRestriction && isSettingEnabled
+ }
+
+ private companion object {
+ val DEFAULT_ENABLED = if (Build.TYPE == "eng") 1 else 0
+
+ const val SETTING = Settings.Global.DEVELOPMENT_SETTINGS_ENABLED
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt b/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt
new file mode 100644
index 000000000000..4d786fe76bc1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/development/domain/interactor/BuildNumberInteractor.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.domain.interactor
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.res.Resources
+import android.os.Build
+import android.os.UserHandle
+import com.android.internal.R as InternalR
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.development.data.repository.DevelopmentSettingRepository
+import com.android.systemui.development.shared.model.BuildNumber
+import com.android.systemui.res.R as SystemUIR
+import com.android.systemui.user.data.repository.UserRepository
+import com.android.systemui.user.utils.UserScopedService
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapConcat
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.withContext
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class BuildNumberInteractor
+@Inject
+constructor(
+ repository: DevelopmentSettingRepository,
+ @Main resources: Resources,
+ private val userRepository: UserRepository,
+ private val clipboardManagerProvider: UserScopedService<ClipboardManager>,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+) {
+
+ /**
+ * Build number, or `null` if Development Settings is not enabled for the current user.
+ *
+ * @see DevelopmentSettingRepository.isDevelopmentSettingEnabled
+ */
+ val buildNumber: Flow<BuildNumber?> =
+ userRepository.selectedUserInfo
+ .flatMapConcat { userInfo -> repository.isDevelopmentSettingEnabled(userInfo) }
+ .map { enabled -> buildText.takeIf { enabled } }
+
+ private val buildText =
+ BuildNumber(
+ resources.getString(
+ InternalR.string.bugreport_status,
+ Build.VERSION.RELEASE_OR_CODENAME,
+ Build.ID,
+ )
+ )
+
+ private val clipLabel = resources.getString(SystemUIR.string.build_number_clip_data_label)
+
+ private val currentUserHandle: UserHandle
+ get() = userRepository.getSelectedUserInfo().userHandle
+
+ /**
+ * Copy to the clipboard the build number for the current user.
+ *
+ * This can be performed regardless of the current user having Development Settings enabled
+ */
+ suspend fun copyBuildNumber() {
+ withContext(backgroundDispatcher) {
+ clipboardManagerProvider
+ .forUser(currentUserHandle)
+ .setPrimaryClip(ClipData.newPlainText(clipLabel, buildText.value))
+ }
+ }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt b/packages/SystemUI/src/com/android/systemui/development/shared/model/BuildNumber.kt
index 5a041691b06a..5bd713fc4840 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/development/shared/model/BuildNumber.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-package com.android.systemui.shared.clocks
+package com.android.systemui.development.shared.model
-object ClockAnimation {
- const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
-}
+@JvmInline value class BuildNumber(val value: String)
diff --git a/packages/SystemUI/src/com/android/systemui/development/ui/compose/BuildNumber.kt b/packages/SystemUI/src/com/android/systemui/development/ui/compose/BuildNumber.kt
new file mode 100644
index 000000000000..72e1cede0002
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/development/ui/compose/BuildNumber.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.ui.compose
+
+import androidx.compose.foundation.basicMarquee
+import androidx.compose.foundation.focusable
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.material3.Text
+import androidx.compose.material3.minimumInteractiveComponentSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.hapticfeedback.HapticFeedbackType
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.platform.LocalHapticFeedback
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.onLongClick
+import androidx.compose.ui.semantics.semantics
+import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture
+import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.res.R
+
+@Composable
+fun BuildNumber(
+ viewModelFactory: BuildNumberViewModel.Factory,
+ textColor: Color,
+ modifier: Modifier = Modifier,
+) {
+ val viewModel = rememberViewModel(traceName = "BuildNumber") { viewModelFactory.create() }
+
+ val buildNumber = viewModel.buildNumber
+
+ if (buildNumber != null) {
+ val haptics = LocalHapticFeedback.current
+ val copyToClipboardActionLabel = stringResource(id = R.string.copy_to_clipboard_a11y_action)
+
+ Text(
+ text = buildNumber.value,
+ modifier =
+ modifier
+ .focusable()
+ .wrapContentWidth()
+ // Using this instead of combinedClickable because this node should not support
+ // single click
+ .pointerInput(Unit) {
+ detectLongPressGesture {
+ haptics.performHapticFeedback(HapticFeedbackType.LongPress)
+ viewModel.onBuildNumberLongPress()
+ }
+ }
+ .semantics {
+ onLongClick(copyToClipboardActionLabel) {
+ viewModel.onBuildNumberLongPress()
+ true
+ }
+ }
+ .basicMarquee(iterations = 1, initialDelayMillis = 2000)
+ .minimumInteractiveComponentSize(),
+ color = textColor,
+ maxLines = 1,
+ )
+ } else {
+ Spacer(modifier)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt b/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt
new file mode 100644
index 000000000000..68c51ea80ffd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModel.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.ui.viewmodel
+
+import androidx.compose.runtime.getValue
+import com.android.systemui.development.domain.interactor.BuildNumberInteractor
+import com.android.systemui.development.shared.model.BuildNumber
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.receiveAsFlow
+import kotlinx.coroutines.launch
+
+/** View model for UI that (optionally) shows the build number and copies it on long press. */
+class BuildNumberViewModel
+@AssistedInject
+constructor(private val buildNumberInteractor: BuildNumberInteractor) : ExclusiveActivatable() {
+
+ private val hydrator = Hydrator("BuildNumberViewModel")
+
+ private val copyRequests = Channel<Unit>()
+
+ val buildNumber: BuildNumber? by
+ hydrator.hydratedStateOf(
+ traceName = "buildNumber",
+ initialValue = null,
+ source = buildNumberInteractor.buildNumber,
+ )
+
+ fun onBuildNumberLongPress() {
+ copyRequests.trySend(Unit)
+ }
+
+ override suspend fun onActivated(): Nothing {
+ coroutineScope {
+ launch { hydrator.activate() }
+ launch {
+ copyRequests.receiveAsFlow().collect { buildNumberInteractor.copyBuildNumber() }
+ }
+ awaitCancellation()
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): BuildNumberViewModel
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 1a5654144b65..400d09742d13 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -16,6 +16,7 @@
package com.android.systemui.deviceentry.domain.interactor
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.policy.IKeyguardDismissCallback
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
@@ -43,7 +44,6 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
* Hosts application business logic related to device entry.
@@ -174,6 +174,14 @@ constructor(
}
/**
+ * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
+ * dismissed once the authentication challenge is completed. For example, completing a biometric
+ * authentication challenge via face unlock or fingerprint sensor can automatically bypass the
+ * lockscreen.
+ */
+ val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
+
+ /**
* Attempt to enter the device and dismiss the lockscreen. If authentication is required to
* unlock the device it will transition to bouncer.
*
@@ -238,11 +246,8 @@ constructor(
isLockscreenEnabled()
}
- /**
- * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
- * dismissed once the authentication challenge is completed. For example, completing a biometric
- * authentication challenge via face unlock or fingerprint sensor can automatically bypass the
- * lockscreen.
- */
- val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
+ /** Locks the device instantly. */
+ fun lockNow() {
+ deviceUnlockedInteractor.lockNow()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
index 35eed5e6a6d9..7d684cab39f7 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
@@ -43,6 +43,7 @@ import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@@ -57,6 +58,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class)
@@ -178,6 +180,8 @@ constructor(
val deviceUnlockStatus: StateFlow<DeviceUnlockStatus> =
repository.deviceUnlockStatus.asStateFlow()
+ private val lockNowRequests = Channel<Unit>()
+
override suspend fun onActivated(): Nothing {
authenticationInteractor.authenticationMethod.collectLatest { authMethod ->
if (!authMethod.isSecure) {
@@ -196,6 +200,11 @@ constructor(
awaitCancellation()
}
+ /** Locks the device instantly. */
+ fun lockNow() {
+ lockNowRequests.trySend(Unit)
+ }
+
private suspend fun handleLockAndUnlockEvents() {
try {
Log.d(TAG, "started watching for lock and unlock events")
@@ -225,10 +234,12 @@ constructor(
.map { (isAsleep, lastSleepReason) ->
if (isAsleep) {
if (
- lastSleepReason == WakeSleepReason.POWER_BUTTON &&
+ (lastSleepReason == WakeSleepReason.POWER_BUTTON) &&
authenticationInteractor.getPowerButtonInstantlyLocks()
) {
LockImmediately("locked instantly from power button")
+ } else if (lastSleepReason == WakeSleepReason.SLEEP_BUTTON) {
+ LockImmediately("locked instantly from sleep button")
} else {
LockWithDelay("entering sleep")
}
@@ -256,6 +267,7 @@ constructor(
emptyFlow()
}
},
+ lockNowRequests.receiveAsFlow().map { LockImmediately("lockNow") },
)
.collectLatest(::onLockEvent)
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
deleted file mode 100644
index 80e68cfbff21..000000000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
+++ /dev/null
@@ -1,129 +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.systemui.dreams;
-
-import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.os.PatternMatcher;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
-import android.util.Log;
-
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.SystemUser;
-import com.android.systemui.shared.condition.Monitor;
-import com.android.systemui.util.condition.ConditionalCoreStartable;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
- * the designated dream overlay component.
- */
-public class DreamOverlayRegistrant extends ConditionalCoreStartable {
- private static final String TAG = "DreamOverlayRegistrant";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private final IDreamManager mDreamManager;
- private final ComponentName mOverlayServiceComponent;
- private final Context mContext;
- private final Resources mResources;
- private boolean mCurrentRegisteredState = false;
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DEBUG) {
- Log.d(TAG, "package changed receiver - onReceive");
- }
-
- registerOverlayService();
- }
- };
-
- private void registerOverlayService() {
- // Check to see if the service has been disabled by the user. In this case, we should not
- // proceed modifying the enabled setting.
- final PackageManager packageManager = mContext.getPackageManager();
- final int enabledState =
- packageManager.getComponentEnabledSetting(mOverlayServiceComponent);
-
- // The overlay service is only registered when its component setting is enabled.
- boolean register = false;
-
- try {
- register = packageManager.getServiceInfo(mOverlayServiceComponent,
- PackageManager.GET_META_DATA).enabled;
- } catch (NameNotFoundException e) {
- Log.e(TAG, "could not find dream overlay service");
- }
-
- if (mCurrentRegisteredState == register) {
- return;
- }
-
- mCurrentRegisteredState = register;
-
- try {
- if (DEBUG) {
- Log.d(TAG, mCurrentRegisteredState
- ? "registering dream overlay service:" + mOverlayServiceComponent
- : "clearing dream overlay service");
- }
-
- mDreamManager.registerDreamOverlayService(
- mCurrentRegisteredState ? mOverlayServiceComponent : null);
- } catch (RemoteException e) {
- Log.e(TAG, "could not register dream overlay service:" + e);
- }
- }
-
- @Inject
- public DreamOverlayRegistrant(Context context, @Main Resources resources,
- @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent,
- @SystemUser Monitor monitor) {
- super(monitor);
- mContext = context;
- mResources = resources;
- mDreamManager = IDreamManager.Stub.asInterface(
- ServiceManager.getService(DreamService.DREAM_SERVICE));
- mOverlayServiceComponent = dreamOverlayServiceComponent;
- }
-
- @Override
- protected void onStart() {
- final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
- filter.addDataScheme("package");
- filter.addDataSchemeSpecificPart(mOverlayServiceComponent.getPackageName(),
- PatternMatcher.PATTERN_LITERAL);
- // Note that we directly register the receiver here as data schemes are not supported by
- // BroadcastDispatcher.
- mContext.registerReceiver(mReceiver, filter);
-
- registerOverlayService();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
new file mode 100644
index 000000000000..e76fd47c74de
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.dreams
+
+import android.content.BroadcastReceiver
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.os.PatternMatcher
+import android.os.RemoteException
+import android.service.dreams.IDreamManager
+import android.util.Log
+import com.android.systemui.Flags
+import com.android.systemui.dagger.qualifiers.SystemUser
+import com.android.systemui.dreams.dagger.DreamModule
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.dagger.DreamLog
+import com.android.systemui.shared.condition.Monitor
+import com.android.systemui.util.condition.ConditionalCoreStartable
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * [DreamOverlayRegistrant] is responsible for telling system server that SystemUI should be the
+ * designated dream overlay component.
+ */
+class DreamOverlayRegistrant
+@Inject
+constructor(
+ private val context: Context,
+ @param:Named(DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT)
+ private val overlayServiceComponent: ComponentName,
+ @SystemUser monitor: Monitor,
+ private val packageManager: PackageManager,
+ private val dreamManager: IDreamManager,
+ @DreamLog private val logBuffer: LogBuffer,
+) : ConditionalCoreStartable(monitor) {
+ private var currentRegisteredState = false
+ private val logger: DreamLogger = DreamLogger(logBuffer, TAG)
+
+ private val receiver: BroadcastReceiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (DEBUG) {
+ Log.d(TAG, "package changed receiver - onReceive")
+ }
+
+ registerOverlayService()
+ }
+ }
+
+ internal val enabledInManifest: Boolean
+ get() {
+ return packageManager
+ .getServiceInfo(
+ overlayServiceComponent,
+ PackageManager.GET_META_DATA or PackageManager.MATCH_DISABLED_COMPONENTS,
+ )
+ .enabled
+ }
+
+ internal val enabled: Boolean
+ get() {
+ // Always disabled via setting
+ if (
+ packageManager.getComponentEnabledSetting(overlayServiceComponent) ==
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ ) {
+ return false
+ }
+
+ // If the overlay is available in the manifest, then it is already available
+ if (enabledInManifest) {
+ return true
+ }
+
+ if (
+ Flags.communalHubOnMobile() &&
+ packageManager.getComponentEnabledSetting(overlayServiceComponent) ==
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ ) {
+ return true
+ }
+
+ return false
+ }
+
+ /**
+ * This method enables the dream overlay at runtime. This method allows expanding the eligible
+ * device pool during development before enabling the component in said devices' manifest.
+ */
+ internal fun enableIfAvailable() {
+ // If the overlay is available in the manifest, then it is already available
+ if (enabledInManifest) {
+ return
+ }
+
+ // Enable for hub on mobile
+ if (Flags.communalHubOnMobile()) {
+ // Not available on TV or auto
+ if (
+ packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+ packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) ||
+ packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY)
+ ) {
+ if (DEBUG) {
+ Log.d(TAG, "unsupported platform")
+ }
+ return
+ }
+
+ // If the component is not in the default enabled state, then don't update
+ if (
+ packageManager.getComponentEnabledSetting(overlayServiceComponent) !=
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ ) {
+ return
+ }
+
+ packageManager.setComponentEnabledSetting(
+ overlayServiceComponent,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP,
+ )
+ }
+ }
+
+ private fun registerOverlayService() {
+ // The overlay service is only registered when its component setting is enabled.
+ var register = false
+
+ try {
+ Log.d(TAG, "trying to find component:" + overlayServiceComponent)
+ // Check to see if the service has been disabled by the user. In this case, we should
+ // not proceed modifying the enabled setting.
+ register = enabled
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.e(TAG, "could not find dream overlay service")
+ }
+
+ if (currentRegisteredState == register) {
+ return
+ }
+
+ currentRegisteredState = register
+
+ try {
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ if (currentRegisteredState)
+ "registering dream overlay service:$overlayServiceComponent"
+ else "clearing dream overlay service",
+ )
+ }
+
+ dreamManager.registerDreamOverlayService(
+ if (currentRegisteredState) overlayServiceComponent else null
+ )
+ logger.logDreamOverlayEnabled(currentRegisteredState)
+ } catch (e: RemoteException) {
+ Log.e(TAG, "could not register dream overlay service:$e")
+ }
+ }
+
+ override fun onStart() {
+ val filter = IntentFilter(Intent.ACTION_PACKAGE_CHANGED)
+ filter.addDataScheme("package")
+ filter.addDataSchemeSpecificPart(
+ overlayServiceComponent.packageName,
+ PatternMatcher.PATTERN_LITERAL,
+ )
+ // Note that we directly register the receiver here as data schemes are not supported by
+ // BroadcastDispatcher.
+ context.registerReceiver(receiver, filter)
+
+ registerOverlayService()
+
+ enableIfAvailable()
+ }
+
+ companion object {
+ private const val TAG = "DreamOverlayRegistrant"
+ private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index b330ba376810..408fe831d74c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -47,6 +47,7 @@ import androidx.lifecycle.ServiceLifecycleDispatcher;
import androidx.lifecycle.ViewModelStore;
import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
+import com.android.compose.animation.scene.SceneKey;
import com.android.dream.lowlight.dagger.LowLightDreamModule;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
@@ -212,16 +213,14 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
private final Consumer<Boolean> mBouncerShowingConsumer = new Consumer<>() {
@Override
public void accept(Boolean bouncerShowing) {
- mExecutor.execute(() -> {
- if (mBouncerShowing == bouncerShowing) {
- return;
- }
-
- mBouncerShowing = bouncerShowing;
+ mExecutor.execute(() -> updateBouncerShowingLocked(bouncerShowing));
+ }
+ };
- updateLifecycleStateLocked();
- updateGestureBlockingLocked();
- });
+ private final Consumer<SceneKey> mCurrentSceneConsumer = new Consumer<>() {
+ @Override
+ public void accept(SceneKey currentScene) {
+ mExecutor.execute(() -> updateBouncerShowingLocked(currentScene == Scenes.Bouncer));
}
};
@@ -425,8 +424,13 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
mIsCommunalAvailableCallback));
mFlows.add(collectFlow(getLifecycle(), communalInteractor.isCommunalVisible(),
mCommunalVisibleConsumer));
- mFlows.add(collectFlow(getLifecycle(), keyguardInteractor.primaryBouncerShowing,
- mBouncerShowingConsumer));
+ if (SceneContainerFlag.isEnabled()) {
+ mFlows.add(collectFlow(getLifecycle(), sceneInteractor.getCurrentScene(),
+ mCurrentSceneConsumer));
+ } else {
+ mFlows.add(collectFlow(getLifecycle(), keyguardInteractor.primaryBouncerShowing,
+ mBouncerShowingConsumer));
+ }
}
@NonNull
@@ -707,4 +711,15 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
Log.w(TAG, "Removing dream overlay container view parent!");
parentView.removeView(containerView);
}
+
+ private void updateBouncerShowingLocked(boolean bouncerShowing) {
+ if (mBouncerShowing == bouncerShowing) {
+ return;
+ }
+
+ mBouncerShowing = bouncerShowing;
+
+ updateLifecycleStateLocked();
+ updateGestureBlockingLocked();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index 7015cc992dad..bd1fda7ad03a 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -16,8 +16,6 @@
package com.android.systemui.dreams;
-import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_ENABLED;
-
import android.service.dreams.DreamService;
import androidx.annotation.NonNull;
@@ -46,7 +44,6 @@ import java.util.function.Consumer;
import java.util.stream.Collectors;
import javax.inject.Inject;
-import javax.inject.Named;
/**
* {@link DreamOverlayStateController} is the source of truth for Dream overlay configurations and
@@ -103,7 +100,6 @@ public class DreamOverlayStateController implements
}
private final Executor mExecutor;
- private final boolean mOverlayEnabled;
private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
@Complication.ComplicationType
@@ -123,12 +119,10 @@ public class DreamOverlayStateController implements
@VisibleForTesting
@Inject
public DreamOverlayStateController(@Main Executor executor,
- @Named(DREAM_OVERLAY_ENABLED) boolean overlayEnabled,
FeatureFlags featureFlags,
@DreamLog LogBuffer logBuffer,
WeakReferenceFactory weakReferenceFactory) {
mExecutor = executor;
- mOverlayEnabled = overlayEnabled;
mLogger = new DreamLogger(logBuffer, TAG);
mFeatureFlags = featureFlags;
mWeakReferenceFactory = weakReferenceFactory;
@@ -138,18 +132,12 @@ public class DreamOverlayStateController implements
} else {
mSupportedTypes = Complication.COMPLICATION_TYPE_NONE;
}
- mLogger.logDreamOverlayEnabled(mOverlayEnabled);
}
/**
* Adds a complication to be included on the dream overlay.
*/
public void addComplication(Complication complication) {
- if (!mOverlayEnabled) {
- mLogger.logIgnoreAddComplication("overlay disabled", complication.toString());
- return;
- }
-
mExecutor.execute(() -> {
if (mComplications.add(complication)) {
mLogger.logAddComplication(complication.toString());
@@ -162,11 +150,6 @@ public class DreamOverlayStateController implements
* Removes a complication from inclusion on the dream overlay.
*/
public void removeComplication(Complication complication) {
- if (!mOverlayEnabled) {
- mLogger.logIgnoreRemoveComplication("overlay disabled", complication.toString());
- return;
- }
-
mExecutor.execute(() -> {
if (mComplications.remove(complication)) {
mLogger.logRemoveComplication(complication.toString());
@@ -264,7 +247,7 @@ public class DreamOverlayStateController implements
* @return {@code true} if overlay is active, {@code false} otherwise.
*/
public boolean isOverlayActive() {
- return mOverlayEnabled && containsState(STATE_DREAM_OVERLAY_ACTIVE);
+ return containsState(STATE_DREAM_OVERLAY_ACTIVE);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
index 5a9e52ae5655..b37206a4fef7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
@@ -20,7 +20,6 @@ import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
-import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -60,9 +59,6 @@ constructor(
if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer
add(Swipe.Up to bouncerOrGone)
- // "Home" is either Dream, Lockscreen, or Gone.
- add(Swipe.End to SceneFamilies.Home)
-
addAll(
when (shadeMode) {
ShadeMode.Single -> singleShadeActions()
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
index 2e792497906e..b82aa817afd8 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
@@ -215,6 +215,21 @@ constructor(
return true
}
+ fun onTileLongClick(): Boolean {
+ if (state == State.IDLE) {
+ // This case represents a long-click detected outside of the QSLongPressEffect. This can
+ // be due to accessibility services
+ qsTile?.longClick(expandable)
+ logEvent(
+ qsTile?.tileSpec,
+ state,
+ "long click action triggered from OnLongClickListener",
+ )
+ return true
+ }
+ return false
+ }
+
/**
* Get the appropriate state for a click action.
*
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt
new file mode 100644
index 000000000000..bb563b1f6561
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shared/model/ShortcutCustomizationRequestResult.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shared.model
+
+enum class ShortcutCustomizationRequestResult {
+ SUCCESS,
+ ERROR_RESERVED_COMBINATION,
+ ERROR_OTHER,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
index 7b3380a6a608..1af7340ad7b4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
@@ -18,6 +18,9 @@ package com.android.systemui.keyboard.shortcut
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.keyboardShortcutHelperRewrite
+import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.DefaultShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
import com.android.systemui.keyboard.shortcut.data.source.AppCategoriesShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.CurrentAppShortcutsSource
@@ -27,6 +30,8 @@ import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsS
import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
import com.android.systemui.keyboard.shortcut.qualifiers.AppCategoriesShortcuts
import com.android.systemui.keyboard.shortcut.qualifiers.CurrentAppShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.CustomShortcutCategories
+import com.android.systemui.keyboard.shortcut.qualifiers.DefaultShortcutCategories
import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts
import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
@@ -63,6 +68,18 @@ interface ShortcutHelperModule {
impl: AppCategoriesShortcutsSource
): KeyboardShortcutGroupsSource
+ @Binds
+ @DefaultShortcutCategories
+ fun defaultShortcutCategoriesRepository(
+ impl: DefaultShortcutCategoriesRepository
+ ): ShortcutCategoriesRepository
+
+ @Binds
+ @CustomShortcutCategories
+ fun customShortcutCategoriesRepository(
+ impl: CustomShortcutCategoriesRepository
+ ): ShortcutCategoriesRepository
+
companion object {
@Provides
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
index ec1d358b6bd2..99cafd3daacb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
@@ -19,26 +19,41 @@ package com.android.systemui.keyboard.shortcut.data.repository
import android.content.Context
import android.content.Context.INPUT_SERVICE
import android.hardware.input.InputGestureData
+import android.hardware.input.InputGestureData.Builder
import android.hardware.input.InputGestureData.KeyTrigger
+import android.hardware.input.InputGestureData.createKeyTrigger
import android.hardware.input.InputManager
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
import android.hardware.input.InputSettings
import android.hardware.input.KeyGestureEvent
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import androidx.compose.runtime.mutableStateOf
+import com.android.systemui.Flags.shortcutHelperKeyGlyph
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup
import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.settings.UserTracker
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
@SysUISingleton
class CustomShortcutCategoriesRepository
@@ -47,9 +62,10 @@ constructor(
stateRepository: ShortcutHelperStateRepository,
private val userTracker: UserTracker,
@Background private val backgroundScope: CoroutineScope,
- @Background private val backgroundDispatcher: CoroutineDispatcher,
+ @Background private val bgCoroutineContext: CoroutineContext,
private val shortcutCategoriesUtils: ShortcutCategoriesUtils,
private val context: Context,
+ private val inputGestureMaps: InputGestureMaps
) : ShortcutCategoriesRepository {
private val userContext: Context
@@ -60,15 +76,53 @@ constructor(
private val inputManager: InputManager
get() = userContext.getSystemService(INPUT_SERVICE) as InputManager
+ private val _selectedKeyCombination = MutableStateFlow<KeyCombination?>(null)
+ private val _shortcutBeingCustomized = mutableStateOf<ShortcutCustomizationRequestInfo?>(null)
+
private val activeInputDevice =
stateRepository.state.map {
if (it is Active) {
- withContext(backgroundDispatcher) { inputManager.getInputDevice(it.deviceId) }
+ withContext(bgCoroutineContext) { inputManager.getInputDevice(it.deviceId) }
} else {
null
}
}
+ val pressedKeys =
+ _selectedKeyCombination
+ .combine(activeInputDevice) { keyCombination, inputDevice ->
+ if (inputDevice == null || keyCombination == null) {
+ return@combine emptyList()
+ } else {
+ val keyGlyphMap =
+ if (shortcutHelperKeyGlyph()) {
+ inputManager.getKeyGlyphMap(inputDevice.id)
+ } else null
+ val modifiers =
+ shortcutCategoriesUtils.toShortcutModifierKeys(
+ keyCombination.modifiers,
+ keyGlyphMap,
+ )
+ val triggerKey =
+ keyCombination.keyCode?.let {
+ shortcutCategoriesUtils.toShortcutKey(
+ keyGlyphMap,
+ inputDevice.keyCharacterMap,
+ keyCode = it,
+ )
+ }
+ val keys = mutableListOf<ShortcutKey>()
+ modifiers?.let { keys += it }
+ triggerKey?.let { keys += it }
+ return@combine keys
+ }
+ }
+ .stateIn(
+ scope = backgroundScope,
+ started = SharingStarted.Lazily,
+ initialValue = emptyList(),
+ )
+
override val categories: Flow<List<ShortcutCategory>> =
activeInputDevice
.map { inputDevice ->
@@ -104,6 +158,96 @@ constructor(
started = SharingStarted.Lazily,
)
+ fun updateUserKeyCombination(keyCombination: KeyCombination?) {
+ _selectedKeyCombination.value = keyCombination
+ }
+
+ fun onCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo?) {
+ _shortcutBeingCustomized.value = requestInfo
+ }
+
+ @VisibleForTesting
+ fun buildInputGestureDataForShortcutBeingCustomized(): InputGestureData? {
+ try {
+ return Builder()
+ .addKeyGestureTypeFromShortcutLabel()
+ .addTriggerFromSelectedKeyCombination()
+ .build()
+ // TODO(b/379648200) add app launch data for application categories shortcut after
+ // dynamic
+ // label/icon mapping implementation
+ } catch (e: IllegalArgumentException) {
+ Log.w(TAG, "could not add custom shortcut: $e")
+ return null
+ }
+ }
+
+ suspend fun confirmAndSetShortcutCurrentlyBeingCustomized(): ShortcutCustomizationRequestResult {
+ return withContext(bgCoroutineContext) {
+ val inputGestureData =
+ buildInputGestureDataForShortcutBeingCustomized()
+ ?: return@withContext ShortcutCustomizationRequestResult.ERROR_OTHER
+
+ return@withContext when (inputManager.addCustomInputGesture(inputGestureData)) {
+ CUSTOM_INPUT_GESTURE_RESULT_SUCCESS -> ShortcutCustomizationRequestResult.SUCCESS
+ CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS ->
+ ShortcutCustomizationRequestResult.ERROR_RESERVED_COMBINATION
+
+ CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE ->
+ ShortcutCustomizationRequestResult.ERROR_RESERVED_COMBINATION
+
+ else -> ShortcutCustomizationRequestResult.ERROR_OTHER
+ }
+ }
+ }
+
+ private fun Builder.addKeyGestureTypeFromShortcutLabel(): Builder {
+ val shortcutBeingCustomized =
+ getShortcutBeingCustomized() as? ShortcutCustomizationRequestInfo.Add
+
+ if (shortcutBeingCustomized == null) {
+ Log.w(TAG, "User requested to set shortcut but shortcut being customized is null")
+ return this
+ }
+
+ val keyGestureType =
+ inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+
+ if (keyGestureType == null) {
+ Log.w(TAG, "Could not find KeyGestureType for shortcut $shortcutBeingCustomized")
+ return this
+ }
+
+ return setKeyGestureType(keyGestureType)
+ }
+
+ private fun Builder.addTriggerFromSelectedKeyCombination(): Builder {
+ val selectedKeyCombination = _selectedKeyCombination.value
+ if (selectedKeyCombination?.keyCode == null) {
+ Log.w(
+ TAG,
+ "User requested to set shortcut but selected key combination is " +
+ "$selectedKeyCombination",
+ )
+ return this
+ }
+
+ return setTrigger(
+ createKeyTrigger(
+ /* keycode = */ selectedKeyCombination.keyCode,
+ /* modifierState = */
+ shortcutCategoriesUtils.removeUnsupportedModifiers(
+ selectedKeyCombination.modifiers
+ ),
+ )
+ )
+ }
+
+ @VisibleForTesting
+ fun getShortcutBeingCustomized(): ShortcutCustomizationRequestInfo? {
+ return _shortcutBeingCustomized.value
+ }
+
private fun toInternalGroupSources(
inputGestures: List<InputGestureData>
): List<InternalGroupsSource> {
@@ -112,8 +256,10 @@ constructor(
val keyTrigger = gestureData.trigger as KeyTrigger
val keyGestureType = gestureData.action.keyGestureType()
fetchGroupLabelByGestureType(keyGestureType)?.let { groupLabel ->
- toInternalKeyboardShortcutInfo(keyGestureType, keyTrigger)?.let {
- internalKeyboardShortcutInfo ->
+ toInternalKeyboardShortcutInfo(
+ keyGestureType,
+ keyTrigger
+ )?.let { internalKeyboardShortcutInfo ->
val group =
InternalKeyboardShortcutGroup(
label = groupLabel,
@@ -148,7 +294,7 @@ constructor(
private fun fetchGroupLabelByGestureType(
@KeyGestureEvent.KeyGestureType keyGestureType: Int
): String? {
- InputGestures.gestureToInternalKeyboardShortcutGroupLabelMap[keyGestureType]?.let {
+ inputGestureMaps.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let {
return context.getString(it)
} ?: return null
}
@@ -156,7 +302,7 @@ constructor(
private fun fetchShortcutInfoLabelByGestureType(
@KeyGestureEvent.KeyGestureType keyGestureType: Int
): String? {
- InputGestures.gestureToInternalKeyboardShortcutInfoLabelMap[keyGestureType]?.let {
+ inputGestureMaps.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let {
return context.getString(it)
} ?: return null
}
@@ -164,11 +310,15 @@ constructor(
private fun fetchShortcutCategoryTypeByGestureType(
@KeyGestureEvent.KeyGestureType keyGestureType: Int
): ShortcutCategoryType? {
- return InputGestures.gestureToShortcutCategoryTypeMap[keyGestureType]
+ return inputGestureMaps.gestureToShortcutCategoryTypeMap[keyGestureType]
}
private data class InternalGroupsSource(
val groups: List<InternalKeyboardShortcutGroup>,
val type: ShortcutCategoryType,
)
+
+ private companion object {
+ private const val TAG = "CustomShortcutCategoriesRepository"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
index 90be9888e622..d228a15e51b4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyboard.shortcut.data.repository
+import android.content.Context
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_BACK
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
@@ -45,8 +46,11 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
import com.android.systemui.res.R
+import javax.inject.Inject
-object InputGestures {
+class InputGestureMaps
+@Inject
+constructor(private val context: Context) {
val gestureToShortcutCategoryTypeMap =
mapOf(
// System Category
@@ -81,7 +85,7 @@ object InputGestures {
KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to AppCategories,
)
- val gestureToInternalKeyboardShortcutGroupLabelMap =
+ val gestureToInternalKeyboardShortcutGroupLabelResIdMap =
mapOf(
// System Category
KEY_GESTURE_TYPE_HOME to R.string.shortcut_helper_category_system_controls,
@@ -129,7 +133,7 @@ object InputGestures {
R.string.keyboard_shortcut_group_applications,
)
- val gestureToInternalKeyboardShortcutInfoLabelMap =
+ val gestureToInternalKeyboardShortcutInfoLabelResIdMap =
mapOf(
// System Category
KEY_GESTURE_TYPE_HOME to R.string.group_system_access_home_screen,
@@ -174,4 +178,11 @@ object InputGestures {
KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to
R.string.keyboard_shortcut_group_applications_sms,
)
+
+ val shortcutLabelToKeyGestureTypeMap: Map<String, Int>
+ get() = gestureToInternalKeyboardShortcutInfoLabelResIdMap.entries.associateBy({
+ context.getString(it.value)
+ }) {
+ it.key
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
index 899fd15d6115..95bc9f66618c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
@@ -24,6 +24,7 @@ import android.util.Log
import android.view.InputDevice
import android.view.KeyCharacterMap
import android.view.KeyEvent
+import android.view.KeyEvent.META_META_ON
import com.android.systemui.Flags.shortcutHelperKeyGlyph
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup
@@ -35,9 +36,9 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import kotlinx.coroutines.withContext
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.withContext
class ShortcutCategoriesUtils
@Inject
@@ -46,6 +47,11 @@ constructor(
@Background private val backgroundCoroutineContext: CoroutineContext,
private val inputManager: InputManager,
) {
+
+ fun removeUnsupportedModifiers(modifierMask: Int): Int {
+ return SUPPORTED_MODIFIERS.reduce { acc, modifier -> acc or modifier } and modifierMask
+ }
+
fun fetchShortcutCategory(
type: ShortcutCategoryType?,
groups: List<InternalKeyboardShortcutGroup>,
@@ -92,7 +98,7 @@ constructor(
}
.filter { it.shortcuts.isNotEmpty() }
return if (subCategories.isEmpty()) {
- Log.wtf(TAG, "Empty sub categories after converting $shortcutGroups")
+ Log.w(TAG, "Empty sub categories after converting $shortcutGroups")
null
} else {
ShortcutCategory(type, subCategories)
@@ -161,7 +167,7 @@ constructor(
}
if (remainingModifiers != 0) {
// There is a remaining modifier we don't support
- Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers")
+ Log.w(TAG, "Unsupported modifiers remaining: $remainingModifiers")
return null
}
if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) {
@@ -170,21 +176,32 @@ constructor(
?: return null
}
if (keys.isEmpty()) {
- Log.wtf(TAG, "No keys for $info")
+ Log.w(TAG, "No keys for $info")
return null
}
return ShortcutCommand(keys = keys, isCustom = info.isCustomShortcut)
}
+ fun toShortcutModifierKeys(modifiers: Int, keyGlyphMap: KeyGlyphMap?): List<ShortcutKey>? {
+ val keys: MutableList<ShortcutKey> = mutableListOf()
+ var remainingModifiers = modifiers
+ SUPPORTED_MODIFIERS.forEach { supportedModifier ->
+ if ((supportedModifier and remainingModifiers) != 0) {
+ keys += toShortcutModifierKey(keyGlyphMap, supportedModifier) ?: return null
+ remainingModifiers = remainingModifiers and supportedModifier.inv()
+ }
+ }
+ return keys
+ }
+
private fun toShortcutModifierKey(keyGlyphMap: KeyGlyphMap?, modifierMask: Int): ShortcutKey? {
val modifierDrawable = keyGlyphMap?.getDrawableForModifierState(context, modifierMask)
if (modifierDrawable != null) {
return ShortcutKey.Icon.DrawableIcon(drawable = modifierDrawable)
}
- val iconResId = ShortcutHelperKeys.keyIcons[modifierMask]
- if (iconResId != null) {
- return ShortcutKey.Icon.ResIdIcon(iconResId)
+ if (modifierMask == META_META_ON) {
+ return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId)
}
val modifierLabel = ShortcutHelperKeys.modifierLabels[modifierMask]
@@ -195,7 +212,7 @@ constructor(
return null
}
- private fun toShortcutKey(
+ fun toShortcutKey(
keyGlyphMap: KeyGlyphMap?,
keyCharacterMap: KeyCharacterMap,
keyCode: Int,
@@ -222,7 +239,7 @@ constructor(
if (displayLabelCharacter.code != 0) {
return ShortcutKey.Text(displayLabelCharacter.toString())
}
- Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode")
+ Log.w(TAG, "Couldn't find label or icon for key: $keyCode")
return null
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
index 288efa275219..e47b33f8c37c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
@@ -116,9 +116,10 @@ import com.android.systemui.res.R
object ShortcutHelperKeys {
+ val metaModifierIconResId = R.drawable.ic_ksh_key_meta
+
val keyIcons =
mapOf(
- META_META_ON to R.drawable.ic_ksh_key_meta,
KEYCODE_BACK to R.drawable.ic_arrow_back_2,
KEYCODE_HOME to R.drawable.ic_radio_button_unchecked,
KEYCODE_RECENT_APPS to R.drawable.ic_check_box_outline_blank,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
index 85d22144f201..f4e2f05379bb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
@@ -16,13 +16,32 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
-import android.view.KeyEvent.META_META_ON
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
+import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperKeys
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import javax.inject.Inject
-class ShortcutCustomizationInteractor @Inject constructor() {
+class ShortcutCustomizationInteractor
+@Inject
+constructor(private val customShortcutRepository: CustomShortcutCategoriesRepository) {
+ val pressedKeys = customShortcutRepository.pressedKeys
+
+ fun updateUserSelectedKeyCombination(keyCombination: KeyCombination?) {
+ customShortcutRepository.updateUserKeyCombination(keyCombination)
+ }
+
fun getDefaultCustomShortcutModifierKey(): ShortcutKey.Icon.ResIdIcon {
- return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.keyIcons[META_META_ON]!!)
+ return ShortcutKey.Icon.ResIdIcon(ShortcutHelperKeys.metaModifierIconResId)
+ }
+
+ fun onCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo?) {
+ customShortcutRepository.onCustomizationRequested(requestInfo)
+ }
+
+ suspend fun confirmAndSetShortcutCurrentlyBeingCustomized(): ShortcutCustomizationRequestResult {
+ return customShortcutRepository.confirmAndSetShortcutCurrentlyBeingCustomized()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
index 39fc27d35082..0381eaec5026 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
@@ -16,37 +16,66 @@
package com.android.systemui.keyboard.shortcut.domain.interactor
+import com.android.systemui.Flags.keyboardShortcutHelperShortcutCustomizer
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyboard.shortcut.data.repository.DefaultShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.qualifiers.CustomShortcutCategories
+import com.android.systemui.keyboard.shortcut.qualifiers.DefaultShortcutCategories
import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
@SysUISingleton
class ShortcutHelperCategoriesInteractor
@Inject
-constructor(categoriesRepository: DefaultShortcutCategoriesRepository) {
-
+constructor(
+ @DefaultShortcutCategories defaultCategoriesRepository: ShortcutCategoriesRepository,
+ @CustomShortcutCategories customCategoriesRepositoryLazy: Lazy<ShortcutCategoriesRepository>,
+) {
val shortcutCategories: Flow<List<ShortcutCategory>> =
- categoriesRepository.categories.map { categories ->
- categories.map { category -> groupSubCategoriesInCategory(category) }
+ defaultCategoriesRepository.categories.combine(
+ if (keyboardShortcutHelperShortcutCustomizer()) {
+ customCategoriesRepositoryLazy.get().categories
+ } else {
+ flowOf(emptyList())
+ }
+ ) { defaultShortcutCategories, customShortcutCategories ->
+ groupCategories(defaultShortcutCategories + customShortcutCategories)
}
- private fun groupSubCategoriesInCategory(shortcutCategory: ShortcutCategory): ShortcutCategory {
- val subCategoriesWithGroupedShortcuts =
- shortcutCategory.subCategories.map {
+ private fun groupCategories(
+ shortcutCategories: List<ShortcutCategory>
+ ): List<ShortcutCategory> {
+ return shortcutCategories
+ .groupBy { it.type }
+ .entries
+ .map { (categoryType, groupedCategories) ->
+ ShortcutCategory(
+ type = categoryType,
+ subCategories =
+ groupSubCategories(groupedCategories.flatMap { it.subCategories }),
+ )
+ }
+ }
+
+ private fun groupSubCategories(
+ subCategories: List<ShortcutSubCategory>
+ ): List<ShortcutSubCategory> {
+ return subCategories
+ .groupBy { it.label }
+ .entries
+ .map { (label, groupedSubcategories) ->
ShortcutSubCategory(
- label = it.label,
- shortcuts = groupShortcutsInSubcategory(it.shortcuts),
+ label = label,
+ shortcuts =
+ groupShortcutsInSubcategory(groupedSubcategories.flatMap { it.shortcuts }),
)
}
- return ShortcutCategory(
- type = shortcutCategory.type,
- subCategories = subCategoriesWithGroupedShortcuts,
- )
}
private fun groupShortcutsInSubcategory(shortcuts: List<Shortcut>) =
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CustomShortcutCategories.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CustomShortcutCategories.kt
new file mode 100644
index 000000000000..8acb9eebbd4d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/CustomShortcutCategories.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class CustomShortcutCategories
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/DefaultShortcutCategories.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/DefaultShortcutCategories.kt
new file mode 100644
index 000000000000..f94e10d17964
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/DefaultShortcutCategories.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class DefaultShortcutCategories
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/KeyCombination.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/KeyCombination.kt
new file mode 100644
index 000000000000..5e4031b29502
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/KeyCombination.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.shared.model
+
+data class KeyCombination(val modifiers: Int, val keyCode: Int?)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
index e44bfe30a8bb..310078a647e6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -17,10 +17,12 @@
package com.android.systemui.keyboard.shortcut.ui
import android.app.Dialog
+import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -33,6 +35,8 @@ import com.android.systemui.statusbar.phone.SystemUIDialogFactory
import com.android.systemui.statusbar.phone.create
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.launch
class ShortcutCustomizationDialogStarter
@AssistedInject
@@ -48,7 +52,7 @@ constructor(
viewModel.shortcutCustomizationUiState.collect { uiState ->
if (
uiState is ShortcutCustomizationUiState.AddShortcutDialog &&
- !uiState.isDialogShowing
+ !uiState.isDialogShowing
) {
dialog = createAddShortcutDialog().also { it.show() }
viewModel.onAddShortcutDialogShown()
@@ -57,6 +61,7 @@ constructor(
dialog = null
}
}
+ awaitCancellation()
}
fun onShortcutCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo) {
@@ -66,14 +71,28 @@ constructor(
private fun createAddShortcutDialog(): Dialog {
return dialogFactory.create(dialogDelegate = ShortcutCustomizationDialogDelegate()) { dialog
->
- val uiState by viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle()
+ val uiState by
+ viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle(
+ initialValue = ShortcutCustomizationUiState.Inactive
+ )
+ val coroutineScope = rememberCoroutineScope()
AssignNewShortcutDialog(
uiState = uiState,
- modifier = Modifier.width(364.dp).wrapContentHeight().padding(vertical = 24.dp),
+ modifier = Modifier
+ .width(364.dp)
+ .wrapContentHeight()
+ .padding(vertical = 24.dp),
onKeyPress = { viewModel.onKeyPressed(it) },
onCancel = { dialog.dismiss() },
+ onConfirmSetShortcut = {
+ coroutineScope.launch { viewModel.onSetShortcut() }
+ },
)
- dialog.setOnDismissListener { viewModel.onAddShortcutDialogDismissed() }
+ dialog.setOnDismissListener { viewModel.onDialogDismissed() }
+
+ // By default, apps cannot intercept action key. The system always handles it. This
+ // flag is needed to enable customisation dialog window to intercept action key
+ dialog.window?.addPrivateFlags(PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
index 43f0f200ab23..c9b778e96dd1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
@@ -39,18 +40,22 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.KeyEvent
-import androidx.compose.ui.input.key.onPreviewKeyEvent
+import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
import com.android.systemui.res.R
@@ -61,6 +66,7 @@ fun AssignNewShortcutDialog(
modifier: Modifier = Modifier,
onKeyPress: (KeyEvent) -> Boolean,
onCancel: () -> Unit,
+ onConfirmSetShortcut: () -> Unit,
) {
if (uiState is ShortcutCustomizationUiState.AddShortcutDialog) {
Column(modifier = modifier) {
@@ -79,17 +85,26 @@ fun AssignNewShortcutDialog(
defaultModifierKey = uiState.defaultCustomShortcutModifierKey,
)
SelectedKeyCombinationContainer(
- shouldShowErrorMessage = uiState.shouldShowErrorMessage,
+ shouldShowError = uiState.errorMessage.isNotEmpty(),
onKeyPress = onKeyPress,
+ pressedKeys = uiState.pressedKeys,
+ )
+ ErrorMessageContainer(uiState.errorMessage)
+ DialogButtons(
+ onCancel,
+ isSetShortcutButtonEnabled = uiState.pressedKeys.isNotEmpty(),
+ onConfirm = onConfirmSetShortcut,
)
- KeyCombinationAlreadyInUseErrorMessage(uiState.shouldShowErrorMessage)
- DialogButtons(onCancel, isValidKeyCombination = uiState.isValidKeyCombination)
}
}
}
@Composable
-fun DialogButtons(onCancel: () -> Unit, isValidKeyCombination: Boolean) {
+fun DialogButtons(
+ onCancel: () -> Unit,
+ isSetShortcutButtonEnabled: Boolean,
+ onConfirm: () -> Unit,
+) {
Row(
modifier =
Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp)
@@ -107,23 +122,23 @@ fun DialogButtons(onCancel: () -> Unit, isValidKeyCombination: Boolean) {
)
Spacer(modifier = Modifier.width(8.dp))
ShortcutHelperButton(
- onClick = {},
+ onClick = onConfirm,
color = MaterialTheme.colorScheme.primary,
width = 116.dp,
contentColor = MaterialTheme.colorScheme.onPrimary,
text =
stringResource(R.string.shortcut_helper_customize_dialog_set_shortcut_button_label),
- enabled = isValidKeyCombination,
+ enabled = isSetShortcutButtonEnabled,
)
}
}
@Composable
-fun KeyCombinationAlreadyInUseErrorMessage(shouldShowErrorMessage: Boolean) {
- if (shouldShowErrorMessage) {
+fun ErrorMessageContainer(errorMessage: String) {
+ if (errorMessage.isNotEmpty()) {
Box(modifier = Modifier.padding(horizontal = 16.dp).width(332.dp).height(40.dp)) {
Text(
- text = stringResource(R.string.shortcut_helper_customize_dialog_error_message),
+ text = errorMessage,
style = MaterialTheme.typography.bodyMedium,
fontSize = 14.sp,
lineHeight = 20.sp,
@@ -137,17 +152,19 @@ fun KeyCombinationAlreadyInUseErrorMessage(shouldShowErrorMessage: Boolean) {
@Composable
fun SelectedKeyCombinationContainer(
- keyCombination: String =
- stringResource(R.string.shortcut_helper_add_shortcut_dialog_placeholder),
- shouldShowErrorMessage: Boolean,
+ shouldShowError: Boolean,
onKeyPress: (KeyEvent) -> Boolean,
+ pressedKeys: List<ShortcutKey>,
) {
val interactionSource = remember { MutableInteractionSource() }
val isFocused by interactionSource.collectIsFocusedAsState()
val outlineColor =
if (!isFocused) MaterialTheme.colorScheme.outline
- else if (shouldShowErrorMessage) MaterialTheme.colorScheme.error
+ else if (shouldShowError) MaterialTheme.colorScheme.error
else MaterialTheme.colorScheme.primary
+ val focusRequester = remember { FocusRequester() }
+
+ LaunchedEffect(Unit) { focusRequester.requestFocus() }
ClickableShortcutSurface(
onClick = {},
@@ -157,24 +174,21 @@ fun SelectedKeyCombinationContainer(
Modifier.padding(all = 16.dp)
.sizeIn(minWidth = 332.dp, minHeight = 56.dp)
.border(width = 2.dp, color = outlineColor, shape = RoundedCornerShape(50.dp))
- .onPreviewKeyEvent { onKeyPress(it) },
+ .onKeyEvent { onKeyPress(it) }
+ .focusRequester(focusRequester),
interactionSource = interactionSource,
) {
Row(
modifier = Modifier.padding(start = 24.dp, top = 16.dp, end = 16.dp, bottom = 16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
- Text(
- text = keyCombination,
- style = MaterialTheme.typography.headlineSmall,
- fontSize = 16.sp,
- lineHeight = 24.sp,
- fontWeight = FontWeight.W500,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
- modifier = Modifier.width(252.dp),
- )
+ if (pressedKeys.isEmpty()) {
+ PressKeyPrompt()
+ } else {
+ PressedKeysTextContainer(pressedKeys)
+ }
Spacer(modifier = Modifier.weight(1f))
- if (shouldShowErrorMessage) {
+ if (shouldShowError) {
Icon(
imageVector = Icons.Default.ErrorOutline,
contentDescription = null,
@@ -187,6 +201,67 @@ fun SelectedKeyCombinationContainer(
}
@Composable
+private fun RowScope.PressedKeysTextContainer(pressedKeys: List<ShortcutKey>) {
+ pressedKeys.forEachIndexed { keyIndex, key ->
+ if (keyIndex > 0) {
+ ShortcutKeySeparator()
+ }
+ if (key is ShortcutKey.Text) {
+ ShortcutTextKey(key)
+ } else if (key is ShortcutKey.Icon) {
+ ShortcutIconKey(key)
+ }
+ }
+}
+
+@Composable
+private fun ShortcutKeySeparator() {
+ Text(
+ text = stringResource(id = R.string.shortcut_helper_plus_symbol),
+ style = MaterialTheme.typography.titleSmall,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+}
+
+@Composable
+private fun RowScope.ShortcutIconKey(key: ShortcutKey.Icon) {
+ Icon(
+ painter =
+ when (key) {
+ is ShortcutKey.Icon.ResIdIcon -> painterResource(key.drawableResId)
+ is ShortcutKey.Icon.DrawableIcon -> rememberDrawablePainter(drawable = key.drawable)
+ },
+ contentDescription = null,
+ modifier = Modifier.align(Alignment.CenterVertically).height(24.dp),
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+}
+
+@Composable
+private fun PressKeyPrompt() {
+ Text(
+ text = stringResource(id = R.string.shortcut_helper_add_shortcut_dialog_placeholder),
+ style = MaterialTheme.typography.titleSmall,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+}
+
+@Composable
+private fun ShortcutTextKey(key: ShortcutKey.Text) {
+ Text(
+ text = key.value,
+ style = MaterialTheme.typography.titleSmall,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+}
+
+@Composable
private fun Title(title: String, modifier: Modifier = Modifier) {
Text(
text = title,
@@ -203,8 +278,6 @@ private fun Description(modifier: Modifier = Modifier) {
Text(
text = stringResource(id = R.string.shortcut_helper_customize_mode_sub_title),
style = MaterialTheme.typography.bodyMedium,
- fontSize = 14.sp,
- lineHeight = 20.sp,
modifier = modifier.wrapContentSize(Alignment.Center),
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
index e9f2a3b8e5b3..adadeebd0769 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutCustomizationUiState.kt
@@ -21,10 +21,10 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
sealed interface ShortcutCustomizationUiState {
data class AddShortcutDialog(
val shortcutLabel: String,
- val shouldShowErrorMessage: Boolean,
- val isValidKeyCombination: Boolean,
+ val errorMessage: String = "",
val defaultCustomShortcutModifierKey: ShortcutKey.Icon.ResIdIcon,
val isDialogShowing: Boolean,
+ val pressedKeys: List<ShortcutKey> = emptyList(),
) : ShortcutCustomizationUiState
data object Inactive : ShortcutCustomizationUiState
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
index e86da5d25b22..8178c6a1c705 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
@@ -16,26 +16,51 @@
package com.android.systemui.keyboard.shortcut.ui.viewmodel
-import androidx.compose.runtime.mutableStateOf
+import android.content.Context
+import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEvent
+import androidx.compose.ui.input.key.KeyEventType
+import androidx.compose.ui.input.key.isMetaPressed
+import androidx.compose.ui.input.key.key
+import androidx.compose.ui.input.key.nativeKeyCode
+import androidx.compose.ui.input.key.type
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutCustomizationInteractor
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
+import com.android.systemui.res.R
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
class ShortcutCustomizationViewModel
@AssistedInject
-constructor(private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor) {
- private val _shortcutBeingCustomized = mutableStateOf<ShortcutCustomizationRequestInfo?>(null)
-
+constructor(
+ private val context: Context,
+ private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor,
+) {
private val _shortcutCustomizationUiState =
MutableStateFlow<ShortcutCustomizationUiState>(ShortcutCustomizationUiState.Inactive)
- val shortcutCustomizationUiState = _shortcutCustomizationUiState.asStateFlow()
+ val shortcutCustomizationUiState =
+ shortcutCustomizationInteractor.pressedKeys
+ .map { keys ->
+ // Note that Action Key is excluded as it's already displayed on the UI
+ keys.filter {
+ it != shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey()
+ }
+ }
+ .combine(_shortcutCustomizationUiState) { keys, uiState ->
+ if (uiState is ShortcutCustomizationUiState.AddShortcutDialog) {
+ uiState.copy(pressedKeys = keys)
+ } else {
+ uiState
+ }
+ }
fun onShortcutCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo) {
when (requestInfo) {
@@ -43,13 +68,12 @@ constructor(private val shortcutCustomizationInteractor: ShortcutCustomizationIn
_shortcutCustomizationUiState.value =
ShortcutCustomizationUiState.AddShortcutDialog(
shortcutLabel = requestInfo.label,
- shouldShowErrorMessage = false,
- isValidKeyCombination = false,
defaultCustomShortcutModifierKey =
shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey(),
isDialogShowing = false,
+ pressedKeys = emptyList(),
)
- _shortcutBeingCustomized.value = requestInfo
+ shortcutCustomizationInteractor.onCustomizationRequested(requestInfo)
}
}
}
@@ -62,18 +86,82 @@ constructor(private val shortcutCustomizationInteractor: ShortcutCustomizationIn
}
}
- fun onAddShortcutDialogDismissed() {
- _shortcutBeingCustomized.value = null
+ fun onDialogDismissed() {
_shortcutCustomizationUiState.value = ShortcutCustomizationUiState.Inactive
+ shortcutCustomizationInteractor.onCustomizationRequested(null)
+ shortcutCustomizationInteractor.updateUserSelectedKeyCombination(null)
}
fun onKeyPressed(keyEvent: KeyEvent): Boolean {
- // TODO Not yet implemented b/373638584
+ if ((keyEvent.isMetaPressed && keyEvent.type == KeyEventType.KeyDown)) {
+ updatePressedKeys(keyEvent)
+ return true
+ }
return false
}
+ suspend fun onSetShortcut() {
+ val result = shortcutCustomizationInteractor.confirmAndSetShortcutCurrentlyBeingCustomized()
+
+ _shortcutCustomizationUiState.update { uiState ->
+ when (result) {
+ ShortcutCustomizationRequestResult.SUCCESS -> ShortcutCustomizationUiState.Inactive
+ ShortcutCustomizationRequestResult.ERROR_RESERVED_COMBINATION -> {
+ getUiStateWithErrorMessage(
+ uiState = uiState,
+ errorMessage =
+ context.getString(
+ R.string.shortcut_customizer_key_combination_in_use_error_message
+ ),
+ )
+ }
+ ShortcutCustomizationRequestResult.ERROR_OTHER ->
+ getUiStateWithErrorMessage(
+ uiState = uiState,
+ errorMessage =
+ context.getString(R.string.shortcut_customizer_generic_error_message),
+ )
+ }
+ }
+ }
+
+ private fun getUiStateWithErrorMessage(
+ uiState: ShortcutCustomizationUiState,
+ errorMessage: String,
+ ): ShortcutCustomizationUiState {
+ return (uiState as? ShortcutCustomizationUiState.AddShortcutDialog)?.copy(
+ errorMessage = errorMessage
+ ) ?: uiState
+ }
+
+ private fun updatePressedKeys(keyEvent: KeyEvent) {
+ val isModifier = SUPPORTED_MODIFIERS.contains(keyEvent.key)
+ val keyCombination =
+ KeyCombination(
+ modifiers = keyEvent.nativeKeyEvent.modifiers,
+ keyCode = if (!isModifier) keyEvent.key.nativeKeyCode else null,
+ )
+ shortcutCustomizationInteractor.updateUserSelectedKeyCombination(keyCombination)
+ }
+
@AssistedFactory
interface Factory {
fun create(): ShortcutCustomizationViewModel
}
+
+ companion object {
+ private val SUPPORTED_MODIFIERS =
+ listOf(
+ Key.MetaLeft,
+ Key.MetaRight,
+ Key.CtrlRight,
+ Key.CtrlLeft,
+ Key.AltLeft,
+ Key.AltRight,
+ Key.ShiftLeft,
+ Key.ShiftRight,
+ Key.Function,
+ Key.Symbol,
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
index 912bfe99cea8..08fd0af81006 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -123,7 +123,7 @@ constructor(
userContext.packageManager.getApplicationIcon(type.packageName)
IconSource(painter = DrawablePainter(drawable = iconDrawable))
} catch (e: NameNotFoundException) {
- Log.wtf(
+ Log.w(
"ShortcutHelperViewModel",
"Package not found when retrieving icon for ${type.packageName}",
)
@@ -153,7 +153,7 @@ constructor(
packageManagerForUser.getApplicationInfo(type.packageName, /* flags= */ 0)
return packageManagerForUser.getApplicationLabel(currentAppInfo).toString()
} catch (e: NameNotFoundException) {
- Log.wtf(
+ Log.w(
"ShortcutHelperViewModel",
"Package Not found when retrieving Label for ${type.packageName}",
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 32c2bc7c8620..7097c1d2fc4e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -662,7 +662,9 @@ public class KeyguardService extends Service {
trace("doKeyguardTimeout");
checkPermission();
- if (KeyguardWmStateRefactor.isEnabled()) {
+ if (SceneContainerFlag.isEnabled()) {
+ mDeviceEntryInteractorLazy.get().lockNow();
+ } else if (KeyguardWmStateRefactor.isEnabled()) {
mKeyguardLockWhileAwakeInteractor.onKeyguardServiceDoKeyguardTimeout(options);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
index 80675d373b8e..a45204d41718 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
@@ -28,6 +28,7 @@ object BuiltInKeyguardQuickAffordanceKeys {
const val CREATE_NOTE = "create_note"
const val DO_NOT_DISTURB = "do_not_disturb"
const val FLASHLIGHT = "flashlight"
+ const val GLANCEABLE_HUB = "glanceable_hub"
const val HOME_CONTROLS = "home"
const val MUTE = "mute"
const val QR_CODE_SCANNER = "qr_code_scanner"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
new file mode 100644
index 000000000000..0b78be128c69
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.quickaffordance
+
+import android.content.Context
+import android.util.Log
+import com.android.systemui.Flags.glanceableHubShortcutButton
+import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.communal.data.repository.CommunalSceneRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
+
+/** Lockscreen affordance that opens the glanceable hub. */
+@SysUISingleton
+class GlanceableHubQuickAffordanceConfig
+@Inject
+constructor(
+ @Application private val context: Context,
+ private val communalSceneRepository: CommunalSceneRepository,
+ private val communalInteractor: CommunalInteractor,
+ private val sceneInteractor: SceneInteractor,
+) : KeyguardQuickAffordanceConfig {
+
+ private val pickerNameResourceId = R.string.glanceable_hub_lockscreen_affordance_label
+
+ override val key: String = BuiltInKeyguardQuickAffordanceKeys.GLANCEABLE_HUB
+
+ override fun pickerName(): String = context.getString(pickerNameResourceId)
+
+ override val pickerIconResourceId: Int
+ get() = R.drawable.ic_widgets
+
+ override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState>
+ get() = flow {
+ emit(
+ // TODO(b/378113263): Gate on getV2FlagEnabled() when ready.
+ if (!glanceableHubShortcutButton()) {
+ Log.i(TAG, "Button hidden on lockscreen: flag not enabled.")
+ KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+ } else if (!communalInteractor.isCommunalEnabled.value) {
+ Log.i(TAG, "Button hidden on lockscreen: hub not enabled in settings.")
+ KeyguardQuickAffordanceConfig.LockScreenState.Hidden
+ } else {
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon =
+ Icon.Resource(
+ pickerIconResourceId,
+ ContentDescription.Resource(pickerNameResourceId),
+ )
+ )
+ }
+ )
+ }
+
+ override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+ // TODO(b/378113263): Gate on getV2FlagEnabled() when ready.
+ return if (!glanceableHubShortcutButton()) {
+ Log.i(TAG, "Button unavailable in picker: flag not enabled.")
+ KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ } else if (!communalInteractor.isCommunalEnabled.value) {
+ Log.i(TAG, "Button disabled in picker: hub not enabled in settings.")
+ KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
+ context.getString(R.string.glanceable_hub_lockscreen_affordance_disabled_text)
+ )
+ } else {
+ KeyguardQuickAffordanceConfig.PickerScreenState.Default()
+ }
+ }
+
+ override fun onTriggered(
+ expandable: Expandable?
+ ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
+ if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.changeScene(Scenes.Communal, "lockscreen to communal from shortcut")
+ } else {
+ communalSceneRepository.changeScene(CommunalScenes.Communal, null)
+ }
+ return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+ }
+
+ companion object {
+ private const val TAG = "GlanceableHubQuickAffordanceConfig"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
index 45561959a7df..8c6fdb989daf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
@@ -26,7 +26,7 @@ import dagger.multibindings.ElementsIntoSet
interface KeyguardDataQuickAffordanceModule {
@Binds
fun providerClientFactory(
- impl: KeyguardQuickAffordanceProviderClientFactoryImpl,
+ impl: KeyguardQuickAffordanceProviderClientFactoryImpl
): KeyguardQuickAffordanceProviderClientFactory
companion object {
@@ -36,6 +36,7 @@ interface KeyguardDataQuickAffordanceModule {
camera: CameraQuickAffordanceConfig,
doNotDisturb: DoNotDisturbQuickAffordanceConfig,
flashlight: FlashlightQuickAffordanceConfig,
+ glanceableHub: GlanceableHubQuickAffordanceConfig,
home: HomeControlsKeyguardQuickAffordanceConfig,
mute: MuteQuickAffordanceConfig,
quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
@@ -46,6 +47,7 @@ interface KeyguardDataQuickAffordanceModule {
camera,
doNotDisturb,
flashlight,
+ glanceableHub,
home,
mute,
quickAccessWallet,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index f473a82138e6..364b1a9731cc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -202,30 +202,6 @@ constructor(
.distinctUntilChanged()
}
- /**
- * Scenes that are part of the keyguard and are shown when the device is locked or when the
- * keyguard still needs to be dismissed.
- */
- private val keyguardScenes = setOf(Scenes.Lockscreen, Scenes.Bouncer, Scenes.Communal)
-
- /**
- * Scenes that don't belong in the keyguard family and cannot show when the device is locked or
- * when the keyguard still needs to be dismissed.
- */
- private val nonKeyguardScenes = setOf(Scenes.Gone)
-
- /**
- * Scenes that can show regardless of device lock or keyguard dismissal states. Other sources of
- * state need to be consulted to know whether the device has been entered or not.
- */
- private val keyguardAgnosticScenes =
- setOf(
- Scenes.Shade,
- Scenes.QuickSettings,
- Overlays.NotificationsShade,
- Overlays.QuickSettingsShade,
- )
-
private val lockscreenVisibilityWithScenes =
combine(
sceneInteractor.get().transitionState.flatMapLatestConflated {
@@ -355,4 +331,30 @@ constructor(
!BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode)
}
.distinctUntilChanged()
+
+ companion object {
+ /**
+ * Scenes that are part of the keyguard and are shown when the device is locked or when the
+ * keyguard still needs to be dismissed.
+ */
+ val keyguardScenes = setOf(Scenes.Lockscreen, Scenes.Bouncer, Scenes.Communal, Scenes.Dream)
+
+ /**
+ * Scenes that don't belong in the keyguard family and cannot show when the device is locked
+ * or when the keyguard still needs to be dismissed.
+ */
+ private val nonKeyguardScenes = setOf(Scenes.Gone)
+
+ /**
+ * Scenes that can show regardless of device lock or keyguard dismissal states. Other
+ * sources of state need to be consulted to know whether the device has been entered or not.
+ */
+ private val keyguardAgnosticScenes =
+ setOf(
+ Scenes.Shade,
+ Scenes.QuickSettings,
+ Overlays.NotificationsShade,
+ Overlays.QuickSettingsShade,
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
index b51bb7b229ee..aa7eb2933992 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
@@ -28,6 +28,7 @@ import androidx.annotation.VisibleForTesting
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.android.systemui.biometrics.AuthController
+import com.android.systemui.customization.R as customR
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -115,7 +116,7 @@ constructor(
val scaleFactor: Float = authController.scaleFactor
val mBottomPaddingPx =
- context.resources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom)
+ context.resources.getDimensionPixelSize(customR.dimen.lock_icon_margin_bottom)
val bounds = windowManager.currentWindowMetrics.bounds
var widthPixels = bounds.right.toFloat()
if (featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE)) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
index 5065fcbbac93..19652525bee0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
@@ -31,8 +31,10 @@ import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.math.roundToInt
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
@@ -40,6 +42,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
/** Models the UI state for the device entry icon foreground view (displayed icon). */
+@OptIn(FlowPreview::class)
@ExperimentalCoroutinesApi
@SysUISingleton
class DeviceEntryForegroundViewModel
@@ -97,7 +100,7 @@ constructor(
private val padding: Flow<Int> =
deviceEntryUdfpsInteractor.isUdfpsSupported.flatMapLatest { udfpsSupported ->
if (udfpsSupported) {
- udfpsOverlayInteractor.iconPadding
+ udfpsOverlayInteractor.iconPadding.debounce(udfpsPaddingDebounceDuration.toLong())
} else {
configurationInteractor.scaleForResolution.map { scale ->
(context.resources.getDimensionPixelSize(R.dimen.lock_icon_padding) * scale)
@@ -120,6 +123,9 @@ constructor(
)
}
+ private val udfpsPaddingDebounceDuration: Int
+ get() = context.resources.getInteger(R.integer.udfps_padding_debounce_duration)
+
data class ForegroundIconViewModel(
val type: DeviceEntryIconView.IconType,
val useAodVariant: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
index 6adf3e9894bd..a249793798ed 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModel.kt
@@ -25,6 +25,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow.FlowBuilder
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.SysuiStatusBarStateController
import javax.inject.Inject
@@ -50,9 +51,7 @@ constructor(
duration = FromLockscreenTransitionInteractor.TO_GONE_DURATION,
edge = Edge.create(from = LOCKSCREEN, to = Scenes.Gone),
)
- .setupWithoutSceneContainer(
- edge = Edge.create(from = LOCKSCREEN, to = GONE),
- )
+ .setupWithoutSceneContainer(edge = Edge.create(from = LOCKSCREEN, to = GONE))
val shortcutsAlpha: Flow<Float> =
transitionAnimation.sharedFlow(
@@ -65,6 +64,10 @@ constructor(
fun notificationAlpha(viewState: ViewStateAccessor): Flow<Float> {
var startAlpha = 1f
var leaveShadeOpen = false
+ val endAction: (() -> Float)? =
+ if (SceneContainerFlag.isEnabled) {
+ { 1f }
+ } else null
return transitionAnimation.sharedFlow(
duration = 80.milliseconds,
@@ -79,6 +82,8 @@ constructor(
MathUtils.lerp(startAlpha, 0f, it)
}
},
+ onFinish = endAction,
+ onCancel = endAction,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl b/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl
index 3e947d9d2b16..7803f229dda7 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl
+++ b/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl
@@ -16,6 +16,7 @@
package com.android.systemui.notetask;
+import com.android.systemui.notetask.NoteTaskBubbleExpandBehavior;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.os.UserHandle;
@@ -25,5 +26,6 @@ interface INoteTaskBubblesService {
boolean areBubblesAvailable();
- void showOrHideAppBubble(in Intent intent, in UserHandle userHandle, in Icon icon);
+ void showOrHideAppBubble(in Intent intent, in UserHandle userHandle, in Icon icon,
+ in NoteTaskBubbleExpandBehavior bubbleExpandBehavior);
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.aidl b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.aidl
new file mode 100644
index 000000000000..86a06a568a4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.aidl
@@ -0,0 +1,3 @@
+package com.android.systemui.notetask;
+
+parcelable NoteTaskBubbleExpandBehavior; \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.kt
new file mode 100644
index 000000000000..63b38a1b73f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubbleExpandBehavior.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.notetask
+
+import android.os.Parcel
+import android.os.Parcelable
+
+enum class NoteTaskBubbleExpandBehavior : Parcelable {
+ /**
+ * The default bubble expand behavior for note task bubble: The bubble will collapse if there is
+ * already an expanded bubble, The bubble will expand if there is a collapsed bubble.
+ */
+ DEFAULT,
+ /**
+ * The special bubble expand behavior for note task bubble: The bubble will stay expanded, not
+ * collapse, if there is already an expanded bubble, The bubble will expand if there is a
+ * collapsed bubble.
+ */
+ KEEP_IF_EXPANDED;
+
+ override fun describeContents(): Int {
+ return 0
+ }
+
+ override fun writeToParcel(dest: Parcel, flags: Int) {
+ dest.writeString(name)
+ }
+
+ companion object CREATOR : Parcelable.Creator<NoteTaskBubbleExpandBehavior> {
+ override fun createFromParcel(parcel: Parcel?): NoteTaskBubbleExpandBehavior {
+ return parcel?.readString()?.let { valueOf(it) } ?: DEFAULT
+ }
+
+ override fun newArray(size: Int) = arrayOfNulls<NoteTaskBubbleExpandBehavior>(size)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt
index ec205f87d9fa..169285f6742e 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt
@@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.log.DebugLogger.debugLog
+import com.android.wm.shell.bubbles.Bubble
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
import javax.inject.Inject
@@ -48,7 +49,7 @@ open class NoteTaskBubblesController
@Inject
constructor(
@Application private val context: Context,
- @Background private val bgDispatcher: CoroutineDispatcher
+ @Background private val bgDispatcher: CoroutineDispatcher,
) {
private val serviceConnector: ServiceConnector<INoteTaskBubblesService> =
@@ -57,7 +58,7 @@ constructor(
Intent(context, NoteTaskBubblesService::class.java),
Context.BIND_AUTO_CREATE or Context.BIND_WAIVE_PRIORITY or Context.BIND_NOT_VISIBLE,
UserHandle.USER_SYSTEM,
- INoteTaskBubblesService.Stub::asInterface
+ INoteTaskBubblesService.Stub::asInterface,
)
/** Returns whether notes app bubble is supported. */
@@ -79,11 +80,12 @@ constructor(
open suspend fun showOrHideAppBubble(
intent: Intent,
userHandle: UserHandle,
- icon: Icon
+ icon: Icon,
+ bubbleExpandBehavior: NoteTaskBubbleExpandBehavior,
) {
withContext(bgDispatcher) {
serviceConnector
- .post { it.showOrHideAppBubble(intent, userHandle, icon) }
+ .post { it.showOrHideAppBubble(intent, userHandle, icon, bubbleExpandBehavior) }
.whenComplete { _, error ->
if (error != null) {
debugLog(error = error) {
@@ -120,16 +122,28 @@ constructor(
override fun showOrHideAppBubble(
intent: Intent,
userHandle: UserHandle,
- icon: Icon
+ icon: Icon,
+ bubbleExpandBehavior: NoteTaskBubbleExpandBehavior,
) {
mOptionalBubbles.ifPresentOrElse(
- { bubbles -> bubbles.showOrHideAppBubble(intent, userHandle, icon) },
+ { bubbles ->
+ if (
+ bubbleExpandBehavior ==
+ NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED &&
+ bubbles.isBubbleExpanded(
+ Bubble.getAppBubbleKeyForApp(intent.`package`, userHandle)
+ )
+ ) {
+ return@ifPresentOrElse
+ }
+ bubbles.showOrHideAppBubble(intent, userHandle, icon)
+ },
{
debugLog {
"Failed to show or hide bubble for intent $intent," +
"user $user, and icon $icon as bubble is empty."
}
- }
+ },
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 1fa5baaa21ae..ad1f37070c9d 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -43,6 +43,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
@@ -84,7 +85,7 @@ constructor(
private val userTracker: UserTracker,
private val secureSettings: SecureSettings,
@Application private val applicationScope: CoroutineScope,
- @Background private val bgCoroutineContext: CoroutineContext
+ @Background private val bgCoroutineContext: CoroutineContext,
) {
@VisibleForTesting val infoReference = AtomicReference<NoteTaskInfo?>()
@@ -98,7 +99,7 @@ constructor(
if (key != Bubble.getAppBubbleKeyForApp(info.packageName, info.user)) return
// Safe guard mechanism, this callback should only be called for app bubbles.
- if (info.launchMode != NoteTaskLaunchMode.AppBubble) return
+ if (info.launchMode !is NoteTaskLaunchMode.AppBubble) return
if (isExpanding) {
debugLog { "onBubbleExpandChanged - expanding: $info" }
@@ -117,10 +118,7 @@ constructor(
} else {
getUserForHandlingNotesTaking(entryPoint)
}
- activityContext.startActivityAsUser(
- createNotesRoleHolderSettingsIntent(),
- user
- )
+ activityContext.startActivityAsUser(createNotesRoleHolderSettingsIntent(), user)
}
/**
@@ -140,8 +138,7 @@ constructor(
entryPoint == QUICK_AFFORDANCE -> {
userTracker.userProfiles
.firstOrNull { userManager.isManagedProfile(it.id) }
- ?.userHandle
- ?: userTracker.userHandle
+ ?.userHandle ?: userTracker.userHandle
}
// On work profile devices, SysUI always run in the main user.
else -> userTracker.userHandle
@@ -158,19 +155,14 @@ constructor(
*
* That will let users open other apps in full screen, and take contextual notes.
*/
- fun showNoteTask(
- entryPoint: NoteTaskEntryPoint,
- ) {
+ fun showNoteTask(entryPoint: NoteTaskEntryPoint) {
if (!isEnabled) return
showNoteTaskAsUser(entryPoint, getUserForHandlingNotesTaking(entryPoint))
}
/** A variant of [showNoteTask] which launches note task in the given [user]. */
- fun showNoteTaskAsUser(
- entryPoint: NoteTaskEntryPoint,
- user: UserHandle,
- ) {
+ fun showNoteTaskAsUser(entryPoint: NoteTaskEntryPoint, user: UserHandle) {
if (!isEnabled) return
applicationScope.launch("$TAG#showNoteTaskAsUser") {
@@ -178,10 +170,7 @@ constructor(
}
}
- private suspend fun awaitShowNoteTaskAsUser(
- entryPoint: NoteTaskEntryPoint,
- user: UserHandle,
- ) {
+ private suspend fun awaitShowNoteTaskAsUser(entryPoint: NoteTaskEntryPoint, user: UserHandle) {
if (!isEnabled) return
if (!noteTaskBubblesController.areBubblesAvailable()) {
@@ -217,12 +206,26 @@ constructor(
try {
// TODO(b/266686199): We should handle when app not available. For now, we log.
debugLog { "onShowNoteTask - start: $info on user#${user.identifier}" }
+ val useStylusMode =
+ when {
+ info.entryPoint == TAIL_BUTTON -> true
+ info.entryPoint == KEYBOARD_SHORTCUT -> false
+ else ->
+ context.resources.getInteger(R.integer.config_preferredNotesMode) ==
+ PREFERRED_NOTES_MODE_STYLUS
+ }
when (info.launchMode) {
is NoteTaskLaunchMode.AppBubble -> {
- val intent = createNoteTaskIntent(info)
+ val intent = createNoteTaskIntent(info, useStylusMode)
val icon =
Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
- noteTaskBubblesController.showOrHideAppBubble(intent, user, icon)
+ noteTaskBubblesController.showOrHideAppBubble(
+ intent,
+ user,
+ icon,
+ info.launchMode.bubbleExpandBehavior,
+ )
+
// App bubble logging happens on `onBubbleExpandChanged`.
debugLog { "onShowNoteTask - opened as app bubble: $info" }
}
@@ -234,7 +237,7 @@ constructor(
eventLogger.logNoteTaskClosed(info)
debugLog { "onShowNoteTask - closed as activity: $info" }
} else {
- val intent = createNoteTaskIntent(info)
+ val intent = createNoteTaskIntent(info, useStylusMode)
context.startActivityAsUser(intent, user)
eventLogger.logNoteTaskOpened(info)
debugLog { "onShowNoteTask - opened as activity: $info" }
@@ -398,20 +401,21 @@ constructor(
*/
const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
+ const val PREFERRED_NOTES_MODE_STYLUS = 1
+
/** Returns notes role holder settings intent. */
- fun createNotesRoleHolderSettingsIntent() = Intent(Intent.ACTION_MANAGE_DEFAULT_APP).
- putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES)
+ fun createNotesRoleHolderSettingsIntent() =
+ Intent(Intent.ACTION_MANAGE_DEFAULT_APP).putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES)
}
}
/** Creates an [Intent] for [ROLE_NOTES]. */
-private fun createNoteTaskIntent(info: NoteTaskInfo): Intent =
+private fun createNoteTaskIntent(info: NoteTaskInfo, useStylusMode: Boolean): Intent =
Intent(Intent.ACTION_CREATE_NOTE).apply {
setPackage(info.packageName)
// EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint
// was used to start the note task.
- val useStylusMode = info.entryPoint != NoteTaskEntryPoint.KEYBOARD_SHORTCUT
putExtra(Intent.EXTRA_USE_STYLUS_MODE, useStylusMode)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfo.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfo.kt
index 269eb870686c..8319e07525d8 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfo.kt
@@ -31,6 +31,10 @@ data class NoteTaskInfo(
if (isKeyguardLocked || entryPoint == WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE) {
NoteTaskLaunchMode.Activity
} else {
- NoteTaskLaunchMode.AppBubble
+ if (entryPoint == NoteTaskEntryPoint.QS_NOTES_TILE) {
+ NoteTaskLaunchMode.AppBubble(NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED)
+ } else {
+ NoteTaskLaunchMode.AppBubble(NoteTaskBubbleExpandBehavior.DEFAULT)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskLaunchMode.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskLaunchMode.kt
index 836e103f4d69..6c85f20f2bce 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskLaunchMode.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskLaunchMode.kt
@@ -26,7 +26,8 @@ import com.android.wm.shell.bubbles.Bubbles
sealed class NoteTaskLaunchMode {
/** @see Bubbles.showOrHideAppBubble */
- object AppBubble : NoteTaskLaunchMode()
+ data class AppBubble(val bubbleExpandBehavior: NoteTaskBubbleExpandBehavior) :
+ NoteTaskLaunchMode()
/** @see Context.startActivity */
object Activity : NoteTaskLaunchMode()
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
index a1c5c9c682c3..5d5465633f9f 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
@@ -41,6 +41,7 @@ import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
import com.android.systemui.res.R
import dagger.Binds
import dagger.Module
@@ -106,12 +107,14 @@ interface NoteTaskModule {
stateInteractor: NotesTileDataInteractor,
userActionInteractor: NotesTileUserActionInteractor,
): QSTileViewModel =
- factory.create(
- TileSpec.create(NOTES_TILE_SPEC),
- userActionInteractor,
- stateInteractor,
- mapper,
- )
+ if (com.android.systemui.Flags.qsNewTilesFuture())
+ factory.create(
+ TileSpec.create(NOTES_TILE_SPEC),
+ userActionInteractor,
+ stateInteractor,
+ mapper,
+ )
+ else StubQSTileViewModel
@Provides
@IntoMap
@@ -120,10 +123,10 @@ interface NoteTaskModule {
QSTileConfig(
tileSpec = TileSpec.create(NOTES_TILE_SPEC),
uiConfig =
- QSTileUIConfig.Resource(
- iconRes = R.drawable.ic_qs_notes,
- labelRes = R.string.quick_settings_notes_label,
- ),
+ QSTileUIConfig.Resource(
+ iconRes = R.drawable.ic_qs_notes,
+ labelRes = R.string.quick_settings_notes_label,
+ ),
instanceId = uiEventLogger.getNewInstanceId(),
category = TileCategory.UTILITIES,
)
diff --git a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
index 776a8f47f056..c57b53bab442 100644
--- a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
@@ -26,6 +26,9 @@ enum class WakeSleepReason(
/** The physical power button was pressed to wake up or sleep the device. */
POWER_BUTTON(isTouch = false, PowerManager.WAKE_REASON_POWER_BUTTON),
+ /** The sleep button was pressed to sleep the device. */
+ SLEEP_BUTTON(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON),
+
/** The user has tapped or double tapped to wake the screen. */
TAP(isTouch = true, PowerManager.WAKE_REASON_TAP),
@@ -78,6 +81,7 @@ enum class WakeSleepReason(
fun fromPowerManagerSleepReason(reason: Int): WakeSleepReason {
return when (reason) {
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON -> POWER_BUTTON
+ PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON -> SLEEP_BUTTON
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT -> TIMEOUT
PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD -> FOLD
else -> OTHER
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
index 8b0694219630..0d464f5a0936 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
@@ -28,6 +28,7 @@ import com.android.systemui.qs.pipeline.data.repository.TileSpecRepository.Compa
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
@@ -48,7 +49,7 @@ class QSHostAdapter
@Inject
constructor(
private val interactor: CurrentTilesInteractor,
- private val context: Context,
+ @ShadeDisplayAware private val context: Context,
private val tileServiceRequestControllerBuilder: TileServiceRequestController.Builder,
@Application private val scope: CoroutineScope,
dumpManager: DumpManager,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
index d38f8492c883..88f0318c2fbf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
@@ -87,6 +87,7 @@ import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig;
import com.android.systemui.res.R;
import com.android.systemui.security.data.model.SecurityModel;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.SecurityController;
@@ -177,7 +178,7 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
@Inject
QSSecurityFooterUtils(
- @Application Context context, DevicePolicyManager devicePolicyManager,
+ @ShadeDisplayAware Context context, DevicePolicyManager devicePolicyManager,
UserTracker userTracker, @Main Handler mainHandler, ActivityStarter activityStarter,
SecurityController securityController, @Background Looper bgLooper,
DialogTransitionAnimator dialogTransitionAnimator) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
index 676f6a426264..2ec729223a8d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
@@ -20,6 +20,7 @@ import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.Utils
import dagger.Module
import dagger.Provides
@@ -34,7 +35,7 @@ interface QSFragmentComposeModule {
@Provides
@SysUISingleton
@Named(QS_USING_MEDIA_PLAYER)
- fun providesUsingMedia(@Application context: Context): Boolean {
+ fun providesUsingMedia(@ShadeDisplayAware context: Context): Boolean {
return QSComposeFragment.isEnabled && Utils.useQsMediaPlayer(context)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 89f85ab14dd6..15e34990e111 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -43,6 +43,7 @@ import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon;
import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.ShadeDisplayAware;
import java.util.ArrayList;
import java.util.Arrays;
@@ -69,7 +70,7 @@ public class TileQueryHelper {
@Inject
public TileQueryHelper(
- Context context,
+ @ShadeDisplayAware Context context,
UserTracker userTracker,
@Main Executor mainExecutor,
@Background Executor bgExecutor
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index 564bc78a3f98..8ef637545e69 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -37,6 +37,7 @@ import com.android.systemui.qs.footer.data.model.UserSwitcherStatusModel
import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractor
import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.icuMessageFormat
import javax.inject.Inject
import javax.inject.Named
@@ -112,7 +113,7 @@ class FooterActionsViewModel(
class Factory
@Inject
constructor(
- @Application private val context: Context,
+ @ShadeDisplayAware private val context: Context,
private val falsingManager: FalsingManager,
private val footerActionsInteractor: FooterActionsInteractor,
private val globalActionsDialogLiteProvider: Provider<GlobalActionsDialogLite>,
@@ -175,7 +176,7 @@ class FooterActionsViewModel(
}
fun FooterActionsViewModel(
- @Application appContext: Context,
+ @ShadeDisplayAware appContext: Context,
footerActionsInteractor: FooterActionsInteractor,
falsingManager: FalsingManager,
globalActionsDialogLite: GlobalActionsDialogLite,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index 4e094cc77eae..789fdebc36eb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -16,12 +16,17 @@
package com.android.systemui.qs.panels.ui.compose
-import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.requiredHeight
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -39,16 +44,17 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.padding
import com.android.systemui.compose.modifiers.sysuiResTag
+import com.android.systemui.development.ui.compose.BuildNumber
+import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType
-import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.FooterHeight
-import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.InterPageSpacing
+import com.android.systemui.qs.panels.ui.compose.Dimensions.FooterHeight
+import com.android.systemui.qs.panels.ui.compose.Dimensions.InterPageSpacing
import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.ui.compose.borderOnFocus
@@ -121,38 +127,78 @@ constructor(
TileGrid(tiles = page, modifier = Modifier, editModeStart = {})
}
}
- // Use requiredHeight so it won't be squished if the view doesn't quite fit. As this is
- // expected to be inside a scrollable container, this should not be an issue.
- Box(modifier = Modifier.requiredHeight(FooterHeight).fillMaxWidth()) {
- PagerDots(
- pagerState = pagerState,
- activeColor = MaterialTheme.colorScheme.primary,
- nonActiveColor = MaterialTheme.colorScheme.surfaceVariant,
- modifier = Modifier.align(Alignment.Center),
- )
- CompositionLocalProvider(value = LocalContentColor provides Color.White) {
- IconButton(
- onClick = editModeStart,
- shape = RoundedCornerShape(CornerSize(28.dp)),
- modifier =
- Modifier.align(Alignment.CenterEnd)
- .borderOnFocus(
- color = MaterialTheme.colorScheme.secondary,
- cornerSize = CornerSize(FooterHeight / 2),
- ),
- ) {
- Icon(
- imageVector = Icons.Default.Edit,
- contentDescription = stringResource(id = R.string.qs_edit),
+ FooterBar(
+ buildNumberViewModelFactory = viewModel.buildNumberViewModelFactory,
+ pagerState = pagerState,
+ editModeStart = editModeStart,
+ )
+ }
+ }
+}
+
+private object Dimensions {
+ val FooterHeight = 48.dp
+ val InterPageSpacing = 16.dp
+}
+
+@Composable
+private fun FooterBar(
+ buildNumberViewModelFactory: BuildNumberViewModel.Factory,
+ pagerState: PagerState,
+ editModeStart: () -> Unit,
+) {
+ // Use requiredHeight so it won't be squished if the view doesn't quite fit. As this is
+ // expected to be inside a scrollable container, this should not be an issue.
+ // Also, we construct the layout this way to do the following:
+ // * PagerDots is centered in the row, taking as much space as it needs.
+ // * On the start side, we place the BuildNumber, taking as much space as it needs, but
+ // constrained by the available space left over after PagerDots
+ // * On the end side, we place the edit mode button, with the same constraints as for
+ // BuildNumber (but it will usually fit, as it's just a square button).
+ Row(
+ modifier = Modifier.requiredHeight(FooterHeight).fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = spacedBy(8.dp),
+ ) {
+ Row(Modifier.weight(1f)) {
+ BuildNumber(
+ viewModelFactory = buildNumberViewModelFactory,
+ textColor = MaterialTheme.colorScheme.onSurface,
+ modifier =
+ Modifier.borderOnFocus(
+ color = MaterialTheme.colorScheme.secondary,
+ cornerSize = CornerSize(1.dp),
)
- }
+ .wrapContentSize(),
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ }
+ PagerDots(
+ pagerState = pagerState,
+ activeColor = MaterialTheme.colorScheme.primary,
+ nonActiveColor = MaterialTheme.colorScheme.surfaceVariant,
+ modifier = Modifier.wrapContentWidth(),
+ )
+ Row(Modifier.weight(1f)) {
+ Spacer(modifier = Modifier.weight(1f))
+ CompositionLocalProvider(
+ value = LocalContentColor provides MaterialTheme.colorScheme.onSurface
+ ) {
+ IconButton(
+ onClick = editModeStart,
+ shape = RoundedCornerShape(CornerSize(28.dp)),
+ modifier =
+ Modifier.borderOnFocus(
+ color = MaterialTheme.colorScheme.secondary,
+ cornerSize = CornerSize(FooterHeight / 2),
+ ),
+ ) {
+ Icon(
+ imageVector = Icons.Default.Edit,
+ contentDescription = stringResource(id = R.string.qs_edit),
+ )
}
}
}
}
-
- private object Dimensions {
- val FooterHeight = 48.dp
- val InterPageSpacing = 16.dp
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index cb57c6710553..0a80a19871fd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -126,7 +126,7 @@ fun Tile(
val currentBounceableInfo by rememberUpdatedState(bounceableInfo)
val resources = resources()
val uiState = remember(state, resources) { state.toUiState(resources) }
- val colors = TileDefaults.getColorForState(uiState)
+ val colors = TileDefaults.getColorForState(uiState, iconOnly)
val hapticsViewModel: TileHapticsViewModel? =
rememberViewModel(traceName = "TileHapticsViewModel") {
tileHapticsViewModelFactoryProvider.getHapticsViewModelFactory()?.create(tile)
@@ -365,22 +365,24 @@ private object TileDefaults {
)
@Composable
- fun getColorForState(uiState: TileUiState): TileColors {
+ fun getColorForState(uiState: TileUiState, iconOnly: Boolean): TileColors {
return when (uiState.state) {
STATE_ACTIVE -> {
- if (uiState.handlesSecondaryClick) {
+ if (uiState.handlesSecondaryClick && !iconOnly) {
activeDualTargetTileColors()
} else {
activeTileColors()
}
}
+
STATE_INACTIVE -> {
- if (uiState.handlesSecondaryClick) {
+ if (uiState.handlesSecondaryClick && !iconOnly) {
inactiveDualTargetTileColors()
} else {
inactiveTileColors()
}
}
+
else -> unavailableTileColors()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index 4e34e73654fc..faab6960a99c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -56,7 +56,7 @@ constructor(
private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
private val minTilesInteractor: MinimumTilesInteractor,
@ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
- @Application private val applicationContext: Context,
+ @ShadeDisplayAware private val context: Context,
@Named("Default") private val defaultGridLayout: GridLayout,
@Application private val applicationScope: CoroutineScope,
gridLayoutTypeInteractor: GridLayoutTypeInteractor,
@@ -140,7 +140,7 @@ constructor(
.combine(configurationInteractor.onAnyConfigurationChange.emitOnStart()) {
tiles,
_ ->
- tiles.fastMap { it.load(applicationContext) }
+ tiles.fastMap { it.load(context) }
}
} else {
emptyFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
index e5607eb6e620..bff330b98fda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.qs.panels.ui.viewmodel
import androidx.compose.runtime.getValue
+import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
@@ -34,6 +35,7 @@ constructor(
columnsWithMediaViewModelFactory: QSColumnsViewModel.Factory,
paginatedGridInteractor: PaginatedGridInteractor,
inFirstPageViewModel: InFirstPageViewModel,
+ val buildNumberViewModelFactory: BuildNumberViewModel.Factory,
) : IconTilesViewModel by iconTilesViewModel, ExclusiveActivatable() {
private val hydrator = Hydrator("PaginatedGridViewModel")
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt
index c5b27376a82a..41cdefdb2396 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepository.kt
@@ -30,8 +30,8 @@ import androidx.annotation.GuardedBy
import com.android.systemui.common.data.repository.PackageChangeRepository
import com.android.systemui.common.shared.model.PackageChangeModel
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.kotlin.isComponentActuallyEnabled
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -54,7 +54,7 @@ interface InstalledTilesComponentRepository {
class InstalledTilesComponentRepositoryImpl
@Inject
constructor(
- @Application private val applicationContext: Context,
+ @ShadeDisplayAware private val context: Context,
@Background private val backgroundScope: CoroutineScope,
private val packageChangeRepository: PackageChangeRepository
) : InstalledTilesComponentRepository {
@@ -77,10 +77,10 @@ constructor(
* context.
*/
val packageManager =
- if (applicationContext.userId == userId) {
- applicationContext.packageManager
+ if (context.userId == userId) {
+ context.packageManager
} else {
- applicationContext
+ context
.createContextAsUser(
UserHandle.of(userId),
/* flags */ 0,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddable.kt
index 31ea734fb842..e9c91ca0db12 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddable.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddable.kt
@@ -27,6 +27,7 @@ import com.android.systemui.qs.pipeline.domain.model.AutoAddTracking
import com.android.systemui.qs.pipeline.domain.model.AutoAddable
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tiles.NightDisplayTile
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
@@ -42,7 +43,7 @@ class NightDisplayAutoAddable
@Inject
constructor(
private val nightDisplayListenerBuilder: NightDisplayListenerModule.Builder,
- context: Context,
+ @ShadeDisplayAware context: Context,
) : AutoAddable {
private val enabled = ColorDisplayManager.isNightDisplayAvailable(context)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 18b1f071f44e..1fb76f1eaa7f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -415,7 +415,10 @@ constructor(
initLongPressEffectCallback()
init(
{ _: View -> longPressEffect.onTileClick() },
- { _: View -> true }, // Haptics and long-clicks are handled by [QSLongPressEffect]
+ { _: View ->
+ longPressEffect.onTileLongClick()
+ true
+ }, // Haptics and long-clicks are handled by [QSLongPressEffect]
)
} else {
val expandable = Expandable.fromView(this)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 6b654beea149..fed8b60a653f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -39,6 +39,7 @@ import com.android.systemui.qs.PseudoGridView;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.qs.user.UserSwitchDialogController;
import com.android.systemui.res.R;
+import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.BaseUserSwitcherAdapter;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -95,7 +96,7 @@ public class UserDetailView extends PseudoGridView {
}
@Inject
- public Adapter(Context context, UserSwitcherController controller,
+ public Adapter(@ShadeDisplayAware Context context, UserSwitcherController controller,
UiEventLogger uiEventLogger, FalsingManager falsingManager) {
super(controller);
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt
index 87b89ea6810a..45775272e01f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt
@@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor.PolicyResult
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
@@ -70,7 +71,7 @@ interface DisabledByPolicyInteractor {
class DisabledByPolicyInteractorImpl
@Inject
constructor(
- private val context: Context,
+ @ShadeDisplayAware private val context: Context,
private val activityStarter: ActivityStarter,
private val restrictedLockProxy: RestrictedLockProxy,
@Background private val backgroundDispatcher: CoroutineDispatcher,
@@ -105,7 +106,7 @@ constructor(
/** Mockable proxy for [RestrictedLockUtilsInternal] static methods. */
@VisibleForTesting
-class RestrictedLockProxy @Inject constructor(private val context: Context) {
+class RestrictedLockProxy @Inject constructor(@ShadeDisplayAware private val context: Context) {
@WorkerThread
fun hasBaseUserRestriction(userId: Int, userRestriction: String?): Boolean =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
index b766ee0d4333..222fa3efbe94 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
@@ -28,6 +28,7 @@ import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProviderImpl
import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.shade.ShadeDisplayAware
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -66,6 +67,6 @@ interface QSTilesModule {
companion object {
- @Provides fun provideTilesTheme(context: Context): Theme = context.theme
+ @Provides fun provideTilesTheme(@ShadeDisplayAware context: Context): Theme = context.theme
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index 8f6c4e743269..244f024625db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -87,6 +87,7 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.res.R;
+import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.statusbar.connectivity.AccessPointController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.LocationController;
@@ -240,7 +241,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
}
@Inject
- public InternetDialogController(@NonNull Context context, UiEventLogger uiEventLogger,
+ public InternetDialogController(@ShadeDisplayAware Context context, UiEventLogger uiEventLogger,
ActivityStarter starter, AccessPointController accessPointController,
SubscriptionManager subscriptionManager, TelephonyManager telephonyManager,
@Nullable WifiManager wifiManager, ConnectivityManager connectivityManager,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
index 89b9eee52f2a..0ab533bb9838 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
@@ -71,6 +71,7 @@ import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.res.R;
+import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.wifitrackerlib.WifiEntry;
@@ -190,7 +191,7 @@ public class InternetDialogDelegate implements
@AssistedInject
public InternetDialogDelegate(
- Context context,
+ @ShadeDisplayAware Context context,
InternetDialogManager internetDialogManager,
InternetDialogController internetDialogController,
@Assisted(CAN_CONFIG_MOBILE_DATA) boolean canConfigMobileData,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt
index 1546ec2c54bd..32fb1d18724d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt
@@ -26,6 +26,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -68,7 +69,7 @@ interface CustomTileDefaultsRepository {
class CustomTileDefaultsRepositoryImpl
@Inject
constructor(
- private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@Application applicationScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
) : CustomTileDefaultsRepository {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt
index 0ebd6f2b4ac3..cd4938f01b63 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt
@@ -28,6 +28,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
@@ -51,7 +52,7 @@ class CustomTilePackageUpdatesRepositoryImpl
@Inject
constructor(
private val tileSpec: TileSpec.CustomTileSpec,
- @Application private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@QSTileScope private val tileScope: CoroutineScope,
@Background private val backgroundCoroutineContext: CoroutineContext,
) : CustomTilePackageUpdatesRepository {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt
index 60aa4ea4759f..c446865f31af 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt
@@ -30,12 +30,16 @@ import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.shade.ShadeDisplayAware
import javax.inject.Inject
@SysUISingleton
class CustomTileMapper
@Inject
-constructor(private val context: Context, private val uriGrantsManager: IUriGrantsManager) :
+constructor(
+ @ShadeDisplayAware private val context: Context,
+ private val uriGrantsManager: IUriGrantsManager
+) :
QSTileDataToStateMapper<CustomTileDataModel> {
override fun map(config: QSTileConfig, data: CustomTileDataModel): QSTileState {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
index af2bb9d0d2f7..1153b5c67261 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
@@ -42,6 +42,7 @@ import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataMod
import com.android.systemui.qs.tiles.impl.di.QSTileScope
import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
import com.android.systemui.settings.DisplayTracker
+import com.android.systemui.shade.ShadeDisplayAware
import java.util.concurrent.atomic.AtomicReference
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
@@ -51,7 +52,7 @@ import kotlinx.coroutines.withContext
class CustomTileUserActionInteractor
@Inject
constructor(
- private val context: Context,
+ @ShadeDisplayAware private val context: Context,
private val tileSpec: TileSpec,
private val qsTileLogger: QSTileLogger,
private val windowManager: IWindowManager,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
index fc945851cdad..1a6876d0b765 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
@@ -30,6 +30,7 @@ import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileMode
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileIconModel
import javax.inject.Inject
@@ -37,9 +38,9 @@ import javax.inject.Inject
class InternetTileMapper
@Inject
constructor(
- @Main private val resources: Resources,
+ @ShadeDisplayAware private val resources: Resources,
private val theme: Resources.Theme,
- private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@Main private val handler: Handler,
) : QSTileDataToStateMapper<InternetTileModel> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt
index 6fe3979fa446..6d10843decc0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt
@@ -28,6 +28,7 @@ import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
import com.android.systemui.statusbar.pipeline.ethernet.domain.EthernetInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
@@ -54,7 +55,7 @@ import kotlinx.coroutines.flow.stateIn
class InternetTileDataInteractor
@Inject
constructor(
- private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@Application private val scope: CoroutineScope,
airplaneModeRepository: AirplaneModeRepository,
private val connectivityRepository: ConnectivityRepository,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
index 3e44258229f9..9b2880b6d47f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
@@ -28,6 +28,7 @@ import com.android.systemui.qs.tiles.ModesTile
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
import com.android.systemui.statusbar.policy.domain.model.ActiveZenModes
import com.android.systemui.statusbar.policy.domain.model.ZenModeInfo
@@ -42,7 +43,7 @@ import kotlinx.coroutines.flow.map
class ModesTileDataInteractor
@Inject
constructor(
- val context: Context,
+ @ShadeDisplayAware val context: Context,
val zenModeInteractor: ZenModeInteractor,
@Background val bgDispatcher: CoroutineDispatcher,
) : QSTileDataInteractor<ModesTileModel> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
index 252e3f84df6c..05bdf0a92679 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
@@ -32,6 +32,7 @@ import com.android.systemui.qs.tiles.impl.saver.domain.DataSaverDialogDelegate
import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
import com.android.systemui.settings.UserFileManager
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.DataSaverController
import javax.inject.Inject
@@ -42,7 +43,7 @@ import kotlinx.coroutines.withContext
class DataSaverTileUserActionInteractor
@Inject
constructor(
- @Application private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@Main private val coroutineContext: CoroutineContext,
@Background private val backgroundContext: CoroutineContext,
private val dataSaverController: DataSaverController,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt
index c928e8af17fc..7af3576d8cd9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt
@@ -25,6 +25,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
+import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.LocationController
@@ -38,7 +39,7 @@ import kotlinx.coroutines.flow.flowOf
class UiModeNightTileDataInteractor
@Inject
constructor(
- @Application private val context: Context,
+ @ShadeDisplayAware private val context: Context,
private val configurationController: ConfigurationController,
private val uiModeManager: UiModeManager,
private val batteryController: BatteryController,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index 35b1b9636263..ab3862b75ee8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -81,7 +81,7 @@ constructor(
// additional
// guidance on how to auto add your tile
throw UnsupportedOperationException(
- "Turning on tile is not supported now"
+ "Turning on tile is not supported now. Tile spec: $tileSpec"
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index 02b2bb1585bd..d94f00fff400 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -171,9 +171,16 @@ constructor(
}
ALL_ISSUE_TYPES.keys.forEach {
popupMenu.menu.add(it).apply {
+ // Set this for every item in the list to ensure equal spacing. Set it to
+ // transparent for non-selected items so icon is only visible for selected element.
setIcon(R.drawable.arrow_pointing_down)
if (it != state.issueTypeRes) {
iconTintList = ColorStateList.valueOf(Color.TRANSPARENT)
+ } else {
+ contentDescription =
+ context.getString(com.android.internal.R.string.selected) +
+ " " +
+ context.getString(it)
}
intent = Intent().putExtra(EXTRA_ISSUE_TYPE_RES, it)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 9125d7e8bb0e..aece5c65ce12 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -46,6 +46,7 @@ import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
import com.android.systemui.keyguard.DismissCallbackRegistry
import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.keyguardScenes
import com.android.systemui.model.SceneContainerPlugin
import com.android.systemui.model.SysUiState
import com.android.systemui.model.updateFlags
@@ -352,14 +353,13 @@ constructor(
val isAlternateBouncerVisible = alternateBouncerInteractor.isVisibleState()
val isOnPrimaryBouncer = renderedScenes.contains(Scenes.Bouncer)
if (!deviceUnlockStatus.isUnlocked) {
- return@mapNotNull if (isOnLockscreen || isOnPrimaryBouncer) {
- // Already on lockscreen or bouncer, no need to change scenes.
+ return@mapNotNull if (renderedScenes.any { it in keyguardScenes }) {
+ // Already on a keyguard scene, no need to change scenes.
null
} else {
- // The device locked while on a scene that's not Lockscreen or Bouncer,
- // go to Lockscreen.
- Scenes.Lockscreen to
- "device locked in non-Lockscreen and non-Bouncer scene"
+ // The device locked while on a scene that's not a keyguard scene, go
+ // to Lockscreen.
+ Scenes.Lockscreen to "device locked in a non-keyguard scene"
}
}
@@ -430,8 +430,13 @@ constructor(
"mechanism: ${deviceUnlockStatus.deviceUnlockSource}"
else -> null
}
- // Not on lockscreen or bouncer, so remain in the current scene.
- else -> null
+ // Not on lockscreen or bouncer, so remain in the current scene but since
+ // unlocked, replace the Lockscreen scene from the bottom of the navigation
+ // back stack with the Gone scene.
+ else -> {
+ replaceLockscreenSceneOnBackStack()
+ null
+ }
}
}
.collect { (targetSceneKey, loggingReason) ->
@@ -440,17 +445,19 @@ constructor(
}
}
- /** If the [Scenes.Lockscreen] is on the backstack, replaces it with [Scenes.Gone]. */
+ /**
+ * If the [Scenes.Lockscreen] is on the bottom of the navigation backstack, replaces it with
+ * [Scenes.Gone].
+ */
private fun replaceLockscreenSceneOnBackStack() {
sceneBackInteractor.updateBackStack { stack ->
val list = stack.asIterable().toMutableList()
- check(list.last() == Scenes.Lockscreen) {
- "The bottommost/last SceneKey of the back stack isn't" +
- " the Lockscreen scene like expected. The back" +
- " stack is $stack."
+ if (list.lastOrNull() == Scenes.Lockscreen) {
+ list[list.size - 1] = Scenes.Gone
+ sceneStackOf(*list.toTypedArray())
+ } else {
+ stack
}
- list[list.size - 1] = Scenes.Gone
- sceneStackOf(*list.toTypedArray())
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 4ccd2b93911e..42a756c27de7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -3109,17 +3109,20 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
if (isTracking()) {
onTrackingStopped(true);
}
- if (isExpanded() && mBarState != KEYGUARD && !mQsController.getExpanded()) {
- mShadeLog.d("Status Bar was long pressed. Expanding to QS.");
- expandToQs();
- } else {
- if (mBarState == KEYGUARD) {
- mShadeLog.d("Lockscreen Status Bar was long pressed. Expanding to Notifications.");
- mLockscreenShadeTransitionController.goToLockedShade(
- /* expandedView= */null, /* needsQSAnimation= */false);
+ if (!mQsController.getExpanded()) {
+ performHapticFeedback(HapticFeedbackConstants.GESTURE_START);
+ if (isExpanded() && mBarState != KEYGUARD) {
+ mShadeLog.d("Status Bar was long pressed. Expanding to QS.");
+ mQsController.flingQs(0, FLING_EXPAND);
} else {
- mShadeLog.d("Status Bar was long pressed. Expanding to Notifications.");
- expandToNotifications();
+ if (mBarState == KEYGUARD) {
+ mShadeLog.d("Lockscreen Status Bar was long pressed. Expanding to Notifications.");
+ mLockscreenShadeTransitionController.goToLockedShade(
+ /* expandedView= */null, /* needsQSAnimation= */true);
+ } else {
+ mShadeLog.d("Status Bar was long pressed. Expanding to Notifications.");
+ expandToNotifications();
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 830649be2a98..04f89be97e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
@@ -114,6 +114,7 @@ import kotlin.Unit;
import java.io.PrintWriter;
import javax.inject.Inject;
+import javax.inject.Provider;
/** Handles QuickSettings touch handling, expansion and animation state
* TODO (b/264460656) make this dumpable
@@ -141,6 +142,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
private final NotificationShadeDepthController mDepthController;
private final ShadeHeaderController mShadeHeaderController;
private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+ private final Provider<StatusBarLongPressGestureDetector> mStatusBarLongPressGestureDetector;
private final KeyguardStateController mKeyguardStateController;
private final KeyguardBypassController mKeyguardBypassController;
private final NotificationRemoteInputManager mRemoteInputManager;
@@ -316,6 +318,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
NotificationShadeDepthController notificationShadeDepthController,
ShadeHeaderController shadeHeaderController,
StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+ Provider<StatusBarLongPressGestureDetector> statusBarLongPressGestureDetector,
KeyguardStateController keyguardStateController,
KeyguardBypassController keyguardBypassController,
ScrimController scrimController,
@@ -364,6 +367,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
mDepthController = notificationShadeDepthController;
mShadeHeaderController = shadeHeaderController;
mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
+ mStatusBarLongPressGestureDetector = statusBarLongPressGestureDetector;
mKeyguardStateController = keyguardStateController;
mKeyguardBypassController = keyguardBypassController;
mScrimController = scrimController;
@@ -1648,6 +1652,10 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
if (isSplitShadeAndTouchXOutsideQs(event.getX())) {
return false;
}
+ boolean isInStatusBar = event.getY(event.getActionIndex()) < mStatusBarMinHeight;
+ if (ShadeExpandsOnStatusBarLongPress.isEnabled() && isInStatusBar) {
+ mStatusBarLongPressGestureDetector.get().handleTouch(event);
+ }
final int action = event.getActionMasked();
boolean collapsedQs = !getExpanded() && !mSplitShadeEnabled;
boolean expandedShadeCollapsedQs = mShadeExpandedFraction == 1f
@@ -1684,9 +1692,7 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum
if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed && isExpansionEnabled()) {
mTwoFingerExpandPossible = true;
}
- if (mTwoFingerExpandPossible && isOpenQsEvent(event)
- && event.getY(event.getActionIndex())
- < mStatusBarMinHeight) {
+ if (mTwoFingerExpandPossible && isOpenQsEvent(event) && isInStatusBar) {
mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
setExpandImmediate(true);
mNotificationStackScrollLayoutController.setShouldShowShelfOnly(!mSplitShadeEnabled);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index fed4a26ab1ab..4f73a3456cad 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -164,10 +164,8 @@ object ShadeDisplayAwareModule {
@Provides
@IntoMap
- @ClassKey(ShadeDisplaysRepositoryImpl::class)
- fun provideShadePositionRepositoryAsCoreStartable(
- impl: ShadeDisplaysRepositoryImpl
- ): CoreStartable {
+ @ClassKey(ShadePrimaryDisplayCommand::class)
+ fun provideShadePrimaryDisplayCommand(impl: ShadePrimaryDisplayCommand): CoreStartable {
return if (ShadeWindowGoesAround.isEnabled) {
impl
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt
index 506b4e9ab565..a5d9e9660ca5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadePrimaryDisplayCommand.kt
@@ -17,40 +17,107 @@
package com.android.systemui.shade
import android.view.Display
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.display.data.repository.DisplayRepository
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.statusbar.commandline.Command
+import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
+import javax.inject.Inject
-class ShadePrimaryDisplayCommand(private val positionRepository: ShadeDisplaysRepository) :
- Command {
+@SysUISingleton
+class ShadePrimaryDisplayCommand
+@Inject
+constructor(
+ private val commandRegistry: CommandRegistry,
+ private val displaysRepository: DisplayRepository,
+ private val positionRepository: ShadeDisplaysRepository,
+) : Command, CoreStartable {
+
+ override fun start() {
+ commandRegistry.registerCommand("shade_display_override") { this }
+ }
+
+ override fun help(pw: PrintWriter) {
+ pw.println("shade_display_override <displayId> ")
+ pw.println("Set the display which is holding the shade.")
+ pw.println()
+ pw.println("shade_display_override reset ")
+ pw.println("Reset the display which is holding the shade.")
+ pw.println()
+ pw.println("shade_display_override (list|status) ")
+ pw.println("Lists available displays and which has the shade")
+ pw.println()
+ pw.println("shade_display_override any_external")
+ pw.println("Moves the shade to the first not-default display available")
+ }
override fun execute(pw: PrintWriter, args: List<String>) {
- if (args[0].lowercase() == "reset") {
+ CommandHandler(pw, args).execute()
+ }
+
+ /** Wrapper class to avoid propagating [PrintWriter] to all methods. */
+ private inner class CommandHandler(
+ private val pw: PrintWriter,
+ private val args: List<String>,
+ ) {
+
+ fun execute() {
+ when (val command = args.getOrNull(0)?.lowercase()) {
+ "reset" -> reset()
+ "list",
+ "status" -> printStatus()
+ "any_external" -> anyExternal()
+ else -> {
+ val cmdAsInteger = command?.toIntOrNull()
+ if (cmdAsInteger != null) {
+ changeDisplay(displayId = cmdAsInteger)
+ } else {
+ help(pw)
+ }
+ }
+ }
+ }
+
+ private fun reset() {
positionRepository.resetDisplayId()
pw.println("Reset shade primary display id to ${Display.DEFAULT_DISPLAY}")
- return
}
- val displayId: Int =
- try {
- args[0].toInt()
- } catch (e: NumberFormatException) {
- pw.println("Error: task id should be an integer")
- return
+ private fun printStatus() {
+ val displays = displaysRepository.displays.value
+ val shadeDisplay = positionRepository.displayId.value
+ pw.println("Available displays: ")
+ displays.forEach {
+ pw.print(" - ${it.displayId}")
+ pw.println(if (it.displayId == shadeDisplay) " (Shade window is here)" else "")
}
+ }
- if (displayId < 0) {
- pw.println("Error: display id should be positive integer")
+ private fun anyExternal() {
+ val anyExternalDisplay =
+ displaysRepository.displays.value.firstOrNull {
+ it.displayId != Display.DEFAULT_DISPLAY
+ }
+ if (anyExternalDisplay == null) {
+ pw.println("No external displays available.")
+ return
+ }
+ setDisplay(anyExternalDisplay.displayId)
}
- positionRepository.setDisplayId(displayId)
- pw.println("New shade primary display id is $displayId")
- }
+ private fun changeDisplay(displayId: Int) {
+ if (displayId < 0) {
+ pw.println("Error: display id should be positive integer")
+ }
- override fun help(pw: PrintWriter) {
- pw.println("shade_display_override <displayId> ")
- pw.println("Set the display which is holding the shade.")
- pw.println("shade_display_override reset ")
- pw.println("Reset the display which is holding the shade.")
+ setDisplay(displayId)
+ }
+
+ private fun setDisplay(id: Int) {
+ positionRepository.setDisplayId(id)
+ pw.println("New shade primary display id is $id")
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
index e920abac8ccc..4a95e339cade 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeDisplaysRepository.kt
@@ -17,10 +17,7 @@
package com.android.systemui.shade.data.repository
import android.view.Display
-import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.shade.ShadePrimaryDisplayCommand
-import com.android.systemui.statusbar.commandline.CommandRegistry
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -41,9 +38,7 @@ interface ShadeDisplaysRepository {
/** Source of truth for the display currently holding the shade. */
@SysUISingleton
-class ShadeDisplaysRepositoryImpl
-@Inject
-constructor(private val commandRegistry: CommandRegistry) : ShadeDisplaysRepository, CoreStartable {
+class ShadeDisplaysRepositoryImpl @Inject constructor() : ShadeDisplaysRepository {
private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY)
override val displayId: StateFlow<Int>
@@ -56,10 +51,4 @@ constructor(private val commandRegistry: CommandRegistry) : ShadeDisplaysReposit
override fun resetDisplayId() {
_displayId.value = Display.DEFAULT_DISPLAY
}
-
- override fun start() {
- commandRegistry.registerCommand("shade_display_override") {
- ShadePrimaryDisplayCommand(this)
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
index c019f308d3e5..72b03bfa20c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -14,7 +14,7 @@ per-file *Keyboard* = set noparent
per-file *Keyboard* = file:../keyguard/OWNERS
per-file *Keyguard* = set noparent
per-file *Keyguard* = file:../keyguard/OWNERS
-per-file *Notification* = set noparent
+# Not setting noparent here, since *Notification* also matches some status bar notification chips files (statusbar/chips/notification) which should be owned by the status bar team.
per-file *Notification* = file:notification/OWNERS
# Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*)
per-file *Mode* = file:notification/OWNERS
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index a24f2672f251..85cd50565f88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -83,39 +83,36 @@ import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Named
-
/** Controller for managing the smartspace view on the lockscreen */
@SysUISingleton
class LockscreenSmartspaceController
@Inject
constructor(
- private val context: Context,
- private val featureFlags: FeatureFlags,
- private val activityStarter: ActivityStarter,
- private val falsingManager: FalsingManager,
- private val systemClock: SystemClock,
- private val secureSettings: SecureSettings,
- private val userTracker: UserTracker,
- private val contentResolver: ContentResolver,
- private val configurationController: ConfigurationController,
- private val statusBarStateController: StatusBarStateController,
- private val deviceProvisionedController: DeviceProvisionedController,
- private val bypassController: KeyguardBypassController,
- private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
- private val wakefulnessLifecycle: WakefulnessLifecycle,
- private val smartspaceViewModelFactory: SmartspaceViewModel.Factory,
- private val dumpManager: DumpManager,
- private val execution: Execution,
- @Main private val uiExecutor: Executor,
- @Background private val bgExecutor: Executor,
- @Main private val handler: Handler,
- @Background private val bgHandler: Handler,
- @Named(DATE_SMARTSPACE_DATA_PLUGIN)
- optionalDatePlugin: Optional<BcSmartspaceDataPlugin>,
- @Named(WEATHER_SMARTSPACE_DATA_PLUGIN)
- optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>,
- optionalPlugin: Optional<BcSmartspaceDataPlugin>,
- optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>,
+ private val context: Context,
+ private val featureFlags: FeatureFlags,
+ private val activityStarter: ActivityStarter,
+ private val falsingManager: FalsingManager,
+ private val systemClock: SystemClock,
+ private val secureSettings: SecureSettings,
+ private val userTracker: UserTracker,
+ private val contentResolver: ContentResolver,
+ private val configurationController: ConfigurationController,
+ private val statusBarStateController: StatusBarStateController,
+ private val deviceProvisionedController: DeviceProvisionedController,
+ private val bypassController: KeyguardBypassController,
+ private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+ private val wakefulnessLifecycle: WakefulnessLifecycle,
+ private val smartspaceViewModelFactory: SmartspaceViewModel.Factory,
+ private val dumpManager: DumpManager,
+ private val execution: Execution,
+ @Main private val uiExecutor: Executor,
+ @Background private val bgExecutor: Executor,
+ @Main private val handler: Handler,
+ @Background private val bgHandler: Handler,
+ @Named(DATE_SMARTSPACE_DATA_PLUGIN) optionalDatePlugin: Optional<BcSmartspaceDataPlugin>,
+ @Named(WEATHER_SMARTSPACE_DATA_PLUGIN) optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>,
+ optionalPlugin: Optional<BcSmartspaceDataPlugin>,
+ optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>,
) : Dumpable {
companion object {
private const val TAG = "LockscreenSmartspaceController"
@@ -135,11 +132,9 @@ constructor(
// Smartspace can be used on multiple displays, such as when the user casts their screen
@VisibleForTesting var smartspaceViews = mutableSetOf<SmartspaceView>()
- private var regionSamplers =
- mutableMapOf<SmartspaceView, RegionSampler>()
+ private var regionSamplers = mutableMapOf<SmartspaceView, RegionSampler>()
- private val regionSamplingEnabled =
- featureFlags.isEnabled(Flags.REGION_SAMPLING)
+ private val regionSamplingEnabled = featureFlags.isEnabled(Flags.REGION_SAMPLING)
private var isRegionSamplersCreated = false
private var showNotifications = false
private var showSensitiveContentForCurrentUser = false
@@ -157,119 +152,130 @@ constructor(
// how we test color updates when theme changes (See testThemeChangeUpdatesTextColor).
// TODO: Move logic into SmartspaceView
- var stateChangeListener = object : View.OnAttachStateChangeListener {
- override fun onViewAttachedToWindow(v: View) {
- (v as SmartspaceView).setSplitShadeEnabled(mSplitShadeEnabled)
- smartspaceViews.add(v as SmartspaceView)
-
- connectSession()
-
- updateTextColorFromWallpaper()
- statusBarStateListener.onDozeAmountChanged(0f, statusBarStateController.dozeAmount)
-
- if (regionSamplingEnabled && (!regionSamplers.containsKey(v))) {
- var regionSampler = RegionSampler(
- v as View,
- uiExecutor,
- bgExecutor,
- regionSamplingEnabled,
- isLockscreen = true,
- ) { updateTextColorFromRegionSampler() }
- initializeTextColors(regionSampler)
- regionSamplers[v] = regionSampler
- regionSampler.startRegionSampler()
+ var stateChangeListener =
+ object : View.OnAttachStateChangeListener {
+ override fun onViewAttachedToWindow(v: View) {
+ (v as SmartspaceView).setSplitShadeEnabled(mSplitShadeEnabled)
+ smartspaceViews.add(v as SmartspaceView)
+
+ connectSession()
+
+ updateTextColorFromWallpaper()
+ statusBarStateListener.onDozeAmountChanged(0f, statusBarStateController.dozeAmount)
+
+ if (regionSamplingEnabled && (!regionSamplers.containsKey(v))) {
+ var regionSampler =
+ RegionSampler(
+ v as View,
+ uiExecutor,
+ bgExecutor,
+ regionSamplingEnabled,
+ isLockscreen = true,
+ ) {
+ updateTextColorFromRegionSampler()
+ }
+ initializeTextColors(regionSampler)
+ regionSamplers[v] = regionSampler
+ regionSampler.startRegionSampler()
+ }
}
- }
- override fun onViewDetachedFromWindow(v: View) {
- smartspaceViews.remove(v as SmartspaceView)
+ override fun onViewDetachedFromWindow(v: View) {
+ smartspaceViews.remove(v as SmartspaceView)
- regionSamplers[v]?.stopRegionSampler()
- regionSamplers.remove(v as SmartspaceView)
+ regionSamplers[v]?.stopRegionSampler()
+ regionSamplers.remove(v as SmartspaceView)
- if (smartspaceViews.isEmpty()) {
- disconnect()
+ if (smartspaceViews.isEmpty()) {
+ disconnect()
+ }
}
}
- }
- private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
- execution.assertIsMainThread()
+ private val sessionListener =
+ SmartspaceSession.OnTargetsAvailableListener { targets ->
+ execution.assertIsMainThread()
- // The weather data plugin takes unfiltered targets and performs the filtering internally.
- weatherPlugin?.onTargetsAvailable(targets)
-
- val now = Instant.ofEpochMilli(systemClock.currentTimeMillis())
- val weatherTarget = targets.find { t ->
- t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
- now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
- now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
- }
- if (weatherTarget != null) {
- val clickIntent = weatherTarget.headerAction?.intent
- val weatherData = weatherTarget.baseAction?.extras?.let { extras ->
- WeatherData.fromBundle(
- extras,
- ) { _ ->
- if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
- activityStarter.startActivity(
- clickIntent,
- true, /* dismissShade */
- null,
- false)
- }
+ // The weather data plugin takes unfiltered targets and performs the filtering
+ // internally.
+ weatherPlugin?.onTargetsAvailable(targets)
+
+ val now = Instant.ofEpochMilli(systemClock.currentTimeMillis())
+ val weatherTarget =
+ targets.find { t ->
+ t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
+ now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
+ now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
}
- }
+ if (weatherTarget != null) {
+ val clickIntent = weatherTarget.headerAction?.intent
+ val weatherData =
+ weatherTarget.baseAction?.extras?.let { extras ->
+ WeatherData.fromBundle(extras) { _ ->
+ if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ activityStarter.startActivity(
+ clickIntent,
+ true, /* dismissShade */
+ null,
+ false,
+ )
+ }
+ }
+ }
- if (weatherData != null) {
- keyguardUpdateMonitor.sendWeatherData(weatherData)
+ if (weatherData != null) {
+ keyguardUpdateMonitor.sendWeatherData(weatherData)
+ }
}
- }
- val filteredTargets = targets.filter(::filterSmartspaceTarget)
+ val filteredTargets = targets.filter(::filterSmartspaceTarget)
- synchronized(recentSmartspaceData) {
- recentSmartspaceData.offerLast(filteredTargets)
- if (recentSmartspaceData.size > MAX_RECENT_SMARTSPACE_DATA_FOR_DUMP) {
- recentSmartspaceData.pollFirst()
+ synchronized(recentSmartspaceData) {
+ recentSmartspaceData.offerLast(filteredTargets)
+ if (recentSmartspaceData.size > MAX_RECENT_SMARTSPACE_DATA_FOR_DUMP) {
+ recentSmartspaceData.pollFirst()
+ }
}
- }
-
- plugin?.onTargetsAvailable(filteredTargets)
- }
- private val userTrackerCallback = object : UserTracker.Callback {
- override fun onUserChanged(newUser: Int, userContext: Context) {
- execution.assertIsMainThread()
- reloadSmartspace()
+ plugin?.onTargetsAvailable(filteredTargets)
}
- }
- private val settingsObserver = object : ContentObserver(handler) {
- override fun onChange(selfChange: Boolean, uri: Uri?) {
- execution.assertIsMainThread()
- reloadSmartspace()
+ private val userTrackerCallback =
+ object : UserTracker.Callback {
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ execution.assertIsMainThread()
+ reloadSmartspace()
+ }
}
- }
- private val configChangeListener = object : ConfigurationController.ConfigurationListener {
- override fun onThemeChanged() {
- execution.assertIsMainThread()
- updateTextColorFromWallpaper()
+ private val settingsObserver =
+ object : ContentObserver(handler) {
+ override fun onChange(selfChange: Boolean, uri: Uri?) {
+ execution.assertIsMainThread()
+ reloadSmartspace()
+ }
}
- }
- private val statusBarStateListener = object : StatusBarStateController.StateListener {
- override fun onDozeAmountChanged(linear: Float, eased: Float) {
- execution.assertIsMainThread()
- smartspaceViews.forEach { it.setDozeAmount(eased) }
+ private val configChangeListener =
+ object : ConfigurationController.ConfigurationListener {
+ override fun onThemeChanged() {
+ execution.assertIsMainThread()
+ updateTextColorFromWallpaper()
+ }
}
- override fun onDozingChanged(isDozing: Boolean) {
- execution.assertIsMainThread()
- smartspaceViews.forEach { it.setDozing(isDozing) }
+ private val statusBarStateListener =
+ object : StatusBarStateController.StateListener {
+ override fun onDozeAmountChanged(linear: Float, eased: Float) {
+ execution.assertIsMainThread()
+ smartspaceViews.forEach { it.setDozeAmount(eased) }
+ }
+
+ override fun onDozingChanged(isDozing: Boolean) {
+ execution.assertIsMainThread()
+ smartspaceViews.forEach { it.setDozing(isDozing) }
+ }
}
- }
private val deviceProvisionedListener =
object : DeviceProvisionedController.DeviceProvisionedListener {
@@ -313,11 +319,8 @@ constructor(
val isWeatherEnabled: Boolean
get() {
val showWeather =
- secureSettings.getIntForUser(
- LOCK_SCREEN_WEATHER_ENABLED,
- 1,
- userTracker.userId,
- ) == 1
+ secureSettings.getIntForUser(LOCK_SCREEN_WEATHER_ENABLED, 1, userTracker.userId) ==
+ 1
return showWeather
}
@@ -326,9 +329,7 @@ constructor(
smartspaceViews.forEach { it.setKeyguardBypassEnabled(bypassEnabled) }
}
- /**
- * Constructs the date view and connects it to the smartspace service.
- */
+ /** Constructs the date view and connects it to the smartspace service. */
fun buildAndConnectDateView(parent: ViewGroup): View? {
execution.assertIsMainThread()
@@ -343,16 +344,14 @@ constructor(
buildView(
surfaceName = SmartspaceViewModel.SURFACE_DATE_VIEW,
parent = parent,
- plugin = datePlugin
+ plugin = datePlugin,
)
connectSession()
return view
}
- /**
- * Constructs the weather view and connects it to the smartspace service.
- */
+ /** Constructs the weather view and connects it to the smartspace service. */
fun buildAndConnectWeatherView(parent: ViewGroup): View? {
execution.assertIsMainThread()
@@ -367,16 +366,14 @@ constructor(
buildView(
surfaceName = SmartspaceViewModel.SURFACE_WEATHER_VIEW,
parent = parent,
- plugin = weatherPlugin
+ plugin = weatherPlugin,
)
connectSession()
return view
}
- /**
- * Constructs the smartspace view and connects it to the smartspace service.
- */
+ /** Constructs the smartspace view and connects it to the smartspace service. */
fun buildAndConnectView(parent: ViewGroup): View? {
execution.assertIsMainThread()
@@ -384,12 +381,14 @@ constructor(
throw RuntimeException("Cannot build view when not enabled")
}
+ configPlugin?.let { plugin?.registerConfigProvider(it) }
+
val view =
buildView(
surfaceName = SmartspaceViewModel.SURFACE_GENERAL_VIEW,
parent = parent,
plugin = plugin,
- configPlugin = configPlugin
+ configPlugin = configPlugin,
)
connectSession()
@@ -400,7 +399,7 @@ constructor(
surfaceName: String,
parent: ViewGroup,
plugin: BcSmartspaceDataPlugin?,
- configPlugin: BcSmartspaceConfigPlugin? = null
+ configPlugin: BcSmartspaceConfigPlugin? = null,
): View? {
if (plugin == null) {
return null
@@ -413,37 +412,41 @@ constructor(
ssView.setTimeChangedDelegate(SmartspaceTimeChangedDelegate(keyguardUpdateMonitor))
ssView.registerDataProvider(plugin)
- ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
- override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
- if (showOnLockscreen) {
- activityStarter.startActivity(
+ ssView.setIntentStarter(
+ object : BcSmartspaceDataPlugin.IntentStarter {
+ override fun startIntent(view: View, intent: Intent, showOnLockscreen: Boolean) {
+ if (showOnLockscreen) {
+ activityStarter.startActivity(
intent,
true, /* dismissShade */
// launch animator - looks bad with the transparent smartspace bg
null,
- true
- )
- } else {
- activityStarter.postStartActivityDismissingKeyguard(intent, 0)
+ true,
+ )
+ } else {
+ activityStarter.postStartActivityDismissingKeyguard(intent, 0)
+ }
}
- }
- override fun startPendingIntent(
+ override fun startPendingIntent(
view: View,
pi: PendingIntent,
- showOnLockscreen: Boolean
- ) {
- if (showOnLockscreen) {
- val options = ActivityOptions.makeBasic()
- .setPendingIntentBackgroundActivityStartMode(
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
- .toBundle()
- pi.send(options)
- } else {
- activityStarter.postStartActivityDismissingKeyguard(pi)
+ showOnLockscreen: Boolean,
+ ) {
+ if (showOnLockscreen) {
+ val options =
+ ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
+ .toBundle()
+ pi.send(options)
+ } else {
+ activityStarter.postStartActivityDismissingKeyguard(pi)
+ }
}
}
- })
+ )
ssView.setFalsingManager(falsingManager)
ssView.setKeyguardBypassEnabled(bypassController.bypassEnabled)
return (ssView as View).apply {
@@ -452,10 +455,7 @@ constructor(
if (smartspaceLockscreenViewmodel()) {
val viewModel = smartspaceViewModelFactory.create(surfaceName)
- SmartspaceViewBinder.bind(
- smartspaceView = ssView,
- viewModel = viewModel,
- )
+ SmartspaceViewBinder.bind(smartspaceView = ssView, viewModel = viewModel)
}
}
}
@@ -473,34 +473,41 @@ constructor(
// Only connect after the device is fully provisioned to avoid connection caching
// issues
- if (!deviceProvisionedController.isDeviceProvisioned() ||
- !deviceProvisionedController.isCurrentUserSetup()) {
+ if (
+ !deviceProvisionedController.isDeviceProvisioned() ||
+ !deviceProvisionedController.isCurrentUserSetup()
+ ) {
return
}
- val newSession = userSmartspaceManager?.createSmartspaceSession(
- SmartspaceConfig.Builder(
- userTracker.userContext, BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD
- ).build()
+ val newSession =
+ userSmartspaceManager?.createSmartspaceSession(
+ SmartspaceConfig.Builder(
+ userTracker.userContext,
+ BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD,
+ )
+ .build()
+ )
+ Log.d(
+ TAG,
+ "Starting smartspace session for " + BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD,
)
- Log.d(TAG, "Starting smartspace session for " +
- BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
newSession?.addOnTargetsAvailableListener(uiExecutor, sessionListener)
this.session = newSession
deviceProvisionedController.removeCallback(deviceProvisionedListener)
userTracker.addCallback(userTrackerCallback, uiExecutor)
contentResolver.registerContentObserver(
- secureSettings.getUriFor(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
- true,
- settingsObserver,
- UserHandle.USER_ALL
+ secureSettings.getUriFor(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+ true,
+ settingsObserver,
+ UserHandle.USER_ALL,
)
contentResolver.registerContentObserver(
- secureSettings.getUriFor(LOCK_SCREEN_SHOW_NOTIFICATIONS),
- true,
- settingsObserver,
- UserHandle.USER_ALL
+ secureSettings.getUriFor(LOCK_SCREEN_SHOW_NOTIFICATIONS),
+ true,
+ settingsObserver,
+ UserHandle.USER_ALL,
)
configurationController.addCallback(configChangeListener)
statusBarStateController.addCallback(statusBarStateListener)
@@ -522,16 +529,12 @@ constructor(
smartspaceViews.forEach { it.setSplitShadeEnabled(enabled) }
}
- /**
- * Requests the smartspace session for an update.
- */
+ /** Requests the smartspace session for an update. */
fun requestSmartspaceUpdate() {
session?.requestSmartspaceUpdate()
}
- /**
- * Disconnects the smartspace view from the smartspace service and cleans up any resources.
- */
+ /** Disconnects the smartspace view from the smartspace service and cleans up any resources. */
fun disconnect() {
if (!smartspaceViews.isEmpty()) return
if (suppressDisconnects) return
@@ -638,7 +641,7 @@ constructor(
private fun updateTextColorFromWallpaper() {
if (!regionSamplingEnabled || regionSamplers.isEmpty()) {
val wallpaperTextColor =
- Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
+ Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) }
} else {
updateTextColorFromRegionSampler()
@@ -646,26 +649,25 @@ constructor(
}
private fun reloadSmartspace() {
- showNotifications = secureSettings.getIntForUser(
- LOCK_SCREEN_SHOW_NOTIFICATIONS,
- 0,
- userTracker.userId
- ) == 1
-
- showSensitiveContentForCurrentUser = secureSettings.getIntForUser(
- LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- 0,
- userTracker.userId
- ) == 1
+ showNotifications =
+ secureSettings.getIntForUser(LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userTracker.userId) == 1
- managedUserHandle = getWorkProfileUser()
- val managedId = managedUserHandle?.identifier
- if (managedId != null) {
- showSensitiveContentForManagedUser = secureSettings.getIntForUser(
+ showSensitiveContentForCurrentUser =
+ secureSettings.getIntForUser(
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
0,
- managedId
+ userTracker.userId,
) == 1
+
+ managedUserHandle = getWorkProfileUser()
+ val managedId = managedUserHandle?.identifier
+ if (managedId != null) {
+ showSensitiveContentForManagedUser =
+ secureSettings.getIntForUser(
+ LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+ 0,
+ managedId,
+ ) == 1
}
session?.requestSmartspaceUpdate()
@@ -682,9 +684,7 @@ constructor(
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.asIndenting().run {
- printCollection("Region Samplers", regionSamplers.values) {
- it.dump(this)
- }
+ printCollection("Region Samplers", regionSamplers.values) { it.dump(this) }
}
pw.println("Recent BC Smartspace Targets (most recent first)")
@@ -707,15 +707,17 @@ constructor(
private val keyguardUpdateMonitor: KeyguardUpdateMonitor
) : TimeChangedDelegate {
private var keyguardUpdateMonitorCallback: KeyguardUpdateMonitorCallback? = null
+
override fun register(callback: Runnable) {
if (keyguardUpdateMonitorCallback != null) {
unregister()
}
- keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
- override fun onTimeChanged() {
- callback.run()
+ keyguardUpdateMonitorCallback =
+ object : KeyguardUpdateMonitorCallback() {
+ override fun onTimeChanged() {
+ callback.run()
+ }
}
- }
keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
callback.run()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java
new file mode 100644
index 000000000000..aad618d50067
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row;
+
+import android.app.INotificationManager;
+import android.app.NotificationChannel;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.RemoteException;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.AssistantFeedbackController;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.util.List;
+
+/**
+ * The guts of a notification revealed when performing a long press.
+ */
+public class BundleNotificationInfo extends NotificationInfo {
+ private static final String TAG = "BundleNotifInfoGuts";
+
+ public BundleNotificationInfo(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void bindNotification(
+ PackageManager pm,
+ INotificationManager iNotificationManager,
+ OnUserInteractionCallback onUserInteractionCallback,
+ ChannelEditorDialogController channelEditorDialogController,
+ String pkg,
+ NotificationChannel notificationChannel,
+ NotificationEntry entry,
+ OnSettingsClickListener onSettingsClick,
+ OnAppSettingsClickListener onAppSettingsClick,
+ UiEventLogger uiEventLogger,
+ boolean isDeviceProvisioned,
+ boolean isNonblockable,
+ boolean wasShownHighPriority,
+ AssistantFeedbackController assistantFeedbackController,
+ MetricsLogger metricsLogger) throws RemoteException {
+ super.bindNotification(pm, iNotificationManager, onUserInteractionCallback,
+ channelEditorDialogController, pkg, notificationChannel, entry, onSettingsClick,
+ onAppSettingsClick, uiEventLogger, isDeviceProvisioned, isNonblockable,
+ wasShownHighPriority, assistantFeedbackController, metricsLogger);
+
+ // Additionally, bind the feedback button.
+ ComponentName assistant = iNotificationManager.getAllowedNotificationAssistant();
+ bindFeedback(entry.getSbn(), pm, assistant, onAppSettingsClick);
+ }
+
+ protected void bindFeedback(StatusBarNotification sbn, PackageManager pm,
+ ComponentName assistant,
+ NotificationInfo.OnAppSettingsClickListener appSettingsClickListener) {
+ View feedbackButton = findViewById(R.id.notification_guts_bundle_feedback);
+ // If the assistant component is null, don't show the feedback button and finish.
+ if (assistant == null) {
+ feedbackButton.setVisibility(GONE);
+ return;
+ }
+ // Otherwise we extract the assistant package name.
+ String assistantPkg = assistant.getPackageName();
+
+ feedbackButton.setOnClickListener(getBundleFeedbackClickListener(sbn, pm, assistantPkg,
+ appSettingsClickListener));
+ feedbackButton.setVisibility(feedbackButton.hasOnClickListeners() ? VISIBLE : GONE);
+ }
+
+ private OnClickListener getBundleFeedbackClickListener(StatusBarNotification sbn,
+ PackageManager pm, String assistantPkg,
+ NotificationInfo.OnAppSettingsClickListener appSettingsClickListener) {
+ Intent feedbackIntent = getBundleFeedbackIntent(pm, assistantPkg, sbn.getKey());
+ if (feedbackIntent != null) {
+ return ((View view) -> {
+ appSettingsClickListener.onClick(view, feedbackIntent);
+ });
+ }
+ return null;
+ }
+
+ private Intent getBundleFeedbackIntent(PackageManager pm, String packageName, String key) {
+ Intent intent = new Intent(
+ NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS)
+ .setPackage(packageName);
+ final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
+ intent,
+ PackageManager.MATCH_DEFAULT_ONLY
+ );
+ if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
+ return null;
+ }
+ final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
+ intent.setClassName(activityInfo.packageName, activityInfo.name);
+ intent.putExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY, key);
+ return intent;
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d1de6be27296..a90a1053e01c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.row;
import static android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
+import static com.android.systemui.flags.Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.policy.RemoteInputView.FOCUS_ANIMATION_MIN_SCALE;
@@ -75,8 +76,8 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.CallLayout;
+import com.android.systemui.Flags;
import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.flags.RefactorFlag;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginListener;
@@ -293,7 +294,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private static boolean shouldSimulateSlowMeasure() {
return Compile.IS_DEBUG && RefactorFlag.forView(
- Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE).isEnabled();
+ ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE).isEnabled();
}
private static final String SLOW_MEASURE_SIMULATE_DELAY_PROPERTY =
@@ -1370,6 +1371,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
items.add(NotificationMenuRow.createPartialConversationItem(mContext));
items.add(NotificationMenuRow.createInfoItem(mContext));
items.add(NotificationMenuRow.createSnoozeItem(mContext));
+ if (android.app.Flags.notificationClassificationUi()) {
+ items.add(NotificationMenuRow.createBundleItem(mContext));
+ }
mMenuRow.setMenuItems(items);
}
if (existed) {
@@ -1679,7 +1683,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
dismiss(fromAccessibility);
if (canEntryBeDismissed()) {
if (mOnUserInteractionCallback != null) {
- mOnUserInteractionCallback.registerFutureDismissal(mEntry, REASON_CANCEL).run();
+ if (Flags.notificationReentrantDismiss()) {
+ Runnable futureDismissal = mOnUserInteractionCallback.registerFutureDismissal(
+ mEntry, REASON_CANCEL);
+ post(futureDismissal);
+ } else {
+ mOnUserInteractionCallback.registerFutureDismissal(mEntry, REASON_CANCEL).run();
+ }
}
}
}
@@ -1986,7 +1996,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mColorUpdateLogger = colorUpdateLogger;
mDismissibilityProvider = dismissibilityProvider;
mFeatureFlags = featureFlags;
- setHapticFeedbackEnabled(!com.android.systemui.Flags.msdlFeedback());
+ setHapticFeedbackEnabled(!Flags.msdlFeedback());
}
private void initDimens() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 9e9116bd70e7..5ff9bc61f3ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -19,6 +19,7 @@ import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import android.annotation.FlaggedApi;
import android.app.INotificationManager;
import android.app.NotificationChannel;
import android.content.Context;
@@ -317,6 +318,9 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta
(PartialConversationInfo) gutsView);
} else if (gutsView instanceof FeedbackInfo) {
initializeFeedbackInfo(row, (FeedbackInfo) gutsView);
+ } else if (android.app.Flags.notificationClassificationUi()
+ && gutsView instanceof BundleNotificationInfo) {
+ initializeBundleNotificationInfo(row, (BundleNotificationInfo) gutsView);
}
return true;
} catch (Exception e) {
@@ -420,6 +424,60 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta
}
/**
+ * Sets up the {@link BundleNotificationInfo} inside the notification row's guts.
+ * @param row view to set up the guts for
+ * @param notificationInfoView view to set up/bind within {@code row}
+ */
+ @VisibleForTesting
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ void initializeBundleNotificationInfo(
+ final ExpandableNotificationRow row,
+ BundleNotificationInfo notificationInfoView) throws Exception {
+ NotificationGuts guts = row.getGuts();
+ StatusBarNotification sbn = row.getEntry().getSbn();
+ String packageName = sbn.getPackageName();
+ // Settings link is only valid for notifications that specify a non-system user
+ NotificationInfo.OnSettingsClickListener onSettingsClick = null;
+ UserHandle userHandle = sbn.getUser();
+ PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
+ mContext, userHandle.getIdentifier());
+ final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick =
+ (View v, Intent intent) -> {
+ mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
+ guts.resetFalsingCheck();
+ mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(),
+ row);
+ };
+
+ if (!userHandle.equals(UserHandle.ALL)
+ || mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
+ onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
+ mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO);
+ guts.resetFalsingCheck();
+ mOnSettingsClickListener.onSettingsClick(sbn.getKey());
+ startAppNotificationSettingsActivity(packageName, appUid, channel, row);
+ };
+ }
+
+ notificationInfoView.bindNotification(
+ pmUser,
+ mNotificationManager,
+ mOnUserInteractionCallback,
+ mChannelEditorDialogController,
+ packageName,
+ row.getEntry().getChannel(),
+ row.getEntry(),
+ onSettingsClick,
+ onAppSettingsClick,
+ mUiEventLogger,
+ mDeviceProvisionedController.isDeviceProvisioned(),
+ row.getIsNonblockable(),
+ mHighPriorityProvider.isHighPriority(row.getEntry()),
+ mAssistantFeedbackController,
+ mMetricsLogger);
+ }
+
+ /**
* Sets up the {@link PartialConversationInfo} inside the notification row's guts.
* @param row view to set up the guts for
* @param notificationInfoView view to set up/bind within {@code row}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index bdfbc4b53943..6e8ec9576f80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.row;
+import static android.app.NotificationChannel.SYSTEM_RESERVED_IDS;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
@@ -261,7 +262,11 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
mFeedbackItem = createFeedbackItem(mContext);
NotificationEntry entry = mParent.getEntry();
int personNotifType = mPeopleNotificationIdentifier.getPeopleNotificationType(entry);
- if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
+ if (android.app.Flags.notificationClassificationUi()
+ && SYSTEM_RESERVED_IDS.contains(entry.getChannel().getId())) {
+ // Bundled notification; create bundle-specific guts.
+ mInfoItem = createBundleItem(mContext);
+ } else if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
mInfoItem = createPartialConversationItem(mContext);
} else if (personNotifType >= PeopleNotificationIdentifier.TYPE_FULL_PERSON) {
mInfoItem = createConversationItem(mContext);
@@ -677,6 +682,16 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
R.drawable.ic_settings);
}
+ static NotificationMenuItem createBundleItem(Context context) {
+ Resources res = context.getResources();
+ String infoDescription = res.getString(R.string.notification_menu_gear_description);
+ BundleNotificationInfo infoContent =
+ (BundleNotificationInfo) LayoutInflater.from(context).inflate(
+ R.layout.bundle_notification_info, null, false);
+ return new NotificationMenuItem(context, infoDescription, infoContent,
+ R.drawable.ic_settings);
+ }
+
static NotificationMenuItem createPartialConversationItem(Context context) {
Resources res = context.getResources();
String infoDescription = res.getString(R.string.notification_menu_gear_description);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 2dcb706234b8..d0c033bb10b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -834,6 +834,15 @@ constructor(
public?.let {
it.layoutInflaterFactory = provider.provide(row, FLAG_CONTENT_VIEW_PUBLIC)
}
+ if (android.app.Flags.notificationsRedesignAppIcons()) {
+ normalGroupHeader?.let {
+ it.layoutInflaterFactory = provider.provide(row, FLAG_GROUP_SUMMARY_HEADER)
+ }
+ minimizedGroupHeader?.let {
+ it.layoutInflaterFactory =
+ provider.provide(row, FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER)
+ }
+ }
return this
}
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 80c8e8b2a109..db294934c9ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -171,14 +171,12 @@ import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeController;
-import com.android.systemui.shade.ShadeExpandsOnStatusBarLongPress;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.shade.ShadeExpansionListener;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.shade.ShadeLogger;
import com.android.systemui.shade.ShadeSurface;
import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shade.StatusBarLongPressGestureDetector;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -368,7 +366,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
private PhoneStatusBarViewController mPhoneStatusBarViewController;
private PhoneStatusBarTransitions mStatusBarTransitions;
- private final Provider<StatusBarLongPressGestureDetector> mStatusBarLongPressGestureDetector;
private final AuthRippleController mAuthRippleController;
@WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
private final NotificationShadeWindowController mNotificationShadeWindowController;
@@ -674,7 +671,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
ShadeController shadeController,
WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
- Provider<StatusBarLongPressGestureDetector> statusBarLongPressGestureDetector,
ViewMediatorCallback viewMediatorCallback,
InitController initController,
@Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
@@ -782,7 +778,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mShadeController = shadeController;
mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
- mStatusBarLongPressGestureDetector = statusBarLongPressGestureDetector;
mKeyguardViewMediatorCallback = viewMediatorCallback;
mInitController = initController;
mPluginDependencyProvider = pluginDependencyProvider;
@@ -1532,11 +1527,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
// to touch outside the customizer to close it, such as on the status or nav bar.
mShadeController.onStatusBarTouch(event);
}
- if (ShadeExpandsOnStatusBarLongPress.isEnabled()
- && mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
- mStatusBarLongPressGestureDetector.get().handleTouch(event);
- }
-
return getNotificationShadeWindowView().onTouchEvent(event);
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
index 7ef1e416aa19..5837a498e44f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
import javax.inject.Inject;
@@ -63,17 +64,21 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
@Override
public void addCallback(@NonNull Callback callback) {
- mCallbacks.add(callback);
- if (mCallbacks.size() == 1) {
- setListening(true);
+ synchronized (mCallbacks) {
+ mCallbacks.add(callback);
+ if (mCallbacks.size() == 1) {
+ setListening(true);
+ }
+ callback.onManagedProfileChanged();
}
- callback.onManagedProfileChanged();
}
@Override
public void removeCallback(@NonNull Callback callback) {
- if (mCallbacks.remove(callback) && mCallbacks.size() == 0) {
- setListening(false);
+ synchronized (mCallbacks) {
+ if (mCallbacks.remove(callback) && mCallbacks.size() == 0) {
+ setListening(false);
+ }
}
}
@@ -109,10 +114,7 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
}
private void notifyManagedProfileRemoved() {
- ArrayList<Callback> copy = new ArrayList<>(mCallbacks);
- for (Callback callback : copy) {
- callback.onManagedProfileRemoved();
- }
+ notifyCallbacks(Callback::onManagedProfileRemoved);
}
public boolean hasActiveProfile() {
@@ -136,6 +138,16 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
}
}
+ private void notifyCallbacks(Consumer<Callback> method) {
+ ArrayList<Callback> copy;
+ synchronized (mCallbacks) {
+ copy = new ArrayList<>(mCallbacks);
+ }
+ for (Callback callback : copy) {
+ method.accept(callback);
+ }
+ }
+
private void setListening(boolean listening) {
if (mListening == listening) {
return;
@@ -154,19 +166,13 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
@Override
public void onUserChanged(int newUser, @NonNull Context userContext) {
reloadManagedProfiles();
- ArrayList<Callback> copy = new ArrayList<>(mCallbacks);
- for (Callback callback : copy) {
- callback.onManagedProfileChanged();
- }
+ notifyCallbacks(Callback::onManagedProfileChanged);
}
@Override
public void onProfilesChanged(@NonNull List<UserInfo> profiles) {
reloadManagedProfiles();
- ArrayList<Callback> copy = new ArrayList<>(mCallbacks);
- for (Callback callback : copy) {
- callback.onManagedProfileChanged();
- }
+ notifyCallbacks(Callback::onManagedProfileChanged);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
index f6f567f17077..298ef7ee4bfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -88,7 +88,7 @@ public class BaseHeadsUpManager
implements HeadsUpManager, HeadsUpRepository, OnHeadsUpChangedListener {
private static final String TAG = "BaseHeadsUpManager";
private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms";
-
+ private static final String REASON_REORDER_ALLOWED = "mOnReorderingAllowedListener";
protected final ListenerSet<OnHeadsUpChangedListener> mListeners = new ListenerSet<>();
protected final Context mContext;
@@ -633,7 +633,7 @@ public class BaseHeadsUpManager
}
entry.demoteStickyHun();
mHeadsUpEntryMap.remove(key);
- onEntryRemoved(finalHeadsUpEntry);
+ onEntryRemoved(finalHeadsUpEntry, reason);
// TODO(b/328390331) move accessibility events to the view layer
entry.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
if (NotificationThrottleHun.isEnabled()) {
@@ -648,8 +648,9 @@ public class BaseHeadsUpManager
/**
* Manager-specific logic that should occur when an entry is removed.
* @param headsUpEntry entry removed
+ * @param reason why onEntryRemoved was called
*/
- protected void onEntryRemoved(HeadsUpEntry headsUpEntry) {
+ protected void onEntryRemoved(HeadsUpEntry headsUpEntry, String reason) {
NotificationEntry entry = headsUpEntry.mEntry;
entry.setHeadsUp(false);
setEntryPinned(headsUpEntry, false /* isPinned */, "onEntryRemoved");
@@ -664,10 +665,17 @@ public class BaseHeadsUpManager
updateTopHeadsUpFlow();
updateHeadsUpFlow();
if (NotificationThrottleHun.isEnabled()) {
- if (headsUpEntry.mEntry != null) {
- if (mEntriesToRemoveWhenReorderingAllowed.contains(headsUpEntry.mEntry)) {
- mEntriesToRemoveWhenReorderingAllowed.remove(headsUpEntry.mEntry);
- }
+ NotificationEntry notifEntry = headsUpEntry.mEntry;
+ if (notifEntry == null) {
+ return;
+ }
+ // If reorder was just allowed and we called onEntryRemoved while iterating over
+ // mEntriesToRemoveWhenReorderingAllowed, we should not remove from this list (and cause
+ // ArrayIndexOutOfBoundsException). We don't need to in this case anyway, because we
+ // clear mEntriesToRemoveWhenReorderingAllowed after removing these entries.
+ if (!reason.equals(REASON_REORDER_ALLOWED)
+ && mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)) {
+ mEntriesToRemoveWhenReorderingAllowed.remove(notifEntry);
}
}
}
@@ -1135,7 +1143,8 @@ public class BaseHeadsUpManager
&& Notification.CATEGORY_CALL.equals(n.category));
}
- private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> {
+ @VisibleForTesting
+ public final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> {
if (NotificationThrottleHun.isEnabled()) {
mAvalancheController.setEnableAtRuntime(true);
if (mEntriesToRemoveWhenReorderingAllowed.isEmpty()) {
@@ -1146,7 +1155,7 @@ public class BaseHeadsUpManager
for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) {
if (entry != null && isHeadsUpEntry(entry.getKey())) {
// Maybe the heads-up was removed already
- removeEntry(entry.getKey(), "mOnReorderingAllowedListener");
+ removeEntry(entry.getKey(), REASON_REORDER_ALLOWED);
}
}
mEntriesToRemoveWhenReorderingAllowed.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
index d371acf86a28..66a900bd72d8 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
@@ -18,6 +18,7 @@ package com.android.systemui.touchpad.tutorial.ui.composable
import android.content.res.Configuration
import androidx.compose.foundation.background
+import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -36,8 +37,12 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.pointer.pointerInteropFilter
@@ -49,6 +54,7 @@ import com.android.systemui.inputdevice.tutorial.ui.composable.DoneButton
import com.android.systemui.res.R
import com.android.systemui.touchpad.tutorial.ui.gesture.isFourFingerTouchpadSwipe
import com.android.systemui.touchpad.tutorial.ui.gesture.isThreeFingerTouchpadSwipe
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen
@Composable
fun TutorialSelectionScreen(
@@ -56,6 +62,7 @@ fun TutorialSelectionScreen(
onHomeTutorialClicked: () -> Unit,
onRecentAppsTutorialClicked: () -> Unit,
onDoneButtonClicked: () -> Unit,
+ lastSelectedScreen: Screen,
) {
Column(
verticalArrangement = Arrangement.Center,
@@ -80,6 +87,7 @@ fun TutorialSelectionScreen(
onHomeTutorialClicked = onHomeTutorialClicked,
onRecentAppsTutorialClicked = onRecentAppsTutorialClicked,
modifier = Modifier.weight(1f).padding(60.dp),
+ lastSelectedScreen,
)
}
else -> {
@@ -88,6 +96,7 @@ fun TutorialSelectionScreen(
onHomeTutorialClicked = onHomeTutorialClicked,
onRecentAppsTutorialClicked = onRecentAppsTutorialClicked,
modifier = Modifier.weight(1f).padding(60.dp),
+ lastSelectedScreen,
)
}
}
@@ -105,6 +114,7 @@ private fun HorizontalSelectionButtons(
onHomeTutorialClicked: () -> Unit,
onRecentAppsTutorialClicked: () -> Unit,
modifier: Modifier = Modifier,
+ lastSelectedScreen: Screen,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(20.dp),
@@ -116,6 +126,7 @@ private fun HorizontalSelectionButtons(
onHomeTutorialClicked,
onRecentAppsTutorialClicked,
modifier = Modifier.weight(1f).fillMaxSize(),
+ lastSelectedScreen,
)
}
}
@@ -126,6 +137,7 @@ private fun VerticalSelectionButtons(
onHomeTutorialClicked: () -> Unit,
onRecentAppsTutorialClicked: () -> Unit,
modifier: Modifier = Modifier,
+ lastSelectedScreen: Screen,
) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp),
@@ -137,6 +149,7 @@ private fun VerticalSelectionButtons(
onHomeTutorialClicked,
onRecentAppsTutorialClicked,
modifier = Modifier.weight(1f).fillMaxSize(),
+ lastSelectedScreen,
)
}
}
@@ -147,14 +160,26 @@ private fun ThreeTutorialButtons(
onHomeTutorialClicked: () -> Unit,
onRecentAppsTutorialClicked: () -> Unit,
modifier: Modifier = Modifier,
+ lastSelectedScreen: Screen,
) {
+ val homeFocusRequester = remember { FocusRequester() }
+ val backFocusRequester = remember { FocusRequester() }
+ val recentAppsFocusRequester = remember { FocusRequester() }
+ LaunchedEffect(Unit) {
+ when (lastSelectedScreen) {
+ Screen.HOME_GESTURE -> homeFocusRequester.requestFocus()
+ Screen.BACK_GESTURE -> backFocusRequester.requestFocus()
+ Screen.RECENT_APPS_GESTURE -> recentAppsFocusRequester.requestFocus()
+ else -> {} // No-Op.
+ }
+ }
TutorialButton(
text = stringResource(R.string.touchpad_tutorial_home_gesture_button),
icon = ImageVector.vectorResource(id = R.drawable.touchpad_tutorial_home_icon),
iconColor = MaterialTheme.colorScheme.onPrimary,
onClick = onHomeTutorialClicked,
backgroundColor = MaterialTheme.colorScheme.primary,
- modifier = modifier,
+ modifier = modifier.focusRequester(homeFocusRequester).focusable(),
)
TutorialButton(
text = stringResource(R.string.touchpad_tutorial_back_gesture_button),
@@ -162,7 +187,7 @@ private fun ThreeTutorialButtons(
iconColor = MaterialTheme.colorScheme.onTertiary,
onClick = onBackTutorialClicked,
backgroundColor = MaterialTheme.colorScheme.tertiary,
- modifier = modifier,
+ modifier = modifier.focusRequester(backFocusRequester).focusable(),
)
TutorialButton(
text = stringResource(R.string.touchpad_tutorial_recent_apps_gesture_button),
@@ -170,7 +195,7 @@ private fun ThreeTutorialButtons(
iconColor = MaterialTheme.colorScheme.onSecondary,
onClick = onRecentAppsTutorialClicked,
backgroundColor = MaterialTheme.colorScheme.secondary,
- modifier = modifier,
+ modifier = modifier.focusRequester(recentAppsFocusRequester).focusable(),
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
index e1f7bd59005c..6662fc5c127c 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
@@ -24,12 +24,16 @@ import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.theme.PlatformTheme
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger.TutorialContext
import com.android.systemui.inputdevice.tutorial.KeyboardTouchpadTutorialMetricsLogger
+import com.android.systemui.res.R
import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen
import com.android.systemui.touchpad.tutorial.ui.composable.HomeGestureTutorialScreen
import com.android.systemui.touchpad.tutorial.ui.composable.RecentAppsGestureTutorialScreen
@@ -54,6 +58,7 @@ constructor(
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
+ setTitle(getString(R.string.launch_touchpad_tutorial_notification_content))
setContent {
PlatformTheme { TouchpadTutorialScreen(vm, closeTutorial = ::finishTutorial) }
}
@@ -82,13 +87,24 @@ constructor(
@Composable
fun TouchpadTutorialScreen(vm: TouchpadTutorialViewModel, closeTutorial: () -> Unit) {
val activeScreen by vm.screen.collectAsStateWithLifecycle(STARTED)
+ var lastSelectedScreen by remember { mutableStateOf(TUTORIAL_SELECTION) }
when (activeScreen) {
TUTORIAL_SELECTION ->
TutorialSelectionScreen(
- onBackTutorialClicked = { vm.goTo(BACK_GESTURE) },
- onHomeTutorialClicked = { vm.goTo(HOME_GESTURE) },
- onRecentAppsTutorialClicked = { vm.goTo(RECENT_APPS_GESTURE) },
+ onBackTutorialClicked = {
+ lastSelectedScreen = BACK_GESTURE
+ vm.goTo(BACK_GESTURE)
+ },
+ onHomeTutorialClicked = {
+ lastSelectedScreen = HOME_GESTURE
+ vm.goTo(HOME_GESTURE)
+ },
+ onRecentAppsTutorialClicked = {
+ lastSelectedScreen = RECENT_APPS_GESTURE
+ vm.goTo(RECENT_APPS_GESTURE)
+ },
onDoneButtonClicked = closeTutorial,
+ lastSelectedScreen,
)
BACK_GESTURE ->
BackGestureTutorialScreen(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
index c4b028d7d98b..1963ba22d444 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
@@ -18,14 +18,18 @@ package com.android.systemui.volume.dialog.ringer.ui.binder
import android.view.LayoutInflater
import android.view.View
-import android.view.ViewGroup
import android.widget.ImageButton
import androidx.annotation.LayoutRes
import androidx.compose.ui.util.fastForEachIndexed
+import androidx.constraintlayout.motion.widget.MotionLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.internal.R as internalR
+import com.android.settingslib.Utils
import com.android.systemui.lifecycle.WindowLifecycleState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
+import com.android.systemui.util.children
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerButtonViewModel
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerDrawerState
@@ -33,7 +37,6 @@ import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerViewModel
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerViewModelState
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.VolumeDialogRingerDrawerViewModel
import javax.inject.Inject
-import kotlin.math.abs
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -44,12 +47,8 @@ constructor(private val viewModelFactory: VolumeDialogRingerDrawerViewModel.Fact
fun bind(view: View) {
with(view) {
- val drawerAndRingerContainer =
- requireViewById<View>(R.id.volume_ringer_and_drawer_container)
- val drawerContainer = requireViewById<View>(R.id.volume_drawer_container)
- val selectedButtonView =
- requireViewById<ImageButton>(R.id.volume_new_ringer_active_button)
val volumeDialogBackgroundView = requireViewById<View>(R.id.volume_dialog_background)
+ val drawerContainer = requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
repeatWhenAttached {
viewModel(
traceName = "VolumeDialogRingerViewBinder",
@@ -62,29 +61,26 @@ constructor(private val viewModelFactory: VolumeDialogRingerDrawerViewModel.Fact
is RingerViewModelState.Available -> {
val uiModel = ringerState.uiModel
- bindSelectedButton(viewModel, uiModel, selectedButtonView)
- bindDrawerButtons(viewModel, uiModel.availableButtons)
+ bindDrawerButtons(viewModel, uiModel)
- // Set up views background and visibility
- drawerAndRingerContainer.visibility = View.VISIBLE
+ // Set up view background and visibility
+ drawerContainer.visibility = View.VISIBLE
when (uiModel.drawerState) {
is RingerDrawerState.Initial -> {
- drawerContainer.visibility = View.GONE
- selectedButtonView.visibility = View.VISIBLE
+ drawerContainer.closeDrawer(uiModel.currentButtonIndex)
volumeDialogBackgroundView.setBackgroundResource(
R.drawable.volume_dialog_background
)
}
is RingerDrawerState.Closed -> {
- drawerContainer.visibility = View.GONE
- selectedButtonView.visibility = View.VISIBLE
+ drawerContainer.closeDrawer(uiModel.currentButtonIndex)
volumeDialogBackgroundView.setBackgroundResource(
R.drawable.volume_dialog_background
)
}
is RingerDrawerState.Open -> {
- drawerContainer.visibility = View.VISIBLE
- selectedButtonView.visibility = View.GONE
+ // Open drawer
+ drawerContainer.transitionToEnd()
if (
uiModel.currentButtonIndex !=
uiModel.availableButtons.size - 1
@@ -97,7 +93,7 @@ constructor(private val viewModelFactory: VolumeDialogRingerDrawerViewModel.Fact
}
}
is RingerViewModelState.Unavailable -> {
- drawerAndRingerContainer.visibility = View.GONE
+ drawerContainer.visibility = View.GONE
volumeDialogBackgroundView.setBackgroundResource(
R.drawable.volume_dialog_background
)
@@ -112,15 +108,21 @@ constructor(private val viewModelFactory: VolumeDialogRingerDrawerViewModel.Fact
private fun View.bindDrawerButtons(
viewModel: VolumeDialogRingerDrawerViewModel,
- availableButtons: List<RingerButtonViewModel?>,
+ uiModel: RingerViewModel,
) {
- val drawerOptions = requireViewById<ViewGroup>(R.id.volume_drawer_options)
- val count = availableButtons.size
- drawerOptions.ensureChildCount(R.layout.volume_ringer_button, count)
+ val drawerContainer = requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
+ val count = uiModel.availableButtons.size
+ drawerContainer.ensureChildCount(R.layout.volume_ringer_button, count)
- availableButtons.fastForEachIndexed { index, ringerButton ->
+ uiModel.availableButtons.fastForEachIndexed { index, ringerButton ->
ringerButton?.let {
- drawerOptions.getChildAt(count - index - 1).bindDrawerButton(it, viewModel)
+ val view = drawerContainer.getChildAt(count - index - 1)
+ // TODO (b/369995871): object animator for button switch ( active <-> inactive )
+ if (index == uiModel.currentButtonIndex) {
+ view.bindDrawerButton(uiModel.selectedButton, viewModel, isSelected = true)
+ } else {
+ view.bindDrawerButton(it, viewModel)
+ }
}
}
}
@@ -128,15 +130,29 @@ constructor(private val viewModelFactory: VolumeDialogRingerDrawerViewModel.Fact
private fun View.bindDrawerButton(
buttonViewModel: RingerButtonViewModel,
viewModel: VolumeDialogRingerDrawerViewModel,
+ isSelected: Boolean = false,
) {
with(requireViewById<ImageButton>(R.id.volume_drawer_button)) {
setImageResource(buttonViewModel.imageResId)
contentDescription = context.getString(buttonViewModel.contentDescriptionResId)
- setOnClickListener { viewModel.onRingerButtonClicked(buttonViewModel.ringerMode) }
+ if (isSelected) {
+ setBackgroundResource(R.drawable.volume_drawer_selection_bg)
+ setColorFilter(
+ Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnPrimary)
+ )
+ } else {
+ setBackgroundResource(R.drawable.volume_ringer_item_bg)
+ setColorFilter(
+ Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnSurface)
+ )
+ }
+ setOnClickListener {
+ viewModel.onRingerButtonClicked(buttonViewModel.ringerMode, isSelected)
+ }
}
}
- private fun ViewGroup.ensureChildCount(@LayoutRes viewLayoutId: Int, count: Int) {
+ private fun MotionLayout.ensureChildCount(@LayoutRes viewLayoutId: Int, count: Int) {
val childCountDelta = childCount - count
when {
childCountDelta > 0 -> {
@@ -144,21 +160,107 @@ constructor(private val viewModelFactory: VolumeDialogRingerDrawerViewModel.Fact
}
childCountDelta < 0 -> {
val inflater = LayoutInflater.from(context)
- repeat(abs(childCountDelta)) { inflater.inflate(viewLayoutId, this, true) }
+ repeat(-childCountDelta) {
+ inflater.inflate(viewLayoutId, this, true)
+ getChildAt(childCount - 1).id = View.generateViewId()
+ }
+ cloneConstraintSet(R.id.volume_dialog_ringer_drawer_open)
+ .adjustOpenConstraintsForDrawer(this)
}
}
}
- private fun bindSelectedButton(
- viewModel: VolumeDialogRingerDrawerViewModel,
- uiModel: RingerViewModel,
- selectedButtonView: ImageButton,
+ private fun MotionLayout.closeDrawer(selectedIndex: Int) {
+ cloneConstraintSet(R.id.volume_dialog_ringer_drawer_close)
+ .adjustClosedConstraintsForDrawer(selectedIndex, this)
+ transitionToStart()
+ }
+
+ private fun ConstraintSet.adjustOpenConstraintsForDrawer(motionLayout: MotionLayout) {
+ motionLayout.children.forEachIndexed { index, button ->
+ setButtonPositionConstraints(motionLayout, index, button)
+ setAlpha(button.id, 1.0F)
+ constrainWidth(
+ button.id,
+ motionLayout.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_ringer_drawer_button_size
+ ),
+ )
+ constrainHeight(
+ button.id,
+ motionLayout.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_ringer_drawer_button_size
+ ),
+ )
+ if (index != motionLayout.childCount - 1) {
+ setMargin(
+ button.id,
+ ConstraintSet.BOTTOM,
+ motionLayout.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_components_spacing
+ ),
+ )
+ }
+ }
+ motionLayout.updateState(R.id.volume_dialog_ringer_drawer_open, this)
+ }
+
+ private fun ConstraintSet.adjustClosedConstraintsForDrawer(
+ selectedIndex: Int,
+ motionLayout: MotionLayout,
) {
- with(uiModel) {
- selectedButtonView.setImageResource(selectedButton.imageResId)
- selectedButtonView.setOnClickListener {
- viewModel.onRingerButtonClicked(selectedButton.ringerMode)
+ motionLayout.children.forEachIndexed { index, button ->
+ setButtonPositionConstraints(motionLayout, index, button)
+ constrainWidth(
+ button.id,
+ motionLayout.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_ringer_drawer_button_size
+ ),
+ )
+ if (selectedIndex != motionLayout.childCount - index - 1) {
+ setAlpha(button.id, 0.0F)
+ constrainHeight(button.id, 0)
+ setMargin(button.id, ConstraintSet.BOTTOM, 0)
+ } else {
+ setAlpha(button.id, 1.0F)
+ constrainHeight(
+ button.id,
+ motionLayout.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_ringer_drawer_button_size
+ ),
+ )
}
}
+ motionLayout.updateState(R.id.volume_dialog_ringer_drawer_close, this)
+ }
+
+ private fun ConstraintSet.setButtonPositionConstraints(
+ motionLayout: MotionLayout,
+ index: Int,
+ button: View,
+ ) {
+ if (motionLayout.getChildAt(index - 1) == null) {
+ connect(button.id, ConstraintSet.TOP, motionLayout.id, ConstraintSet.TOP)
+ } else {
+ connect(
+ button.id,
+ ConstraintSet.TOP,
+ motionLayout.getChildAt(index - 1).id,
+ ConstraintSet.BOTTOM,
+ )
+ }
+
+ if (motionLayout.getChildAt(index + 1) == null) {
+ connect(button.id, ConstraintSet.BOTTOM, motionLayout.id, ConstraintSet.BOTTOM)
+ } else {
+ connect(
+ button.id,
+ ConstraintSet.BOTTOM,
+ motionLayout.getChildAt(index + 1).id,
+ ConstraintSet.TOP,
+ )
+ }
+ connect(button.id, ConstraintSet.START, motionLayout.id, ConstraintSet.START)
+ connect(button.id, ConstraintSet.END, motionLayout.id, ConstraintSet.END)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
index e040638324ac..624dcc71e2a9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
@@ -84,8 +84,8 @@ constructor(
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.build()
- fun onRingerButtonClicked(ringerMode: RingerMode) {
- if (drawerState.value is RingerDrawerState.Open) {
+ fun onRingerButtonClicked(ringerMode: RingerMode, isSelectedButton: Boolean = false) {
+ if (drawerState.value is RingerDrawerState.Open && !isSelectedButton) {
Events.writeEvent(Events.EVENT_RINGER_TOGGLE, ringerMode.value)
provideTouchFeedback(ringerMode)
maybeShowToast(ringerMode)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
index 538ee47915a8..772ae7736cad 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/dagger/VolumeDialogSliderComponent.kt
@@ -17,6 +17,7 @@
package com.android.systemui.volume.dialog.sliders.dagger
import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
+import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderTouchesViewBinder
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
import dagger.BindsInstance
import dagger.Subcomponent
@@ -31,6 +32,8 @@ interface VolumeDialogSliderComponent {
fun sliderViewBinder(): VolumeDialogSliderViewBinder
+ fun sliderTouchesViewBinder(): VolumeDialogSliderTouchesViewBinder
+
@Subcomponent.Factory
interface Factory {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepository.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepository.kt
new file mode 100644
index 000000000000..adc2383c3a46
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepository.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.dialog.sliders.data.repository
+
+import android.annotation.SuppressLint
+import android.view.MotionEvent
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+
+@VolumeDialogSliderScope
+class VolumeDialogSliderTouchEventsRepository @Inject constructor() {
+
+ @SuppressLint("SharedFlowCreation")
+ private val mutableSliderTouchEvents: MutableStateFlow<MotionEvent?> = MutableStateFlow(null)
+ val sliderTouchEvent: Flow<MotionEvent> = mutableSliderTouchEvents.filterNotNull()
+
+ fun update(event: MotionEvent) {
+ mutableSliderTouchEvents.tryEmit(MotionEvent.obtain(event))
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractor.kt
new file mode 100644
index 000000000000..c7b4184a9f2f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractor.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.dialog.sliders.domain.interactor
+
+import android.view.MotionEvent
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
+import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogCallbacksInteractor
+import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
+import com.android.systemui.volume.dialog.domain.model.VolumeDialogEventModel
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
+import com.android.systemui.volume.dialog.sliders.data.repository.VolumeDialogSliderTouchEventsRepository
+import com.android.systemui.volume.dialog.sliders.shared.model.SliderInputEvent
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filterIsInstance
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
+
+@VolumeDialogSliderScope
+class VolumeDialogSliderInputEventsInteractor
+@Inject
+constructor(
+ @VolumeDialog coroutineScope: CoroutineScope,
+ volumeDialogCallbacksInteractor: VolumeDialogCallbacksInteractor,
+ private val visibilityInteractor: VolumeDialogVisibilityInteractor,
+ private val repository: VolumeDialogSliderTouchEventsRepository,
+) {
+
+ val event: Flow<SliderInputEvent> =
+ merge(
+ repository.sliderTouchEvent.map { SliderInputEvent.Touch(it) },
+ volumeDialogCallbacksInteractor.event
+ .filterIsInstance(VolumeDialogEventModel.VolumeChangedFromKey::class)
+ .map { SliderInputEvent.Button },
+ )
+
+ init {
+ event.onEach { visibilityInteractor.resetDismissTimeout() }.launchIn(coroutineScope)
+ }
+
+ fun onTouchEvent(newEvent: MotionEvent) {
+ repository.update(newEvent)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractor.kt
index 66a598b7cf1b..c904ac5e3ae1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractor.kt
@@ -35,6 +35,7 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.runningReduce
import kotlinx.coroutines.flow.stateIn
private const val DEFAULT_STREAM = AudioManager.STREAM_MUSIC
@@ -54,13 +55,17 @@ constructor(
volumeDialogStateInteractor.volumeDialogState
.filter { it.streamModels.isNotEmpty() }
.map { stateModel ->
- stateModel.streamModels.values
- .filter { streamModel -> shouldShowSliders(stateModel, streamModel) }
- .sortedWith(streamsSorter)
+ val sliderTypes =
+ stateModel.streamModels.values
+ .filter { streamModel -> shouldShowSliders(stateModel, streamModel) }
+ .sortedWith(streamsSorter)
+ .map { model -> model.toType() }
+ LinkedHashSet(sliderTypes)
}
- .map { models ->
- val sliderTypes: List<VolumeDialogSliderType> =
- models.map { model -> model.toType() }
+ .runningReduce { sliderTypes, newSliderTypes ->
+ newSliderTypes.apply { addAll(sliderTypes) }
+ }
+ .map { sliderTypes ->
VolumeDialogSlidersModel(
slider = sliderTypes.first(),
floatingSliders = sliderTypes.drop(1),
diff --git a/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/shared/model/SliderInputEvent.kt
index 6bbbeb8e1e06..37dbb4b3a81d 100644
--- a/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/shared/model/SliderInputEvent.kt
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-package android.media.tv.extension.scan;
+package com.android.systemui.volume.dialog.sliders.shared.model
-import android.os.Bundle;
+import android.view.MotionEvent
-/**
- * @hide
- */
-oneway interface ILcnConflictListener {
- void onDetectLcnConflict(in Bundle detectLcnConflicts);
+/** Models input event happened on the Volume Slider */
+sealed interface SliderInputEvent {
+
+ data class Touch(val event: MotionEvent) : SliderInputEvent
+
+ data object Button : SliderInputEvent
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt
new file mode 100644
index 000000000000..7fd177d55d76
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderTouchesViewBinder.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.dialog.sliders.ui
+
+import android.annotation.SuppressLint
+import android.view.View
+import com.android.systemui.lifecycle.WindowLifecycleState
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.lifecycle.viewModel
+import com.android.systemui.res.R
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
+import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderTouchesViewModel
+import com.google.android.material.slider.Slider
+import javax.inject.Inject
+
+@VolumeDialogSliderScope
+class VolumeDialogSliderTouchesViewBinder
+@Inject
+constructor(private val viewModelFactory: VolumeDialogSliderTouchesViewModel.Factory) {
+
+ @SuppressLint("ClickableViewAccessibility")
+ fun bind(view: View) {
+ with(view.requireViewById<Slider>(R.id.volume_dialog_slider)) {
+ repeatWhenAttached {
+ viewModel(
+ traceName = "VolumeDialogSliderTouchesViewBinder",
+ minWindowLifecycleState = WindowLifecycleState.ATTACHED,
+ factory = { viewModelFactory.create() },
+ ) { viewModel ->
+ setOnTouchListener { _, event ->
+ viewModel.onTouchEvent(event)
+ false
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
index 9078f82d3e98..1b2b4fff5b8e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSlidersViewBinder.kt
@@ -26,6 +26,7 @@ import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
+import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderComponent
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSlidersViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.launchIn
@@ -50,7 +51,7 @@ constructor(private val viewModelFactory: VolumeDialogSlidersViewModel.Factory)
) { viewModel ->
viewModel.sliders
.onEach { uiModel ->
- uiModel.sliderComponent.sliderViewBinder().bind(mainSliderContainer)
+ uiModel.sliderComponent.bindSlider(mainSliderContainer)
val floatingSliderViewBinders = uiModel.floatingSliderComponent
floatingSlidersContainer.ensureChildCount(
@@ -58,9 +59,9 @@ constructor(private val viewModelFactory: VolumeDialogSlidersViewModel.Factory)
count = floatingSliderViewBinders.size,
)
floatingSliderViewBinders.fastForEachIndexed { index, sliderComponent ->
- sliderComponent
- .sliderViewBinder()
- .bind(floatingSlidersContainer.getChildAt(index))
+ sliderComponent.bindSlider(
+ floatingSlidersContainer.getChildAt(index)
+ )
}
}
.launchIn(this)
@@ -68,6 +69,11 @@ constructor(private val viewModelFactory: VolumeDialogSlidersViewModel.Factory)
}
}
}
+
+ private fun VolumeDialogSliderComponent.bindSlider(sliderContainer: View) {
+ sliderViewBinder().bind(sliderContainer)
+ sliderTouchesViewBinder().bind(sliderContainer)
+ }
}
private fun ViewGroup.ensureChildCount(@LayoutRes viewLayoutId: Int, count: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderQuantization.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt
index 033d55cc9b61..144c75da2b2b 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderQuantization.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderTouchesViewModel.kt
@@ -14,13 +14,23 @@
* limitations under the License.
*/
-package com.android.systemui.haptics.slider
+package com.android.systemui.volume.dialog.sliders.ui.viewmodel
-interface SliderQuantization {
- /** What is the step size between discrete steps of the slider */
- val stepSize: Float
+import android.view.MotionEvent
+import com.android.systemui.volume.dialog.sliders.domain.interactor.VolumeDialogSliderInputEventsInteractor
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
- data class Continuous(override val stepSize: Float = Float.MIN_VALUE) : SliderQuantization
+class VolumeDialogSliderTouchesViewModel
+@AssistedInject
+constructor(private val interactor: VolumeDialogSliderInputEventsInteractor) {
- data class Discrete(override val stepSize: Float) : SliderQuantization
+ fun onTouchEvent(event: MotionEvent) {
+ interactor.onTouchEvent(event)
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): VolumeDialogSliderTouchesViewModel
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 1ceac78af1a2..aa95abb3528f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -168,8 +168,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
public void showFullscreenModeButton_addViewAndSetImageResource() {
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- verify(mSpyImageView).setImageResource(
- getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
+ verify(mSpyImageView).setImageResource(getIconResId());
assertEquals(mSpyImageView, mWindowManager.getAttachedView());
assertShowFadingAnimation(FADE_IN_ALPHA);
assertShowFadingAnimation(FADE_OUT_ALPHA);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
index ec42b7fc4713..97abba7a4bcb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
@@ -31,8 +31,8 @@ import org.junit.runner.RunWith
@SmallTest
class FontInterpolatorTest : SysuiTestCase() {
- private val sFont = TextRunShaper.shapeTextRun("A", 0, 1, 0, 1, 0f, 0f, false, Paint())
- .getFont(0)
+ private val sFont =
+ TextRunShaper.shapeTextRun("A", 0, 1, 0, 1, 0f, 0f, false, Paint()).getFont(0)
private fun assertSameAxes(expect: Font, actual: Font) {
val expectAxes = expect.axes?.also { it.sortBy { axis -> axis.tag } }
@@ -42,21 +42,20 @@ class FontInterpolatorTest : SysuiTestCase() {
private fun assertSameAxes(expectVarSettings: String, actual: Font) {
- val expectAxes = FontVariationAxis.fromFontVariationSettings(expectVarSettings)?.also {
- it.sortBy { axis -> axis.tag }
- }
+ val expectAxes =
+ FontVariationAxis.fromFontVariationSettings(expectVarSettings)?.also {
+ it.sortBy { axis -> axis.tag }
+ }
val actualAxes = actual.axes?.also { it.sortBy { axis -> axis.tag } }
assertThat(actualAxes).isEqualTo(expectAxes)
}
@Test
fun textInterpolation() {
- val startFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 100, 'ital' 0, 'GRAD' 200")
- .build()
- val endFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 900, 'ital' 1, 'GRAD' 700")
- .build()
+ val startFont =
+ Font.Builder(sFont).setFontVariationSettings("'wght' 100, 'ital' 0, 'GRAD' 200").build()
+ val endFont =
+ Font.Builder(sFont).setFontVariationSettings("'wght' 900, 'ital' 1, 'GRAD' 700").build()
val interp = FontInterpolator()
assertSameAxes(startFont, interp.lerp(startFont, endFont, 0f))
@@ -66,12 +65,8 @@ class FontInterpolatorTest : SysuiTestCase() {
@Test
fun textInterpolation_DefaultValue() {
- val startFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 100")
- .build()
- val endFont = Font.Builder(sFont)
- .setFontVariationSettings("'ital' 1")
- .build()
+ val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+ val endFont = Font.Builder(sFont).setFontVariationSettings("'ital' 1").build()
val interp = FontInterpolator()
assertSameAxes("'wght' 250, 'ital' 0.5", interp.lerp(startFont, endFont, 0.5f))
@@ -79,12 +74,8 @@ class FontInterpolatorTest : SysuiTestCase() {
@Test
fun testInterpCache() {
- val startFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 100")
- .build()
- val endFont = Font.Builder(sFont)
- .setFontVariationSettings("'ital' 1")
- .build()
+ val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+ val endFont = Font.Builder(sFont).setFontVariationSettings("'ital' 1").build()
val interp = FontInterpolator()
val resultFont = interp.lerp(startFont, endFont, 0.5f)
@@ -94,12 +85,8 @@ class FontInterpolatorTest : SysuiTestCase() {
@Test
fun testAxesCache() {
- val startFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 100")
- .build()
- val endFont = Font.Builder(sFont)
- .setFontVariationSettings("'ital' 1")
- .build()
+ val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+ val endFont = Font.Builder(sFont).setFontVariationSettings("'ital' 1").build()
val interp = FontInterpolator()
val resultFont = interp.lerp(startFont, endFont, 0.5f)
@@ -111,20 +98,12 @@ class FontInterpolatorTest : SysuiTestCase() {
fun testCacheMaxSize() {
val interp = FontInterpolator()
- val startFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 100")
- .build()
- val endFont = Font.Builder(sFont)
- .setFontVariationSettings("'wght' 1")
- .build()
+ val startFont = Font.Builder(sFont).setFontVariationSettings("'wght' 100").build()
+ val endFont = Font.Builder(sFont).setFontVariationSettings("'wght' 1").build()
val resultFont = interp.lerp(startFont, endFont, 0.5f)
- for (i in 0..interp.cacheMaxEntries + 1) {
- val f1 = Font.Builder(sFont)
- .setFontVariationSettings("'wght' ${i * 100}")
- .build()
- val f2 = Font.Builder(sFont)
- .setFontVariationSettings("'wght' $i")
- .build()
+ for (i in 0..(interp.fontCache as FontCacheImpl).cacheMaxEntries + 1) {
+ val f1 = Font.Builder(sFont).setFontVariationSettings("'wght' ${i * 100}").build()
+ val f2 = Font.Builder(sFont).setFontVariationSettings("'wght' $i").build()
interp.lerp(f1, f2, 0.5f)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
index 6ba171525bd1..dcf38800bb01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
@@ -42,6 +42,8 @@ import org.mockito.Mockito.`when`
@SmallTest
class TextAnimatorTest : SysuiTestCase() {
+ private val typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf")
+
private fun makeLayout(text: String, paint: TextPaint): Layout {
val width = ceil(Layout.getDesiredWidth(text, 0, text.length, paint)).toInt()
return StaticLayout.Builder.obtain(text, 0, text.length, paint, width).build()
@@ -56,7 +58,7 @@ class TextAnimatorTest : SysuiTestCase() {
`when`(textInterpolator.targetPaint).thenReturn(paint)
val textAnimator =
- TextAnimator(layout, null, {}).apply {
+ TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
this.animator = valueAnimator
}
@@ -86,7 +88,7 @@ class TextAnimatorTest : SysuiTestCase() {
`when`(textInterpolator.targetPaint).thenReturn(paint)
val textAnimator =
- TextAnimator(layout, null, {}).apply {
+ TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
this.animator = valueAnimator
}
@@ -114,7 +116,7 @@ class TextAnimatorTest : SysuiTestCase() {
val animationEndCallback = mock(Runnable::class.java)
val textAnimator =
- TextAnimator(layout, null, {}).apply {
+ TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
this.animator = valueAnimator
}
@@ -122,7 +124,7 @@ class TextAnimatorTest : SysuiTestCase() {
textAnimator.setTextStyle(
weight = 400,
animate = true,
- onAnimationEnd = animationEndCallback
+ onAnimationEnd = animationEndCallback,
)
// Verify animationEnd callback has been added.
@@ -140,14 +142,11 @@ class TextAnimatorTest : SysuiTestCase() {
val layout = makeLayout("Hello, World", PAINT)
val valueAnimator = mock(ValueAnimator::class.java)
val textInterpolator = mock(TextInterpolator::class.java)
- val paint =
- TextPaint().apply {
- typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf")
- }
+ val paint = TextPaint().apply { this.typeface = typeface }
`when`(textInterpolator.targetPaint).thenReturn(paint)
val textAnimator =
- TextAnimator(layout, null, {}).apply {
+ TextAnimator(layout, TypefaceVariantCacheImpl(typeface, 20)).apply {
this.textInterpolator = textInterpolator
this.animator = valueAnimator
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
index cca5f3525ef6..c6fbe3fcd301 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
@@ -31,11 +31,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
+import java.io.File
+import kotlin.math.ceil
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
-import kotlin.math.ceil
private const val TEXT = "Hello, World."
private const val BIDI_TEXT = "abc\u05D0\u05D1\u05D2"
@@ -47,20 +47,23 @@ private const val BMP_HEIGHT = 300
private val VF_FONT = Font.Builder(File("/system/fonts/Roboto-Regular.ttf")).build()
private fun Font.toTypeface() =
- Typeface.CustomFallbackBuilder(FontFamily.Builder(this).build()).build()
+ Typeface.CustomFallbackBuilder(FontFamily.Builder(this).build()).build()
-internal val PAINT = TextPaint().apply {
- typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
- textSize = 32f
-}
+internal val PAINT =
+ TextPaint().apply {
+ typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
+ textSize = 32f
+ }
-private val START_PAINT = TextPaint(PAINT).apply {
- typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
-}
+private val START_PAINT =
+ TextPaint(PAINT).apply {
+ typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
+ }
-private val END_PAINT = TextPaint(PAINT).apply {
- typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 700").build().toTypeface()
-}
+private val END_PAINT =
+ TextPaint(PAINT).apply {
+ typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 700").build().toTypeface()
+ }
@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -70,16 +73,17 @@ class TextInterpolatorTest : SysuiTestCase() {
private fun makeLayout(
text: String,
paint: TextPaint,
- dir: TextDirectionHeuristic = TextDirectionHeuristics.LTR
+ dir: TextDirectionHeuristic = TextDirectionHeuristics.LTR,
): Layout {
val width = ceil(Layout.getDesiredWidth(text, 0, text.length, paint)).toInt()
return StaticLayout.Builder.obtain(text, 0, text.length, paint, width)
- .setTextDirection(dir).build()
+ .setTextDirection(dir)
+ .build()
}
@Before
fun setup() {
- typefaceCache = TypefaceVariantCacheImpl(PAINT.typeface)
+ typefaceCache = TypefaceVariantCacheImpl(PAINT.typeface, 10)
}
@Test
@@ -135,10 +139,10 @@ class TextInterpolatorTest : SysuiTestCase() {
// end state.
interp.progress = 0.5f
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- assertThat(actual.sameAs(makeLayout(TEXT, START_PAINT)
- .toBitmap(BMP_WIDTH, BMP_HEIGHT))).isFalse()
- assertThat(actual.sameAs(makeLayout(TEXT, END_PAINT)
- .toBitmap(BMP_WIDTH, BMP_HEIGHT))).isFalse()
+ assertThat(actual.sameAs(makeLayout(TEXT, START_PAINT).toBitmap(BMP_WIDTH, BMP_HEIGHT)))
+ .isFalse()
+ assertThat(actual.sameAs(makeLayout(TEXT, END_PAINT).toBitmap(BMP_WIDTH, BMP_HEIGHT)))
+ .isFalse()
}
@Test
@@ -177,7 +181,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
assertThat(interp.progress).isEqualTo(0f)
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.LTR)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.LTR)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
assertThat(expected.sameAs(actual)).isTrue()
@@ -197,7 +202,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
assertThat(interp.progress).isEqualTo(0f)
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
assertThat(expected.sameAs(actual)).isTrue()
@@ -207,10 +213,8 @@ class TextInterpolatorTest : SysuiTestCase() {
fun testGlyphCallback_Empty() {
val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
- val interp = TextInterpolator(layout, typefaceCache).apply {
- glyphFilter = { glyph, progress ->
- }
- }
+ val interp =
+ TextInterpolator(layout, typefaceCache).apply { glyphFilter = { glyph, progress -> } }
interp.basePaint.set(START_PAINT)
interp.onBasePaintModified()
@@ -219,7 +223,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
assertThat(expected.sameAs(actual)).isTrue()
@@ -229,11 +234,10 @@ class TextInterpolatorTest : SysuiTestCase() {
fun testGlyphCallback_Xcoordinate() {
val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
- val interp = TextInterpolator(layout, typefaceCache).apply {
- glyphFilter = { glyph, progress ->
- glyph.x += 30f
+ val interp =
+ TextInterpolator(layout, typefaceCache).apply {
+ glyphFilter = { glyph, progress -> glyph.x += 30f }
}
- }
interp.basePaint.set(START_PAINT)
interp.onBasePaintModified()
@@ -242,7 +246,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
// The glyph position was modified by callback, so the bitmap should not be the same.
@@ -254,11 +259,10 @@ class TextInterpolatorTest : SysuiTestCase() {
fun testGlyphCallback_Ycoordinate() {
val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
- val interp = TextInterpolator(layout, typefaceCache).apply {
- glyphFilter = { glyph, progress ->
- glyph.y += 30f
+ val interp =
+ TextInterpolator(layout, typefaceCache).apply {
+ glyphFilter = { glyph, progress -> glyph.y += 30f }
}
- }
interp.basePaint.set(START_PAINT)
interp.onBasePaintModified()
@@ -267,7 +271,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
// The glyph position was modified by callback, so the bitmap should not be the same.
@@ -279,11 +284,10 @@ class TextInterpolatorTest : SysuiTestCase() {
fun testGlyphCallback_TextSize() {
val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
- val interp = TextInterpolator(layout, typefaceCache).apply {
- glyphFilter = { glyph, progress ->
- glyph.textSize += 10f
+ val interp =
+ TextInterpolator(layout, typefaceCache).apply {
+ glyphFilter = { glyph, progress -> glyph.textSize += 10f }
}
- }
interp.basePaint.set(START_PAINT)
interp.onBasePaintModified()
@@ -292,7 +296,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
// The glyph position was modified by callback, so the bitmap should not be the same.
@@ -304,11 +309,10 @@ class TextInterpolatorTest : SysuiTestCase() {
fun testGlyphCallback_Color() {
val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
- val interp = TextInterpolator(layout, typefaceCache).apply {
- glyphFilter = { glyph, progress ->
- glyph.color = Color.RED
+ val interp =
+ TextInterpolator(layout, typefaceCache).apply {
+ glyphFilter = { glyph, progress -> glyph.color = Color.RED }
}
- }
interp.basePaint.set(START_PAINT)
interp.onBasePaintModified()
@@ -317,7 +321,8 @@ class TextInterpolatorTest : SysuiTestCase() {
// Just after created TextInterpolator, it should have 0 progress.
val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
- val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+ val expected =
+ makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
.toBitmap(BMP_WIDTH, BMP_HEIGHT)
// The glyph position was modified by callback, so the bitmap should not be the same.
@@ -327,7 +332,7 @@ class TextInterpolatorTest : SysuiTestCase() {
}
private fun Layout.toBitmap(width: Int, height: Int) =
- Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }!!
+ Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }!!
private fun TextInterpolator.toBitmap(width: Int, height: Int) =
- Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }
+ Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt
index 6e9b24f1433e..4ca84c58f6d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/backup/CommunalBackupHelperTest.kt
@@ -37,7 +37,6 @@ import com.google.common.truth.Truth.assertThat
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
-import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -63,22 +62,18 @@ class CommunalBackupHelperTest : SysuiTestCase() {
Room.inMemoryDatabaseBuilder(context, CommunalDatabase::class.java)
.allowMainThreadQueries()
.build()
+ onTeardown { database.close() }
CommunalDatabase.setInstance(database)
dao = database.communalWidgetDao()
backupUtils = CommunalBackupUtils(context)
backupDataFile = File(context.cacheDir, "backup_data_file")
+ onTeardown { backupDataFile.delete() }
underTest = CommunalBackupHelper(UserHandle.SYSTEM, backupUtils)
}
- @After
- fun teardown() {
- backupDataFile.delete()
- database.close()
- }
-
@Test
@EnableFlags(Flags.FLAG_COMMUNAL_HUB)
fun backupAndRestoreCommunalHub() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
index f8d848139039..85ab746211d6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
@@ -16,6 +16,19 @@
package com.android.systemui.keyboard.shortcut.ui.viewmodel
+import android.content.Context
+import android.content.Context.INPUT_SERVICE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTHER
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
+import android.hardware.input.fakeInputManager
+import android.os.SystemClock
+import android.view.KeyEvent.ACTION_DOWN
+import android.view.KeyEvent.KEYCODE_A
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_META_ON
+import androidx.compose.ui.input.key.KeyEvent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -24,23 +37,44 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shortcutCustomizationViewModelFactory
+import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.userTracker
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
class ShortcutCustomizationViewModelTest : SysuiTestCase() {
- private val kosmos = Kosmos()
+ private val mockUserContext: Context = mock()
+ private val kosmos =
+ Kosmos().also {
+ it.testCase = this
+ it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
+ }
private val testScope = kosmos.testScope
+ private val inputManager = kosmos.fakeInputManager.inputManager
+ private val helper = kosmos.shortcutHelperTestHelper
private val viewModel = kosmos.shortcutCustomizationViewModelFactory.create()
+ @Before
+ fun setup() {
+ helper.showFromActivity()
+ whenever(mockUserContext.getSystemService(INPUT_SERVICE)).thenReturn(inputManager)
+ }
+
@Test
fun uiState_inactiveByDefault() {
testScope.runTest {
@@ -78,11 +112,196 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
viewModel.onAddShortcutDialogShown()
- viewModel.onAddShortcutDialogDismissed()
+ viewModel.onDialogDismissed()
assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
}
}
+ @Test
+ fun uiState_pressedKeys_emptyByDefault() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+ .isEmpty()
+ }
+ }
+
+ @Test
+ fun uiState_becomeInactiveAfterSuccessfullySettingShortcut() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ whenever(inputManager.addCustomInputGesture(any()))
+ .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_SUCCESS)
+
+ openAddShortcutDialogAndSetShortcut()
+
+ assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
+ }
+ }
+
+ @Test
+ fun uiState_errorMessage_isEmptyByDefault() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(allAppsShortcutCustomizationRequest)
+ viewModel.onAddShortcutDialogShown()
+
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+ .isEmpty()
+ }
+ }
+
+ @Test
+ fun uiState_errorMessage_isKeyCombinationInUse_whenKeyCombinationAlreadyExists() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ whenever(inputManager.addCustomInputGesture(any()))
+ .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_ERROR_ALREADY_EXISTS)
+
+ openAddShortcutDialogAndSetShortcut()
+
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+ .isEqualTo(
+ context.getString(
+ R.string.shortcut_customizer_key_combination_in_use_error_message
+ )
+ )
+ }
+ }
+
+ @Test
+ fun uiState_errorMessage_isKeyCombinationInUse_whenKeyCombinationIsReserved() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ whenever(inputManager.addCustomInputGesture(any()))
+ .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE)
+
+ openAddShortcutDialogAndSetShortcut()
+
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+ .isEqualTo(
+ context.getString(
+ R.string.shortcut_customizer_key_combination_in_use_error_message
+ )
+ )
+ }
+ }
+
+ @Test
+ fun uiState_errorMessage_isGenericError_whenErrorIsUnknown() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ whenever(inputManager.addCustomInputGesture(any()))
+ .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTHER)
+
+ openAddShortcutDialogAndSetShortcut()
+
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
+ .isEqualTo(context.getString(R.string.shortcut_customizer_generic_error_message))
+ }
+ }
+
+ @Test
+ fun onKeyPressed_handlesKeyEvents_whereActionKeyIsAlsoPressed() {
+ testScope.runTest {
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ val isHandled = viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+
+ assertThat(isHandled).isTrue()
+ }
+ }
+
+ @Test
+ fun onKeyPressed_doesNotHandleKeyEvents_whenActionKeyIsNotAlsoPressed() {
+ testScope.runTest {
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ val isHandled = viewModel.onKeyPressed(keyDownEventWithoutActionKeyPressed)
+
+ assertThat(isHandled).isFalse()
+ }
+ }
+
+ @Test
+ fun onKeyPressed_convertsKeyEventsAndUpdatesUiStatesPressedKey() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+ viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+
+ // Note that Action Key is excluded as it's already displayed on the UI
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+ .containsExactly(ShortcutKey.Text("Ctrl"), ShortcutKey.Text("A"))
+ }
+ }
+
+ @Test
+ fun uiState_pressedKeys_resetsToEmptyListAfterDialogIsDismissedAndReopened() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+ viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+
+ // Note that Action Key is excluded as it's already displayed on the UI
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+ .containsExactly(ShortcutKey.Text("Ctrl"), ShortcutKey.Text("A"))
+
+ // Close the dialog and show it again
+ viewModel.onDialogDismissed()
+ viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
+ assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).pressedKeys)
+ .isEmpty()
+ }
+ }
+
+ private suspend fun openAddShortcutDialogAndSetShortcut() {
+ viewModel.onShortcutCustomizationRequested(allAppsShortcutCustomizationRequest)
+ viewModel.onAddShortcutDialogShown()
+
+ viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+ viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+
+ viewModel.onSetShortcut()
+ }
+
+ private val keyDownEventWithoutActionKeyPressed =
+ KeyEvent(
+ android.view.KeyEvent(
+ /* downTime = */ SystemClock.uptimeMillis(),
+ /* eventTime = */ SystemClock.uptimeMillis(),
+ /* action = */ ACTION_DOWN,
+ /* code = */ KEYCODE_A,
+ /* repeat = */ 0,
+ /* metaState = */ META_CTRL_ON,
+ )
+ )
+
+ private val keyDownEventWithActionKeyPressed =
+ KeyEvent(
+ android.view.KeyEvent(
+ /* downTime = */ SystemClock.uptimeMillis(),
+ /* eventTime = */ SystemClock.uptimeMillis(),
+ /* action = */ ACTION_DOWN,
+ /* code = */ KEYCODE_A,
+ /* repeat = */ 0,
+ /* metaState = */ META_CTRL_ON or META_META_ON,
+ )
+ )
+
+ private val keyUpEventWithActionKeyPressed =
+ KeyEvent(
+ android.view.KeyEvent(
+ /* downTime = */ SystemClock.uptimeMillis(),
+ /* eventTime = */ SystemClock.uptimeMillis(),
+ /* action = */ ACTION_DOWN,
+ /* code = */ KEYCODE_A,
+ /* repeat = */ 0,
+ /* metaState = */ 0,
+ )
+ )
+
private val standardAddShortcutRequest =
ShortcutCustomizationRequestInfo.Add(
label = "Standard shortcut",
@@ -90,11 +309,16 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
subCategoryLabel = "Standard subcategory",
)
+ private val allAppsShortcutCustomizationRequest =
+ ShortcutCustomizationRequestInfo.Add(
+ label = "Open apps list",
+ categoryType = ShortcutCategoryType.System,
+ subCategoryLabel = "System controls",
+ )
+
private val expectedStandardAddShortcutUiState =
ShortcutCustomizationUiState.AddShortcutDialog(
shortcutLabel = "Standard shortcut",
- shouldShowErrorMessage = false,
- isValidKeyCombination = false,
defaultCustomShortcutModifierKey =
ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
isDialogShowing = false,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
index 7383faf2fd78..feae901114e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
@@ -278,7 +278,11 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
testScope.runTest {
fakeSystemSource.setGroups(
groupWithShortcutLabels("first Foo shortcut1", "first bar shortcut1"),
- groupWithShortcutLabels("second foO shortcut2", "second bar shortcut2"),
+ groupWithShortcutLabels(
+ "second foO shortcut2",
+ "second bar shortcut2",
+ groupLabel = SECOND_SIMPLE_GROUP_LABEL,
+ ),
)
fakeMultiTaskingSource.setGroups(
groupWithShortcutLabels("third FoO shortcut1", "third bar shortcut1")
@@ -298,7 +302,10 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
ShortcutCategory(
System,
subCategoryWithShortcutLabels("first Foo shortcut1"),
- subCategoryWithShortcutLabels("second foO shortcut2"),
+ subCategoryWithShortcutLabels(
+ "second foO shortcut2",
+ subCategoryLabel = SECOND_SIMPLE_GROUP_LABEL,
+ ),
),
),
ShortcutCategoryUi(
@@ -380,16 +387,23 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
assertThat(activeUiState.defaultSelectedCategory).isInstanceOf(CurrentApp::class.java)
}
- private fun groupWithShortcutLabels(vararg shortcutLabels: String) =
- KeyboardShortcutGroup(SIMPLE_GROUP_LABEL, shortcutLabels.map { simpleShortcutInfo(it) })
- .apply { packageName = "test.package.name" }
+ private fun groupWithShortcutLabels(
+ vararg shortcutLabels: String,
+ groupLabel: String = FIRST_SIMPLE_GROUP_LABEL,
+ ) =
+ KeyboardShortcutGroup(groupLabel, shortcutLabels.map { simpleShortcutInfo(it) }).apply {
+ packageName = "test.package.name"
+ }
private fun simpleShortcutInfo(label: String) =
KeyboardShortcutInfo(label, KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON)
- private fun subCategoryWithShortcutLabels(vararg shortcutLabels: String) =
+ private fun subCategoryWithShortcutLabels(
+ vararg shortcutLabels: String,
+ subCategoryLabel: String = FIRST_SIMPLE_GROUP_LABEL,
+ ) =
ShortcutSubCategory(
- label = SIMPLE_GROUP_LABEL,
+ label = subCategoryLabel,
shortcuts = shortcutLabels.map { simpleShortcut(it) },
)
@@ -402,6 +416,7 @@ class ShortcutHelperViewModelTest : SysuiTestCase() {
}
companion object {
- private const val SIMPLE_GROUP_LABEL = "simple group"
+ private const val FIRST_SIMPLE_GROUP_LABEL = "simple group 1"
+ private const val SECOND_SIMPLE_GROUP_LABEL = "simple group 2"
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index d7084898a4a4..7849ea5ab7ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -38,6 +38,7 @@ import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
import android.content.pm.ShortcutManager
import android.content.pm.UserInfo
+import android.content.res.Resources
import android.graphics.drawable.Icon
import android.os.UserHandle
import android.os.UserManager
@@ -84,6 +85,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.whenever
@@ -106,6 +108,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Mock private lateinit var shortcutManager: ShortcutManager
@Mock private lateinit var activityManager: ActivityManager
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
+ private lateinit var spiedResources: Resources
private val userTracker = FakeUserTracker()
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
@@ -130,7 +133,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(
devicePolicyManager.getKeyguardDisabledFeatures(
/* admin= */ eq(null),
- /* userHandle= */ anyInt()
+ /* userHandle= */ anyInt(),
)
)
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE)
@@ -139,6 +142,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(activityManager.getRunningTasks(anyInt())).thenReturn(emptyList())
whenever(userManager.isManagedProfile(workUserInfo.id)).thenReturn(true)
whenever(context.resources).thenReturn(getContext().resources)
+
+ spiedResources = spy(context.resources)
+ `when`(context.resources).thenReturn(spiedResources)
}
private fun createNoteTaskController(
@@ -161,7 +167,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
noteTaskBubblesController =
FakeNoteTaskBubbleController(context, testDispatcher, Optional.ofNullable(bubbles)),
applicationScope = testScope,
- bgCoroutineContext = testScope.backgroundScope.coroutineContext
+ bgCoroutineContext = testScope.backgroundScope.coroutineContext,
)
// region onBubbleExpandChanged
@@ -225,11 +231,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test
fun onBubbleExpandChanged_notKeyAppBubble_shouldDoNothing() {
- createNoteTaskController()
- .onBubbleExpandChanged(
- isExpanding = true,
- key = "any other key",
- )
+ createNoteTaskController().onBubbleExpandChanged(isExpanding = true, key = "any other key")
verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger)
}
@@ -251,11 +253,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
fun showNoteTaskAsUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
val user10 = UserHandle.of(/* userId= */ 10)
val expectedInfo =
- NOTE_TASK_INFO.copy(
- entryPoint = TAIL_BUTTON,
- isKeyguardLocked = true,
- user = user10,
- )
+ NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
@@ -360,7 +358,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
secureSettings.putIntForUser(
/* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
/* value= */ 10,
- /* userHandle= */ userTracker.userId
+ /* userHandle= */ userTracker.userId,
)
val user10 = UserHandle.of(/* userId= */ 10)
@@ -373,10 +371,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
- createNoteTaskController()
- .showNoteTask(
- entryPoint = expectedInfo.entryPoint!!,
- )
+ createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
val intentCaptor = argumentCaptor<Intent>()
val userCaptor = argumentCaptor<UserHandle>()
@@ -456,6 +451,85 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
verifyNoMoreInteractions(bubbles)
}
+ @Test
+ fun showNoteTask_stylusModePreferred_keyboardShortcut_shouldStartInDefaultUIMode() {
+ `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1)
+ val expectedInfo =
+ NOTE_TASK_INFO.copy(entryPoint = KEYBOARD_SHORTCUT, isKeyguardLocked = true)
+ whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+ whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+ createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+ val intentCaptor = argumentCaptor<Intent>()
+ val userCaptor = argumentCaptor<UserHandle>()
+ verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+ assertThat(intentCaptor.value).run {
+ hasAction(ACTION_CREATE_NOTE)
+ hasPackage(NOTE_TASK_PACKAGE_NAME)
+ extras().bool(EXTRA_USE_STYLUS_MODE).isFalse()
+ }
+ }
+
+ @Test
+ fun showNoteTask_stylusModePreferred_quickAffordance_shouldStartInStylusUIMode() {
+ `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1)
+ val expectedInfo =
+ NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true)
+ whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+ whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+ createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+ val intentCaptor = argumentCaptor<Intent>()
+ val userCaptor = argumentCaptor<UserHandle>()
+ verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+ assertThat(intentCaptor.value).run {
+ hasAction(ACTION_CREATE_NOTE)
+ hasPackage(NOTE_TASK_PACKAGE_NAME)
+ extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
+ }
+ }
+
+ @Test
+ fun showNoteTask_noUIRecommendation_quickAffordance_shouldStartInDefaultUIMode() {
+ `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0)
+ val expectedInfo =
+ NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true)
+ whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+ whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+ createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+ val intentCaptor = argumentCaptor<Intent>()
+ val userCaptor = argumentCaptor<UserHandle>()
+ verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+ assertThat(intentCaptor.value).run {
+ hasAction(ACTION_CREATE_NOTE)
+ hasPackage(NOTE_TASK_PACKAGE_NAME)
+ extras().bool(EXTRA_USE_STYLUS_MODE).isFalse()
+ }
+ }
+
+ @Test
+ fun showNoteTask_noUIRecommendation_tailButton_shouldStartInStylusUIMode() {
+ `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0)
+ val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
+ whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+ whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
+
+ createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
+
+ val intentCaptor = argumentCaptor<Intent>()
+ val userCaptor = argumentCaptor<UserHandle>()
+ verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+ assertThat(intentCaptor.value).run {
+ hasAction(ACTION_CREATE_NOTE)
+ hasPackage(NOTE_TASK_PACKAGE_NAME)
+ extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
+ }
+ }
+
// endregion
// region setNoteTaskShortcutEnabled
@@ -543,7 +617,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(
devicePolicyManager.getKeyguardDisabledFeatures(
/* admin= */ eq(null),
- /* userHandle= */ anyInt()
+ /* userHandle= */ anyInt(),
)
)
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
@@ -559,7 +633,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(
devicePolicyManager.getKeyguardDisabledFeatures(
/* admin= */ eq(null),
- /* userHandle= */ anyInt()
+ /* userHandle= */ anyInt(),
)
)
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
@@ -575,7 +649,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(
devicePolicyManager.getKeyguardDisabledFeatures(
/* admin= */ eq(null),
- /* userHandle= */ anyInt()
+ /* userHandle= */ anyInt(),
)
)
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
@@ -591,7 +665,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(
devicePolicyManager.getKeyguardDisabledFeatures(
/* admin= */ eq(null),
- /* userHandle= */ anyInt()
+ /* userHandle= */ anyInt(),
)
)
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
@@ -604,8 +678,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
// endregion
// region showNoteTask, COPE devices
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { // ktlint-disable max-line-length
+ fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() {
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(listOf(mainUserInfo), mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -629,7 +704,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
secureSettings.putIntForUser(
/* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
/* value= */ mainUserInfo.id,
- /* userHandle= */ userTracker.userId
+ /* userHandle= */ userTracker.userId,
)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -836,12 +911,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
}
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length
+ fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() {
secureSettings.putIntForUser(
/* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
/* value= */ workUserInfo.id,
- /* userHandle= */ userTracker.userId
+ /* userHandle= */ userTracker.userId,
)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -851,12 +927,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
}
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length
+ fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() {
secureSettings.putIntForUser(
/* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
/* value= */ mainUserInfo.id,
- /* userHandle= */ userTracker.userId
+ /* userHandle= */ userTracker.userId,
)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -934,8 +1011,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
}
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
+ fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() {
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE)
@@ -947,8 +1025,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
}
+ @Suppress("ktlint:standard:max-line-length")
@Test
- fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
+ fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() {
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
createNoteTaskController().startNotesRoleSetting(context, entryPoint = null)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
index 2812bd334b0f..b3a5872a7dec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
@@ -49,7 +49,7 @@ class SimpleDigitalClockTextViewTest : SysuiTestCase() {
context,
context.resources,
ClockSettings(),
- TypefaceCache(messageBuffer) {
+ TypefaceCache(messageBuffer, 20) {
// TODO(b/364680873): Move constant to config_clockFontFamily when shipping
return@TypefaceCache Typeface.create(
"google-sans-flex-clock",
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index e313a05773ab..d8a23d6bd32e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -45,6 +45,7 @@ import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -551,12 +552,26 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
}
@Test
+ @DisableFlags(com.android.systemui.Flags.FLAG_NOTIFICATION_REENTRANT_DISMISS)
+ public void testCanDismiss_immediately() throws Exception {
+ ExpandableNotificationRow row =
+ mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
+ when(mNotificationTestHelper.getDismissibilityProvider().isDismissable(row.getEntry()))
+ .thenReturn(true);
+ row.performDismiss(false);
+ verify(mNotificationTestHelper.getOnUserInteractionCallback())
+ .registerFutureDismissal(any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(com.android.systemui.Flags.FLAG_NOTIFICATION_REENTRANT_DISMISS)
public void testCanDismiss() throws Exception {
ExpandableNotificationRow row =
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
when(mNotificationTestHelper.getDismissibilityProvider().isDismissable(row.getEntry()))
.thenReturn(true);
row.performDismiss(false);
+ TestableLooper.get(this).processAllMessages();
verify(mNotificationTestHelper.getOnUserInteractionCallback())
.registerFutureDismissal(any(), anyInt());
}
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 b142fc2deea9..c9f8463d510c 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
@@ -607,7 +607,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mShadeController,
mWindowRootViewVisibilityInteractor,
mStatusBarKeyguardViewManager,
- () -> mStatusBarLongPressGestureDetector,
mViewMediatorCallback,
mInitController,
new Handler(TestableLooper.get(this).getLooper()),
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 856333ea724e..aad8b4ba1191 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -2707,6 +2707,44 @@ public class BubblesTest extends SysuiTestCase {
eq(BubbleLogger.Event.BUBBLE_BAR_EXPANDED));
}
+ @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
+ @Test
+ public void testEventLogging_bubbleBar_openOverflow() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(true);
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ mEntryListener.onEntryAdded(mRow);
+
+ clearInvocations(mBubbleLogger);
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(BubbleOverflow.KEY, 0);
+ verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_OVERFLOW_SELECTED);
+ verifyNoMoreInteractions(mBubbleLogger);
+ }
+
+ @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
+ @Test
+ public void testEventLogging_bubbleBar_fromOverflowToBar() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(true);
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ mEntryListener.onEntryAdded(mRow);
+
+ // Dismiss the bubble so it's in the overflow
+ mBubbleController.removeBubble(
+ mRow.getKey(), Bubbles.DISMISS_USER_GESTURE);
+ Bubble overflowBubble = mBubbleData.getOverflowBubbleWithKey(mRow.getKey());
+ assertThat(overflowBubble).isNotNull();
+
+ // Promote overflow bubble and check that it is logged
+ mBubbleController.promoteBubbleFromOverflow(overflowBubble);
+ verify(mBubbleLogger).log(eqBubbleWithKey(overflowBubble.getKey()),
+ eq(BubbleLogger.Event.BUBBLE_BAR_OVERFLOW_REMOVE_BACK_TO_BAR));
+ }
+
/** Creates a bubble using the userId and package. */
private Bubble createBubble(int userId, String pkg) {
final UserHandle userHandle = new UserHandle(userId);
diff --git a/packages/SystemUI/tests/utils/src/android/content/ClipboardManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/content/ClipboardManagerKosmos.kt
new file mode 100644
index 000000000000..379c00842b62
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/content/ClipboardManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+val Kosmos.clipboardManager by Kosmos.Fixture { mock<ClipboardManager>() }
diff --git a/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryKosmos.kt
index cbdb83c656f4..3ce119576096 100644
--- a/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/development/data/repository/DevelopmentSettingRepositoryKosmos.kt
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package android.media.tv.extension.scan;
+package com.android.systemui.development.data.repository
-import android.os.Bundle;
+import android.os.userManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.util.settings.fakeGlobalSettings
-/**
- * @hide
- */
-oneway interface ILcnV2ChannelListListener {
- void onDetectLcnV2ChannelList(in Bundle detectLcnV2ChannelList);
-}
+val Kosmos.developmentSettingRepository by
+ Kosmos.Fixture { DevelopmentSettingRepository(fakeGlobalSettings, userManager, testDispatcher) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt
new file mode 100644
index 000000000000..aa4dd18a6cba
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/development/domain/interactor/BuildNumberInteractorKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.domain.interactor
+
+import android.content.clipboardManager
+import android.content.res.mainResources
+import com.android.systemui.development.data.repository.developmentSettingRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.user.data.repository.userRepository
+
+val Kosmos.buildNumberInteractor by
+ Kosmos.Fixture {
+ BuildNumberInteractor(
+ developmentSettingRepository,
+ mainResources,
+ userRepository,
+ { clipboardManager },
+ testDispatcher,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModelKosmos.kt
new file mode 100644
index 000000000000..c827311a6ac3
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/development/ui/viewmodel/BuildNumberViewModelKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.development.ui.viewmodel
+
+import com.android.systemui.development.domain.interactor.buildNumberInteractor
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.buildNumberViewModelFactory by
+ Kosmos.Fixture {
+ object : BuildNumberViewModel.Factory {
+ override fun create(): BuildNumberViewModel {
+ return BuildNumberViewModel(buildNumberInteractor)
+ }
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 903bc8ebf42d..721c0b8339db 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -24,6 +24,7 @@ import android.view.windowManager
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository
import com.android.systemui.keyboard.shortcut.data.repository.DefaultShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.InputGestureMaps
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesUtils
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper
@@ -101,6 +102,11 @@ val Kosmos.defaultShortcutCategoriesRepository by
)
}
+val Kosmos.inputGestureMaps by
+ Kosmos.Fixture {
+ InputGestureMaps(applicationContext)
+ }
+
val Kosmos.customShortcutCategoriesRepository by
Kosmos.Fixture {
CustomShortcutCategoriesRepository(
@@ -110,6 +116,7 @@ val Kosmos.customShortcutCategoriesRepository by
testDispatcher,
shortcutCategoriesUtils,
applicationContext,
+ inputGestureMaps
)
}
@@ -136,7 +143,11 @@ val Kosmos.shortcutHelperStateInteractor by
}
val Kosmos.shortcutHelperCategoriesInteractor by
- Kosmos.Fixture { ShortcutHelperCategoriesInteractor(defaultShortcutCategoriesRepository) }
+ Kosmos.Fixture {
+ ShortcutHelperCategoriesInteractor(defaultShortcutCategoriesRepository) {
+ customShortcutCategoriesRepository
+ }
+ }
val Kosmos.shortcutHelperViewModel by
Kosmos.Fixture {
@@ -162,13 +173,17 @@ val Kosmos.shortcutCustomizationDialogStarterFactory by
}
}
-val Kosmos.shortcutCustomizationInteractor by Kosmos.Fixture { ShortcutCustomizationInteractor() }
+val Kosmos.shortcutCustomizationInteractor by
+ Kosmos.Fixture { ShortcutCustomizationInteractor(customShortcutCategoriesRepository) }
val Kosmos.shortcutCustomizationViewModelFactory by
Kosmos.Fixture {
object : ShortcutCustomizationViewModel.Factory {
override fun create(): ShortcutCustomizationViewModel {
- return ShortcutCustomizationViewModel(shortcutCustomizationInteractor)
+ return ShortcutCustomizationViewModel(
+ applicationContext,
+ shortcutCustomizationInteractor,
+ )
}
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
index 0e5edb75846d..2e80293eafff 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import com.android.systemui.development.ui.viewmodel.buildNumberViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.domain.interactor.paginatedGridInteractor
@@ -26,5 +27,6 @@ val Kosmos.paginatedGridViewModel by
qsColumnsViewModelFactory,
paginatedGridInteractor,
inFirstPageViewModel,
+ buildNumberViewModelFactory,
)
}
diff --git a/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepositoryKosmos.kt
index 7dcd46177c43..1e8dfa1c9767 100644
--- a/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/data/repository/VolumeDialogSliderTouchEventsRepositoryKosmos.kt
@@ -14,14 +14,9 @@
* limitations under the License.
*/
-package android.media.tv.extension.scan;
+package com.android.systemui.volume.dialog.sliders.data.repository
-import android.os.Bundle;
+import com.android.systemui.kosmos.Kosmos
-
-/**
- * @hide
- */
-oneway interface IOperatorDetectionListener {
- void onDetectOperatorDetectionList(in Bundle[] detectOperatorDetectionList);
-}
+val Kosmos.volumeDialogSliderTouchEventsRepository by
+ Kosmos.Fixture { VolumeDialogSliderTouchEventsRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorKosmo.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorKosmo.kt
new file mode 100644
index 000000000000..39ae5aa3ce1f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorKosmo.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.dialog.sliders.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.volume.dialog.domain.interactor.volumeDialogCallbacksInteractor
+import com.android.systemui.volume.dialog.domain.interactor.volumeDialogVisibilityInteractor
+import com.android.systemui.volume.dialog.sliders.data.repository.volumeDialogSliderTouchEventsRepository
+
+val Kosmos.volumeDialogSliderInputEventsInteractor: VolumeDialogSliderInputEventsInteractor by
+ Kosmos.Fixture {
+ VolumeDialogSliderInputEventsInteractor(
+ applicationCoroutineScope,
+ volumeDialogCallbacksInteractor,
+ volumeDialogVisibilityInteractor,
+ volumeDialogSliderTouchEventsRepository,
+ )
+ }
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index 869d854f7b23..9b71f8050c80 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -30,6 +30,8 @@ import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.ravenwood.common.RavenwoodCommonUtils;
+
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.Runner;
@@ -229,7 +231,9 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
s.evaluate();
onAfter(description, scope, order, null);
} catch (Throwable t) {
- if (onAfter(description, scope, order, t)) {
+ var shouldReportFailure = RavenwoodCommonUtils.runIgnoringException(
+ () -> onAfter(description, scope, order, t));
+ if (shouldReportFailure == null || shouldReportFailure) {
throw t;
}
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 678a97be60a2..979076eaabfd 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -22,6 +22,8 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_R
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.parseNullableInt;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.withDefault;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
@@ -39,6 +41,7 @@ import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
@@ -64,6 +67,7 @@ import com.android.ravenwood.common.SneakyThrow;
import com.android.server.LocalServices;
import com.android.server.compat.PlatformCompat;
+import org.junit.internal.management.ManagementFactory;
import org.junit.runner.Description;
import java.io.File;
@@ -154,6 +158,13 @@ public class RavenwoodRuntimeEnvironmentController {
private static RavenwoodAwareTestRunner sRunner;
private static RavenwoodSystemProperties sProps;
+ private static final int DEFAULT_TARGET_SDK_LEVEL = VERSION_CODES.CUR_DEVELOPMENT;
+ private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname";
+
+ private static int sTargetSdkLevel;
+ private static String sTestPackageName;
+ private static String sTargetPackageName;
+
/**
* Initialize the global environment.
*/
@@ -194,6 +205,8 @@ public class RavenwoodRuntimeEnvironmentController {
// Some process-wide initialization. (maybe redirect stdout/stderr)
RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME);
+ dumpCommandLineArgs();
+
// We haven't initialized liblog yet, so directly write to System.out here.
RavenwoodCommonUtils.log(TAG, "globalInitInner()");
@@ -235,9 +248,22 @@ public class RavenwoodRuntimeEnvironmentController {
System.setProperty("android.junit.runner",
"androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner");
+ loadRavenwoodProperties();
+
assertMockitoVersion();
}
+ private static void loadRavenwoodProperties() {
+ var props = RavenwoodSystemProperties.readProperties("ravenwood.properties");
+
+ sTargetSdkLevel = withDefault(
+ parseNullableInt(props.get("targetSdkVersionInt")), DEFAULT_TARGET_SDK_LEVEL);
+ sTargetPackageName = withDefault(props.get("packageName"), DEFAULT_PACKAGE_NAME);
+ sTestPackageName = withDefault(props.get("instPackageName"), sTargetPackageName);
+
+ // TODO(b/377765941) Read them from the manifest too?
+ }
+
/**
* Initialize the environment.
*/
@@ -256,7 +282,9 @@ public class RavenwoodRuntimeEnvironmentController {
initInner(runner.mState.getConfig());
} catch (Exception th) {
Log.e(TAG, "init() failed", th);
- reset();
+
+ RavenwoodCommonUtils.runIgnoringException(()-> reset());
+
SneakyThrow.sneakyThrow(th);
}
}
@@ -267,6 +295,14 @@ public class RavenwoodRuntimeEnvironmentController {
Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
}
+ config.mTargetPackageName = sTargetPackageName;
+ config.mTestPackageName = sTestPackageName;
+ config.mTargetSdkLevel = sTargetSdkLevel;
+
+ Log.i(TAG, "TargetPackageName=" + sTargetPackageName);
+ Log.i(TAG, "TestPackageName=" + sTestPackageName);
+ Log.i(TAG, "TargetSdkLevel=" + sTargetSdkLevel);
+
RavenwoodRuntimeState.sUid = config.mUid;
RavenwoodRuntimeState.sPid = config.mPid;
RavenwoodRuntimeState.sTargetSdkLevel = config.mTargetSdkLevel;
@@ -349,8 +385,11 @@ public class RavenwoodRuntimeEnvironmentController {
* Partially re-initialize after each test method invocation
*/
public static void reinit() {
- var config = sRunner.mState.getConfig();
- Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+ // sRunner could be null, if there was a failure in the initialization.
+ if (sRunner != null) {
+ var config = sRunner.mState.getConfig();
+ Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+ }
}
private static void initializeCompatIds(RavenwoodConfig config) {
@@ -380,6 +419,9 @@ public class RavenwoodRuntimeEnvironmentController {
/**
* De-initialize.
+ *
+ * Note, we call this method when init() fails too, so this method should deal with
+ * any partially-initialized states.
*/
public static void reset() {
if (RAVENWOOD_VERBOSE_LOGGING) {
@@ -411,7 +453,9 @@ public class RavenwoodRuntimeEnvironmentController {
config.mState.mSystemServerContext.cleanUp();
}
- Looper.getMainLooper().quit();
+ if (Looper.getMainLooper() != null) {
+ Looper.getMainLooper().quit();
+ }
Looper.clearMainLooperForTest();
ActivityManager.reset$ravenwood();
@@ -547,4 +591,18 @@ public class RavenwoodRuntimeEnvironmentController {
+ " access to system property '" + key + "' denied via RavenwoodConfig");
}
}
+
+ private static void dumpCommandLineArgs() {
+ Log.i(TAG, "JVM arguments:");
+
+ // Note, we use the wrapper in JUnit4, not the actual class (
+ // java.lang.management.ManagementFactory), because we can't see the later at the build
+ // because this source file is compiled for the device target, where ManagementFactory
+ // doesn't exist.
+ var args = ManagementFactory.getRuntimeMXBean().getInputArguments();
+
+ for (var arg : args) {
+ Log.i(TAG, " " + arg);
+ }
+ }
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
index 3ed8b0a748e1..7ca9239d2062 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
@@ -22,7 +22,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Instrumentation;
import android.content.Context;
-import android.os.Build;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -30,16 +29,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/**
- * Represents how to configure the ravenwood environment for a test class.
- *
- * If a ravenwood test class has a public static field with the {@link Config} annotation,
- * Ravenwood will extract the config from it and initializes the environment. The type of the
- * field must be of {@link RavenwoodConfig}.
+ * @deprecated This class will be removed. Reach out to g/ravenwood if you need any features in it.
*/
+@Deprecated
public final class RavenwoodConfig {
/**
* Use this to mark a field as the configuration.
@@ -66,7 +61,7 @@ public final class RavenwoodConfig {
String mTestPackageName;
String mTargetPackageName;
- int mTargetSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ int mTargetSdkLevel;
final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
@@ -91,12 +86,6 @@ public final class RavenwoodConfig {
return RavenwoodRule.isOnRavenwood();
}
- private void setDefaults() {
- if (mTargetPackageName == null) {
- mTargetPackageName = mTestPackageName;
- }
- }
-
public static class Builder {
private final RavenwoodConfig mConfig = new RavenwoodConfig();
@@ -120,28 +109,27 @@ public final class RavenwoodConfig {
}
/**
- * Configure the package name of the test, which corresponds to
- * {@link Instrumentation#getContext()}.
+ * @deprecated no longer used. Package name is set in the build file. (for now)
*/
+ @Deprecated
public Builder setPackageName(@NonNull String packageName) {
- mConfig.mTestPackageName = Objects.requireNonNull(packageName);
return this;
}
/**
- * Configure the package name of the target app, which corresponds to
- * {@link Instrumentation#getTargetContext()}. Defaults to {@link #setPackageName}.
+ * @deprecated no longer used. Package name is set in the build file. (for now)
*/
+ @Deprecated
public Builder setTargetPackageName(@NonNull String packageName) {
- mConfig.mTargetPackageName = Objects.requireNonNull(packageName);
return this;
}
+
/**
- * Configure the target SDK level of the test.
+ * @deprecated no longer used. Target SDK level is set in the build file. (for now)
*/
+ @Deprecated
public Builder setTargetSdkLevel(int sdkLevel) {
- mConfig.mTargetSdkLevel = sdkLevel;
return this;
}
@@ -154,34 +142,32 @@ public final class RavenwoodConfig {
}
/**
- * Configure the given system property as immutable for the duration of the test.
- * Read access to the key is allowed, and write access will fail. When {@code value} is
- * {@code null}, the value is left as undefined.
- *
- * All properties in the {@code debug.*} namespace are automatically mutable, with no
- * developer action required.
- *
- * Has no effect on non-Ravenwood environments.
+ * @deprecated Use {@link RavenwoodRule.Builder#setSystemPropertyImmutable(String, Object)}
*/
+ @Deprecated
public Builder setSystemPropertyImmutable(@NonNull String key,
@Nullable Object value) {
- mConfig.mSystemProperties.setValue(key, value);
- mConfig.mSystemProperties.setAccessReadOnly(key);
return this;
}
/**
- * Configure the given system property as mutable for the duration of the test.
- * Both read and write access to the key is allowed, and its value will be reset between
- * each test. When {@code value} is {@code null}, the value is left as undefined.
- *
- * All properties in the {@code debug.*} namespace are automatically mutable, with no
- * developer action required.
- *
- * Has no effect on non-Ravenwood environments.
+ * @deprecated Use {@link RavenwoodRule.Builder#setSystemPropertyMutable(String, Object)}
*/
+ @Deprecated
public Builder setSystemPropertyMutable(@NonNull String key,
@Nullable Object value) {
+ return this;
+ }
+
+ Builder setSystemPropertyImmutableReal(@NonNull String key,
+ @Nullable Object value) {
+ mConfig.mSystemProperties.setValue(key, value);
+ mConfig.mSystemProperties.setAccessReadOnly(key);
+ return this;
+ }
+
+ Builder setSystemPropertyMutableReal(@NonNull String key,
+ @Nullable Object value) {
mConfig.mSystemProperties.setValue(key, value);
mConfig.mSystemProperties.setAccessReadWrite(key);
return this;
@@ -205,7 +191,6 @@ public final class RavenwoodConfig {
}
public RavenwoodConfig build() {
- mConfig.setDefaults();
return mConfig;
}
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index bfa3802ce583..5681a9040f63 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -36,10 +36,8 @@ import java.util.Objects;
import java.util.regex.Pattern;
/**
- * @deprecated Use {@link RavenwoodConfig} to configure the ravenwood environment instead.
- * A {@link RavenwoodRule} is no longer needed for {@link DisabledOnRavenwood}. To get the
- * {@link Context} and {@link Instrumentation}, use
- * {@link androidx.test.platform.app.InstrumentationRegistry} instead.
+ * @deprecated This class is undergoing a major change. Reach out to g/ravenwood if you need
+ * any featues in it.
*/
@Deprecated
public final class RavenwoodRule implements TestRule {
@@ -128,11 +126,10 @@ public final class RavenwoodRule implements TestRule {
}
/**
- * Configure the identity of this process to be the given package name for the duration
- * of the test. Has no effect on non-Ravenwood environments.
+ * @deprecated no longer used.
*/
+ @Deprecated
public Builder setPackageName(@NonNull String packageName) {
- mBuilder.setPackageName(packageName);
return this;
}
@@ -155,7 +152,7 @@ public final class RavenwoodRule implements TestRule {
* Has no effect on non-Ravenwood environments.
*/
public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) {
- mBuilder.setSystemPropertyImmutable(key, value);
+ mBuilder.setSystemPropertyImmutableReal(key, value);
return this;
}
@@ -170,7 +167,7 @@ public final class RavenwoodRule implements TestRule {
* Has no effect on non-Ravenwood environments.
*/
public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) {
- mBuilder.setSystemPropertyMutable(key, value);
+ mBuilder.setSystemPropertyMutableReal(key, value);
return this;
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 3e4619f55c6d..9bd376a76f77 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -52,7 +52,7 @@ public class RavenwoodSystemProperties {
"vendor_dlkm",
};
- private static Map<String, String> readProperties(String propFile) {
+ static Map<String, String> readProperties(String propFile) {
// Use an ordered map just for cleaner dump log.
final Map<String, String> ret = new LinkedHashMap<>();
try {
@@ -60,7 +60,7 @@ public class RavenwoodSystemProperties {
.map(String::trim)
.filter(s -> !s.startsWith("#"))
.map(s -> s.split("\\s*=\\s*", 2))
- .filter(a -> a.length == 2)
+ .filter(a -> a.length == 2 && a[1].length() > 0)
.forEach(a -> ret.put(a[0], a[1]));
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
index 520f050f0655..2a04d4469ef4 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -30,6 +30,7 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
+import java.util.function.Supplier;
public class RavenwoodCommonUtils {
private static final String TAG = "RavenwoodCommonUtils";
@@ -277,11 +278,55 @@ public class RavenwoodCommonUtils {
(isStatic ? "static" : "")));
}
+ /**
+ * Run a supplier and swallow the exception, if any.
+ *
+ * It's a dangerous function. Only use it in an exception handler where we don't want to crash.
+ */
+ @Nullable
+ public static <T> T runIgnoringException(@NonNull Supplier<T> s) {
+ try {
+ return s.get();
+ } catch (Throwable th) {
+ log(TAG, "Warning: Exception detected! " + getStackTraceString(th));
+ }
+ return null;
+ }
+
+ /**
+ * Run a runnable and swallow the exception, if any.
+ *
+ * It's a dangerous function. Only use it in an exception handler where we don't want to crash.
+ */
+ public static void runIgnoringException(@NonNull Runnable r) {
+ runIgnoringException(() -> {
+ r.run();
+ return null;
+ });
+ }
+
@NonNull
- public static String getStackTraceString(@Nullable Throwable th) {
+ public static String getStackTraceString(@NonNull Throwable th) {
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter);
th.printStackTrace(writer);
return stringWriter.toString();
}
+
+ /** Same as {@link Integer#parseInt(String)} but accepts null and returns null. */
+ @Nullable
+ public static Integer parseNullableInt(@Nullable String value) {
+ if (value == null) {
+ return null;
+ }
+ return Integer.parseInt(value);
+ }
+
+ /**
+ * @return {@code value} if it's non-null. Otherwise, returns {@code def}.
+ */
+ @Nullable
+ public static <T> T withDefault(@Nullable T value, @Nullable T def) {
+ return value != null ? value : def;
+ }
}
diff --git a/ravenwood/tests/bivalentinst/Android.bp b/ravenwood/tests/bivalentinst/Android.bp
index 41e45e5a6d95..31e3bcc3634f 100644
--- a/ravenwood/tests/bivalentinst/Android.bp
+++ b/ravenwood/tests/bivalentinst/Android.bp
@@ -27,6 +27,9 @@ android_ravenwood_test {
"junit",
"truth",
],
+
+ package_name: "com.android.ravenwood.bivalentinsttest_self_inst",
+
resource_apk: "RavenwoodBivalentInstTest_self_inst_device",
auto_gen_config: true,
}
@@ -53,6 +56,10 @@ android_ravenwood_test {
"truth",
],
resource_apk: "RavenwoodBivalentInstTestTarget",
+
+ package_name: "com.android.ravenwood.bivalentinst_target_app",
+ inst_package_name: "com.android.ravenwood.bivalentinsttest_nonself_inst",
+
inst_resource_apk: "RavenwoodBivalentInstTest_nonself_inst_device",
auto_gen_config: true,
}
diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
index 92d43d714e14..db252d87c784 100644
--- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
+++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
@@ -19,8 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Context;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -39,11 +37,6 @@ public class RavenwoodInstrumentationTest_nonself {
private static final String TEST_PACKAGE_NAME =
"com.android.ravenwood.bivalentinsttest_nonself_inst";
- @Config
- public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
- .setPackageName(TEST_PACKAGE_NAME)
- .setTargetPackageName(TARGET_PACKAGE_NAME)
- .build();
private static Instrumentation sInstrumentation;
private static Context sTestContext;
diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
index 2f35923dead2..94b18619efcd 100644
--- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
+++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
@@ -19,8 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Context;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -40,13 +38,6 @@ public class RavenwoodInstrumentationTest_self {
private static final String TEST_PACKAGE_NAME =
"com.android.ravenwood.bivalentinsttest_self_inst";
- @Config
- public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
- .setPackageName(TEST_PACKAGE_NAME)
- .setTargetPackageName(TARGET_PACKAGE_NAME)
- .build();
-
-
private static Instrumentation sInstrumentation;
private static Context sTestContext;
private static Context sTargetContext;
diff --git a/ravenwood/tests/bivalenttest/Android.bp b/ravenwood/tests/bivalenttest/Android.bp
index 40e6672a3c63..ac545dfb06cc 100644
--- a/ravenwood/tests/bivalenttest/Android.bp
+++ b/ravenwood/tests/bivalenttest/Android.bp
@@ -84,6 +84,8 @@ java_defaults {
android_ravenwood_test {
name: "RavenwoodBivalentTest",
defaults: ["ravenwood-bivalent-defaults"],
+ target_sdk_version: "34",
+ package_name: "com.android.ravenwoodtest.bivalenttest",
auto_gen_config: true,
}
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
index a5a16c14600b..306c2b39c70d 100644
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
@@ -20,8 +20,6 @@ import static android.platform.test.ravenwood.RavenwoodConfig.isOnRavenwood;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
-import android.platform.test.ravenwood.RavenwoodConfig;
-
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -33,13 +31,7 @@ import org.junit.runner.RunWith;
*/
@RunWith(AndroidJUnit4.class)
public class RavenwoodConfigTest {
- private static final String PACKAGE_NAME = "com.test";
-
- @RavenwoodConfig.Config
- public static RavenwoodConfig sConfig =
- new RavenwoodConfig.Builder()
- .setPackageName(PACKAGE_NAME)
- .build();
+ private static final String PACKAGE_NAME = "com.android.ravenwoodtest.bivalenttest";
@Test
public void testConfig() {
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
index a95760db1a61..882c91c43ee9 100644
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
@@ -16,8 +16,6 @@
package com.android.ravenwoodtest.bivalenttest.compat
import android.app.compat.CompatChanges
-import android.os.Build
-import android.platform.test.ravenwood.RavenwoodConfig
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.internal.ravenwood.RavenwoodEnvironment.CompatIdsForTest
import org.junit.Assert
@@ -26,14 +24,6 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class RavenwoodCompatFrameworkTest {
- companion object {
- @JvmField // Expose as a raw field, not as a property.
- @RavenwoodConfig.Config
- val config = RavenwoodConfig.Builder()
- .setTargetSdkLevel(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
- .build()
- }
-
@Test
fun testEnabled() {
Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1))
@@ -53,4 +43,4 @@ class RavenwoodCompatFrameworkTest {
fun testEnabledAfterUForUApps() {
Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4))
}
-} \ No newline at end of file
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
index 02d10732245d..f94b98bc1fb8 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
@@ -24,6 +24,7 @@ import android.platform.test.ravenwood.RavenwoodRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
@@ -32,6 +33,10 @@ import org.junit.runner.RunWith;
/**
* Test for @Config field extraction and validation.
+ *
+ * TODO(b/377765941) Most of the tests here will be obsolete and deleted with b/377765941, but
+ * some of the tests may need to be re-implemented one way or another. (e.g. the package name
+ * test.) Until that happens, we'll keep all tests here but add an {@code @Ignore} instead.
*/
@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase {
@@ -59,6 +64,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,0,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class ConfigInBaseClassTest extends ConfigInBaseClass {
@Test
public void test() {
@@ -83,6 +89,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,0,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class ConfigOverridingTest extends ConfigInBaseClass {
static String PACKAGE_NAME_OVERRIDE = "com.ConfigOverridingTest";
@@ -376,6 +383,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,0,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class RuleInBaseClassSuccessTest extends RuleInBaseClass {
@Test
@@ -437,6 +445,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,1,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass {
@Test
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
index f7a2198a9bc4..0e3d053e90b1 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
@@ -25,6 +25,8 @@ import android.util.Log;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
+
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
@@ -103,6 +105,7 @@ public abstract class RavenwoodRunnerTestBase {
var thisClass = this.getClass();
var ret = Arrays.stream(thisClass.getNestMembers())
.filter((c) -> c.getAnnotation(Expected.class) != null)
+ .filter((c) -> c.getAnnotation(Ignore.class) == null)
.toArray(Class[]::new);
assertThat(ret.length).isGreaterThan(0);
diff --git a/ravenwood/tests/runtime-test/Android.bp b/ravenwood/tests/runtime-test/Android.bp
index 0c0df1f993aa..c3520031ea7d 100644
--- a/ravenwood/tests/runtime-test/Android.bp
+++ b/ravenwood/tests/runtime-test/Android.bp
@@ -9,7 +9,7 @@ package {
android_ravenwood_test {
name: "RavenwoodRuntimeTest",
-
+ target_sdk_version: "34",
libs: [
"ravenwood-helper-runtime",
],
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
index 8ec0932d89dd..61e254b225c3 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
@@ -43,7 +43,7 @@ fun checkClass(cn: ClassNode, classes: ClassNodes): Boolean {
}
var allOk = true
- log.i("Checking ${cn.name.toHumanReadableClassName()}")
+ log.v("Checking ${cn.name.toHumanReadableClassName()}")
// See if there's any class that extends a legacy base class.
// But ignore the base classes in android.test.
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index d4af7b765254..c210e726fc12 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4503,13 +4503,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
if (shortcutType == HARDWARE) {
skipVolumeShortcutDialogTimeoutRestriction(userId);
- if (com.android.server.accessibility.Flags.enableHardwareShortcutDisablesWarning()) {
- persistIntToSetting(
- userId,
- Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- AccessibilityShortcutController.DialogStatus.SHOWN
- );
- }
+ persistIntToSetting(
+ userId,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.SHOWN
+ );
} else if (shortcutType == SOFTWARE) {
// Update the A11y FAB size to large when the Magnification shortcut is
// enabled and the user hasn't changed the floating button size
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index c6a966f47952..d11ae0a6ad97 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -58,8 +58,6 @@ import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.VelocityTracker;
@@ -155,9 +153,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@VisibleForTesting State mCurrentState;
@VisibleForTesting State mPreviousState;
- private PointerCoords[] mTempPointerCoords;
- private PointerProperties[] mTempPointerProperties;
-
@VisibleForTesting static final int OVERSCROLL_NONE = 0;
@VisibleForTesting static final int OVERSCROLL_LEFT_EDGE = 1;
@VisibleForTesting static final int OVERSCROLL_RIGHT_EDGE = 2;
@@ -430,38 +425,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mPanningScalingState.clear();
}
- private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
- final int oldSize = (mTempPointerCoords != null) ? mTempPointerCoords.length : 0;
- if (oldSize < size) {
- PointerCoords[] oldTempPointerCoords = mTempPointerCoords;
- mTempPointerCoords = new PointerCoords[size];
- if (oldTempPointerCoords != null) {
- System.arraycopy(oldTempPointerCoords, 0, mTempPointerCoords, 0, oldSize);
- }
- }
- for (int i = oldSize; i < size; i++) {
- mTempPointerCoords[i] = new PointerCoords();
- }
- return mTempPointerCoords;
- }
-
- private PointerProperties[] getTempPointerPropertiesWithMinSize(int size) {
- final int oldSize = (mTempPointerProperties != null) ? mTempPointerProperties.length
- : 0;
- if (oldSize < size) {
- PointerProperties[] oldTempPointerProperties = mTempPointerProperties;
- mTempPointerProperties = new PointerProperties[size];
- if (oldTempPointerProperties != null) {
- System.arraycopy(oldTempPointerProperties, 0, mTempPointerProperties, 0,
- oldSize);
- }
- }
- for (int i = oldSize; i < size; i++) {
- mTempPointerProperties[i] = new PointerProperties();
- }
- return mTempPointerProperties;
- }
-
@VisibleForTesting
void transitionTo(State state) {
if (DEBUG_STATE_TRANSITIONS) {
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index e59bb42fd666..4f632c9e28a1 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -353,7 +353,10 @@ public final class Helper {
private static void addAutofillableIds(@NonNull ViewNode node,
@NonNull ArrayList<AutofillId> ids, boolean autofillableOnly) {
if (!autofillableOnly || node.getAutofillType() != View.AUTOFILL_TYPE_NONE) {
- ids.add(node.getAutofillId());
+ AutofillId id = node.getAutofillId();
+ if (id != null) {
+ ids.add(id);
+ }
}
final int size = node.getChildCount();
for (int i = 0; i < size; i++) {
diff --git a/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java b/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
new file mode 100644
index 000000000000..5e4bab15952d
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/BackupAgentConnectionManager.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup;
+
+import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.BackupManagerService.TAG;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ApplicationThreadConstants;
+import android.app.IActivityManager;
+import android.app.IBackupAgent;
+import android.app.backup.BackupAnnotations;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Binder;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.backup.internal.LifecycleOperationStorage;
+
+import java.util.Set;
+
+/**
+ * Handles the lifecycle of {@link IBackupAgent}s that the {@link UserBackupManagerService}
+ * communicates with.
+ *
+ * <p>There can only be one agent that's connected to at a time.
+ *
+ * <p>There should be only one instance of this class per {@link UserBackupManagerService}.
+ */
+public class BackupAgentConnectionManager {
+
+ /**
+ * Enables the OS making a decision on whether backup restricted mode should be used for apps
+ * that haven't explicitly opted in or out. See
+ * {@link android.content.pm.PackageManager#PROPERTY_USE_RESTRICTED_BACKUP_MODE} for details.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.BAKLAVA)
+ public static final long OS_DECIDES_BACKUP_RESTRICTED_MODE = 376661510;
+
+ // The thread performing the sequence of queued backups binds to each app's agent
+ // in succession. Bind notifications are asynchronously delivered through the
+ // Activity Manager; use this lock object to signal when a requested binding has
+ // completed.
+ private final Object mAgentConnectLock = new Object();
+ private IBackupAgent mConnectedAgent;
+ private volatile boolean mConnecting;
+ private final ArraySet<String> mRestoreNoRestrictedModePackages = new ArraySet<>();
+ private final ArraySet<String> mBackupNoRestrictedModePackages = new ArraySet<>();
+
+ private final IActivityManager mActivityManager;
+ private final ActivityManagerInternal mActivityManagerInternal;
+ private final LifecycleOperationStorage mOperationStorage;
+ private final PackageManager mPackageManager;
+ private final UserBackupManagerService mUserBackupManagerService;
+ private final int mUserId;
+ private final String mUserIdMsg;
+
+ BackupAgentConnectionManager(LifecycleOperationStorage operationStorage,
+ PackageManager packageManager, UserBackupManagerService userBackupManagerService,
+ int userId) {
+ mActivityManager = ActivityManager.getService();
+ mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mOperationStorage = operationStorage;
+ mPackageManager = packageManager;
+ mUserBackupManagerService = userBackupManagerService;
+ mUserId = userId;
+ mUserIdMsg = "[UserID:" + userId + "] ";
+ }
+
+ /**
+ * Fires off a backup agent, blocking until it attaches (and ActivityManager will call
+ * {@link #agentConnected(String, IBinder)}) or until this operation times out.
+ *
+ * @param mode a {@code BACKUP_MODE} from {@link android.app.ApplicationThreadConstants}.
+ */
+ @Nullable
+ public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode,
+ @BackupAnnotations.BackupDestination int backupDestination) {
+ IBackupAgent agent = null;
+ synchronized (mAgentConnectLock) {
+ mConnecting = true;
+ mConnectedAgent = null;
+ boolean useRestrictedMode = shouldUseRestrictedBackupModeForPackage(mode,
+ app.packageName);
+ try {
+ if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId,
+ backupDestination, useRestrictedMode)) {
+ Slog.d(TAG, mUserIdMsg + "awaiting agent for " + app);
+
+ // success; wait for the agent to arrive
+ // only wait 10 seconds for the bind to happen
+ long timeoutMark = System.currentTimeMillis() + 10 * 1000;
+ while (mConnecting && mConnectedAgent == null && (System.currentTimeMillis()
+ < timeoutMark)) {
+ try {
+ mAgentConnectLock.wait(5000);
+ } catch (InterruptedException e) {
+ // just bail
+ Slog.w(TAG, mUserIdMsg + "Interrupted: " + e);
+ mConnecting = false;
+ mConnectedAgent = null;
+ }
+ }
+
+ // if we timed out with no connect, abort and move on
+ if (mConnecting) {
+ Slog.w(TAG, mUserIdMsg + "Timeout waiting for agent " + app);
+ mConnectedAgent = null;
+ }
+ Slog.i(TAG, mUserIdMsg + "got agent " + mConnectedAgent);
+ agent = mConnectedAgent;
+ }
+ } catch (RemoteException e) {
+ // can't happen - ActivityManager is local
+ }
+ }
+ if (agent == null) {
+ mActivityManagerInternal.clearPendingBackup(mUserId);
+ }
+ return agent;
+ }
+
+ /**
+ * Tell the ActivityManager that we are done with the {@link IBackupAgent} of this {@code app}.
+ * It will tell the app to destroy the agent.
+ */
+ public void unbindAgent(ApplicationInfo app) {
+ try {
+ mActivityManager.unbindBackupAgent(app);
+ } catch (RemoteException e) {
+ // Can't happen - activity manager is local
+ }
+ }
+
+ /**
+ * Callback: a requested backup agent has been instantiated. This should only be called from
+ * the
+ * {@link ActivityManager} when it's telling us that an agent is ready after a call to
+ * {@link #bindToAgentSynchronous(ApplicationInfo, int, int)}.
+ */
+ public void agentConnected(String packageName, IBinder agentBinder) {
+ synchronized (mAgentConnectLock) {
+ if (getCallingUid() == android.os.Process.SYSTEM_UID) {
+ Slog.d(TAG,
+ mUserIdMsg + "agentConnected pkg=" + packageName + " agent=" + agentBinder);
+ mConnectedAgent = IBackupAgent.Stub.asInterface(agentBinder);
+ mConnecting = false;
+ } else {
+ Slog.w(TAG, mUserIdMsg + "Non-system process uid=" + getCallingUid()
+ + " claiming agent connected");
+ }
+ mAgentConnectLock.notifyAll();
+ }
+ }
+
+ /**
+ * Callback: a backup agent has failed to come up, or has unexpectedly quit. If the agent failed
+ * to come up in the first place, the agentBinder argument will be {@code null}. This should
+ * only be called from the {@link ActivityManager}.
+ */
+ public void agentDisconnected(String packageName) {
+ synchronized (mAgentConnectLock) {
+ if (getCallingUid() == Process.SYSTEM_UID) {
+ mConnectedAgent = null;
+ mConnecting = false;
+ } else {
+ Slog.w(TAG, mUserIdMsg + "Non-system process uid=" + getCallingUid()
+ + " claiming agent disconnected");
+ }
+ Slog.w(TAG, mUserIdMsg + "agentDisconnected: the backup agent for " + packageName
+ + " died: cancel current operations");
+
+ // Offload operation cancellation off the main thread as the cancellation callbacks
+ // might call out to BackupTransport. Other operations started on the same package
+ // before the cancellation callback has executed will also be cancelled by the callback.
+ Runnable cancellationRunnable = () -> {
+ // handleCancel() causes the PerformFullTransportBackupTask to go on to
+ // tearDownAgentAndKill: that will unbindBackupAgent in the Activity Manager, so
+ // that the package being backed up doesn't get stuck in restricted mode until the
+ // backup time-out elapses.
+ for (int token : mOperationStorage.operationTokensForPackage(packageName)) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG,
+ mUserIdMsg + "agentDisconnected: will handleCancel(all) for token:"
+ + Integer.toHexString(token));
+ }
+ mUserBackupManagerService.handleCancel(token, true /* cancelAll */);
+ }
+ };
+ getThreadForCancellation(cancellationRunnable).start();
+
+ mAgentConnectLock.notifyAll();
+ }
+ }
+
+ /**
+ * Marks the given set of packages as packages that should not be put into restricted mode if
+ * they are started for the given {@link BackupAnnotations.OperationType}.
+ */
+ public void setNoRestrictedModePackages(Set<String> packageNames,
+ @BackupAnnotations.OperationType int opType) {
+ if (opType == BackupAnnotations.OperationType.BACKUP) {
+ mBackupNoRestrictedModePackages.clear();
+ mBackupNoRestrictedModePackages.addAll(packageNames);
+ } else if (opType == BackupAnnotations.OperationType.RESTORE) {
+ mRestoreNoRestrictedModePackages.clear();
+ mRestoreNoRestrictedModePackages.addAll(packageNames);
+ } else {
+ throw new IllegalArgumentException("opType must be BACKUP or RESTORE");
+ }
+ }
+
+ /**
+ * Clears the list of packages that should not be put into restricted mode for either backup or
+ * restore.
+ */
+ public void clearNoRestrictedModePackages() {
+ mBackupNoRestrictedModePackages.clear();
+ mRestoreNoRestrictedModePackages.clear();
+ }
+
+ /**
+ * If the app has specified {@link PackageManager#PROPERTY_USE_RESTRICTED_BACKUP_MODE}, then
+ * its value is returned. If it hasn't and it targets an SDK below
+ * {@link Build.VERSION_CODES#BAKLAVA} then returns true. If it targets a newer SDK, then
+ * returns the decision made by the {@link android.app.backup.BackupTransport}.
+ *
+ * <p>When this method is called, we should have already asked the transport and cached its
+ * response in {@link #mBackupNoRestrictedModePackages} or
+ * {@link #mRestoreNoRestrictedModePackages} so this method will immediately return without
+ * any IPC to the transport.
+ */
+ private boolean shouldUseRestrictedBackupModeForPackage(
+ @BackupAnnotations.OperationType int mode, String packageName) {
+ if (!Flags.enableRestrictedModeChanges()) {
+ return true;
+ }
+
+ // Key/Value apps are never put in restricted mode.
+ if (mode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL
+ || mode == ApplicationThreadConstants.BACKUP_MODE_RESTORE) {
+ return false;
+ }
+
+ try {
+ PackageManager.Property property = mPackageManager.getPropertyAsUser(
+ PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE,
+ packageName, /* className= */ null, mUserId);
+ if (property.isBoolean()) {
+ // If the package has explicitly specified, we won't ask the transport.
+ return property.getBoolean();
+ } else {
+ Slog.w(TAG,
+ PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE + "must be a boolean.");
+ }
+ } catch (NameNotFoundException e) {
+ // This is expected when the package has not defined the property in its manifest.
+ }
+
+ // The package has not specified the property. The behavior depends on the package's
+ // targetSdk.
+ // <36 gets the old behavior of always using restricted mode.
+ if (!CompatChanges.isChangeEnabled(OS_DECIDES_BACKUP_RESTRICTED_MODE, packageName,
+ UserHandle.of(mUserId))) {
+ return true;
+ }
+
+ // Apps targeting >=36 get the behavior decided by the transport.
+ // By this point, we should have asked the transport and cached its decision.
+ if ((mode == ApplicationThreadConstants.BACKUP_MODE_FULL
+ && mBackupNoRestrictedModePackages.contains(packageName)) || (
+ mode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL
+ && mRestoreNoRestrictedModePackages.contains(packageName))) {
+ Slog.d(TAG, "Transport requested no restricted mode for: " + packageName);
+ return false;
+ }
+ return true;
+ }
+
+ @VisibleForTesting
+ Thread getThreadForCancellation(Runnable operation) {
+ return new Thread(operation, /* operationName */ "agent-disconnected");
+ }
+
+ @VisibleForTesting
+ int getCallingUid() {
+ return Binder.getCallingUid();
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 5f0071d47c89..3f6ede95eaf9 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -658,7 +658,8 @@ public class BackupManagerService extends IBackupManager.Stub {
getServiceForUserIfCallerHasPermission(userId, "agentConnected()");
if (userBackupManagerService != null) {
- userBackupManagerService.agentConnected(packageName, agentBinder);
+ userBackupManagerService.getBackupAgentConnectionManager().agentConnected(packageName,
+ agentBinder);
}
}
@@ -683,7 +684,8 @@ public class BackupManagerService extends IBackupManager.Stub {
getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()");
if (userBackupManagerService != null) {
- userBackupManagerService.agentDisconnected(packageName);
+ userBackupManagerService.getBackupAgentConnectionManager().agentDisconnected(
+ packageName);
}
}
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index f5d68362c70a..136bacdd6399 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -146,7 +146,8 @@ public class KeyValueAdbBackupEngine {
private IBackupAgent bindToAgent(ApplicationInfo targetApp) {
try {
- return mBackupManagerService.bindToAgentSynchronous(targetApp,
+ return mBackupManagerService.getBackupAgentConnectionManager().bindToAgentSynchronous(
+ targetApp,
ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL,
BackupAnnotations.BackupDestination.CLOUD);
} catch (SecurityException e) {
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 5de2fb30ac78..e085f6e63067 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -43,9 +43,7 @@ import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.AppGlobals;
-import android.app.ApplicationThreadConstants;
import android.app.IActivityManager;
-import android.app.IBackupAgent;
import android.app.PendingIntent;
import android.app.backup.BackupAgent;
import android.app.backup.BackupAnnotations;
@@ -60,9 +58,6 @@ import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
-import android.app.compat.CompatChanges;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -83,7 +78,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.IBinder;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
@@ -302,21 +296,10 @@ public class UserBackupManagerService {
private static final String BACKUP_FINISHED_ACTION = "android.intent.action.BACKUP_FINISHED";
private static final String BACKUP_FINISHED_PACKAGE_EXTRA = "packageName";
- /**
- * Enables the OS making a decision on whether backup restricted mode should be used for apps
- * that haven't explicitly opted in or out. See
- * {@link PackageManager#PROPERTY_USE_RESTRICTED_BACKUP_MODE} for details.
- */
- @ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.BAKLAVA)
- public static final long OS_DECIDES_BACKUP_RESTRICTED_MODE = 376661510;
-
// Time delay for initialization operations that can be delayed so as not to consume too much
// CPU on bring-up and increase time-to-UI.
private static final long INITIALIZATION_DELAY_MILLIS = 3000;
- // Timeout interval for deciding that a bind has taken too long.
- private static final long BIND_TIMEOUT_INTERVAL = 10 * 1000;
// Timeout interval for deciding that a clear-data has taken too long.
private static final long CLEAR_DATA_TIMEOUT_INTERVAL = 30 * 1000;
@@ -365,22 +348,9 @@ public class UserBackupManagerService {
// Backups that we haven't started yet. Keys are package names.
private final HashMap<String, BackupRequest> mPendingBackups = new HashMap<>();
- private final ArraySet<String> mRestoreNoRestrictedModePackages = new ArraySet<>();
- private final ArraySet<String> mBackupNoRestrictedModePackages = new ArraySet<>();
-
// locking around the pending-backup management
private final Object mQueueLock = new Object();
-
private final UserBackupPreferences mBackupPreferences;
-
- // The thread performing the sequence of queued backups binds to each app's agent
- // in succession. Bind notifications are asynchronously delivered through the
- // Activity Manager; use this lock object to signal when a requested binding has
- // completed.
- private final Object mAgentConnectLock = new Object();
- private IBackupAgent mConnectedAgent;
- private volatile boolean mConnecting;
-
private volatile boolean mBackupRunning;
private volatile long mLastBackupPass;
@@ -410,6 +380,7 @@ public class UserBackupManagerService {
private ActiveRestoreSession mActiveRestoreSession;
+ private final BackupAgentConnectionManager mBackupAgentConnectionManager;
private final LifecycleOperationStorage mOperationStorage;
private final Random mTokenGenerator = new Random();
@@ -547,6 +518,8 @@ public class UserBackupManagerService {
mRegisterTransportsRequestedTime = 0;
mPackageManager = packageManager;
mOperationStorage = operationStorage;
+ mBackupAgentConnectionManager = new BackupAgentConnectionManager(mOperationStorage,
+ mPackageManager, this, mUserId);
mTransportManager = transportManager;
mFullBackupQueue = new ArrayList<>();
mBackupHandler = backupHandler;
@@ -599,6 +572,8 @@ public class UserBackupManagerService {
mAgentTimeoutParameters.start();
mOperationStorage = new LifecycleOperationStorage(mUserId);
+ mBackupAgentConnectionManager = new BackupAgentConnectionManager(mOperationStorage,
+ mPackageManager, this, mUserId);
Objects.requireNonNull(userBackupThread, "userBackupThread cannot be null");
mBackupHandler = new BackupHandler(this, mOperationStorage, userBackupThread);
@@ -1660,67 +1635,6 @@ public class UserBackupManagerService {
}
}
- /** Fires off a backup agent, blocking until it attaches or times out. */
- @Nullable
- public IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode,
- @BackupDestination int backupDestination) {
- IBackupAgent agent = null;
- synchronized (mAgentConnectLock) {
- mConnecting = true;
- mConnectedAgent = null;
- boolean useRestrictedMode = shouldUseRestrictedBackupModeForPackage(mode,
- app.packageName);
- try {
- if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId,
- backupDestination, useRestrictedMode)) {
- Slog.d(TAG, addUserIdToLogMessage(mUserId, "awaiting agent for " + app));
-
- // success; wait for the agent to arrive
- // only wait 10 seconds for the bind to happen
- long timeoutMark = System.currentTimeMillis() + BIND_TIMEOUT_INTERVAL;
- while (mConnecting && mConnectedAgent == null
- && (System.currentTimeMillis() < timeoutMark)) {
- try {
- mAgentConnectLock.wait(5000);
- } catch (InterruptedException e) {
- // just bail
- Slog.w(TAG, addUserIdToLogMessage(mUserId, "Interrupted: " + e));
- mConnecting = false;
- mConnectedAgent = null;
- }
- }
-
- // if we timed out with no connect, abort and move on
- if (mConnecting) {
- Slog.w(
- TAG,
- addUserIdToLogMessage(mUserId, "Timeout waiting for agent " + app));
- mConnectedAgent = null;
- }
- if (DEBUG) {
- Slog.i(TAG, addUserIdToLogMessage(mUserId, "got agent " + mConnectedAgent));
- }
- agent = mConnectedAgent;
- }
- } catch (RemoteException e) {
- // can't happen - ActivityManager is local
- }
- }
- if (agent == null) {
- mActivityManagerInternal.clearPendingBackup(mUserId);
- }
- return agent;
- }
-
- /** Unbind from a backup agent. */
- public void unbindAgent(ApplicationInfo app) {
- try {
- mActivityManager.unbindBackupAgent(app);
- } catch (RemoteException e) {
- // Can't happen - activity manager is local
- }
- }
-
/**
* Clear an application's data after a failed restore, blocking until the operation completes or
* times out.
@@ -2493,10 +2407,6 @@ public class UserBackupManagerService {
AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, mUserId);
}
- // *****************************
- // NEW UNIFIED RESTORE IMPLEMENTATION
- // *****************************
-
/** Schedule a backup pass for {@code packageName}. */
public void dataChangedImpl(String packageName) {
HashSet<String> targets = dataChangedTargets(packageName);
@@ -3122,91 +3032,6 @@ public class UserBackupManagerService {
}
}
- /**
- * Marks the given set of packages as packages that should not be put into restricted mode if
- * they are started for the given {@link BackupAnnotations.OperationType}.
- */
- public void setNoRestrictedModePackages(Set<String> packageNames,
- @BackupAnnotations.OperationType int opType) {
- if (opType == BackupAnnotations.OperationType.BACKUP) {
- mBackupNoRestrictedModePackages.clear();
- mBackupNoRestrictedModePackages.addAll(packageNames);
- } else if (opType == BackupAnnotations.OperationType.RESTORE) {
- mRestoreNoRestrictedModePackages.clear();
- mRestoreNoRestrictedModePackages.addAll(packageNames);
- } else {
- throw new IllegalArgumentException("opType must be BACKUP or RESTORE");
- }
- }
-
- /**
- * Clears the list of packages that should not be put into restricted mode for either backup or
- * restore.
- */
- public void clearNoRestrictedModePackages() {
- mBackupNoRestrictedModePackages.clear();
- mRestoreNoRestrictedModePackages.clear();
- }
-
- /**
- * If the app has specified {@link PackageManager#PROPERTY_USE_RESTRICTED_BACKUP_MODE}, then
- * its value is returned. If it hasn't and it targets an SDK below
- * {@link Build.VERSION_CODES#BAKLAVA} then returns true. If it targets a newer SDK, then
- * returns the decision made by the {@link android.app.backup.BackupTransport}.
- *
- * <p>When this method is called, we should have already asked the transport and cached its
- * response in {@link #mBackupNoRestrictedModePackages} or
- * {@link #mRestoreNoRestrictedModePackages} so this method will immediately return without
- * any IPC to the transport.
- */
- private boolean shouldUseRestrictedBackupModeForPackage(
- @BackupAnnotations.OperationType int mode, String packageName) {
- if (!Flags.enableRestrictedModeChanges()) {
- return true;
- }
-
- // Key/Value apps are never put in restricted mode.
- if (mode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL
- || mode == ApplicationThreadConstants.BACKUP_MODE_RESTORE) {
- return false;
- }
-
- try {
- PackageManager.Property property = mPackageManager.getPropertyAsUser(
- PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE,
- packageName, /* className= */ null,
- mUserId);
- if (property.isBoolean()) {
- // If the package has explicitly specified, we won't ask the transport.
- return property.getBoolean();
- } else {
- Slog.w(TAG, PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE
- + "must be a boolean.");
- }
- } catch (NameNotFoundException e) {
- // This is expected when the package has not defined the property in its manifest.
- }
-
- // The package has not specified the property. The behavior depends on the package's
- // targetSdk.
- // <36 gets the old behavior of always using restricted mode.
- if (!CompatChanges.isChangeEnabled(OS_DECIDES_BACKUP_RESTRICTED_MODE, packageName,
- UserHandle.of(mUserId))) {
- return true;
- }
-
- // Apps targeting >=36 get the behavior decided by the transport.
- // By this point, we should have asked the transport and cached its decision.
- if ((mode == ApplicationThreadConstants.BACKUP_MODE_FULL
- && mBackupNoRestrictedModePackages.contains(packageName))
- || (mode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL
- && mRestoreNoRestrictedModePackages.contains(packageName))) {
- Slog.d(TAG, "Transport requested no restricted mode for: " + packageName);
- return false;
- }
- return true;
- }
-
private boolean startConfirmationUi(int token, String action) {
try {
Intent confIntent = new Intent(action);
@@ -3898,83 +3723,6 @@ public class UserBackupManagerService {
}
/**
- * Callback: a requested backup agent has been instantiated. This should only be called from the
- * {@link ActivityManager}.
- */
- public void agentConnected(String packageName, IBinder agentBinder) {
- synchronized (mAgentConnectLock) {
- if (Binder.getCallingUid() == Process.SYSTEM_UID) {
- Slog.d(
- TAG,
- addUserIdToLogMessage(
- mUserId,
- "agentConnected pkg=" + packageName + " agent=" + agentBinder));
- mConnectedAgent = IBackupAgent.Stub.asInterface(agentBinder);
- mConnecting = false;
- } else {
- Slog.w(
- TAG,
- addUserIdToLogMessage(
- mUserId,
- "Non-system process uid="
- + Binder.getCallingUid()
- + " claiming agent connected"));
- }
- mAgentConnectLock.notifyAll();
- }
- }
-
- /**
- * Callback: a backup agent has failed to come up, or has unexpectedly quit. If the agent failed
- * to come up in the first place, the agentBinder argument will be {@code null}. This should
- * only be called from the {@link ActivityManager}.
- */
- public void agentDisconnected(String packageName) {
- synchronized (mAgentConnectLock) {
- if (Binder.getCallingUid() == Process.SYSTEM_UID) {
- mConnectedAgent = null;
- mConnecting = false;
- } else {
- Slog.w(
- TAG,
- addUserIdToLogMessage(
- mUserId,
- "Non-system process uid="
- + Binder.getCallingUid()
- + " claiming agent disconnected"));
- }
- Slog.w(TAG, "agentDisconnected: the backup agent for " + packageName
- + " died: cancel current operations");
-
- // Offload operation cancellation off the main thread as the cancellation callbacks
- // might call out to BackupTransport. Other operations started on the same package
- // before the cancellation callback has executed will also be cancelled by the callback.
- Runnable cancellationRunnable = () -> {
- // handleCancel() causes the PerformFullTransportBackupTask to go on to
- // tearDownAgentAndKill: that will unbindBackupAgent in the Activity Manager, so
- // that the package being backed up doesn't get stuck in restricted mode until the
- // backup time-out elapses.
- for (int token : mOperationStorage.operationTokensForPackage(packageName)) {
- if (MORE_DEBUG) {
- Slog.d(TAG, "agentDisconnected: will handleCancel(all) for token:"
- + Integer.toHexString(token));
- }
- handleCancel(token, true /* cancelAll */);
- }
- };
- getThreadForAsyncOperation(/* operationName */ "agent-disconnected",
- cancellationRunnable).start();
-
- mAgentConnectLock.notifyAll();
- }
- }
-
- @VisibleForTesting
- Thread getThreadForAsyncOperation(String operationName, Runnable operation) {
- return new Thread(operation, operationName);
- }
-
- /**
* An application being installed will need a restore pass, then the {@link PackageManager} will
* need to be told when the restore is finished.
*/
@@ -4521,4 +4269,8 @@ public class UserBackupManagerService {
public IBackupManager getBackupManagerBinder() {
return mBackupManagerBinder;
}
+
+ public BackupAgentConnectionManager getBackupAgentConnectionManager() {
+ return mBackupAgentConnectionManager;
+ }
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 12712063e344..b98cb1086680 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -314,7 +314,7 @@ public class FullBackupEngine {
Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
}
mAgent =
- backupManagerService.bindToAgentSynchronous(
+ backupManagerService.getBackupAgentConnectionManager().bindToAgentSynchronous(
mPkg.applicationInfo, ApplicationThreadConstants.BACKUP_MODE_FULL,
mBackupEligibilityRules.getBackupDestination());
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index be9cdc8692cb..65730c9591a8 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -702,7 +702,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
}
// Clear this to avoid using the memory until reboot.
- mUserBackupManagerService.clearNoRestrictedModePackages();
+ mUserBackupManagerService
+ .getBackupAgentConnectionManager().clearNoRestrictedModePackages();
Slog.i(TAG, "Full data backup pass finished.");
mUserBackupManagerService.getWakelock().release();
@@ -741,7 +742,8 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
}
packageNames = transport.getPackagesThatShouldNotUseRestrictedMode(packageNames,
BACKUP);
- mUserBackupManagerService.setNoRestrictedModePackages(packageNames, BACKUP);
+ mUserBackupManagerService.getBackupAgentConnectionManager().setNoRestrictedModePackages(
+ packageNames, BACKUP);
} catch (RemoteException e) {
Slog.i(TAG, "Failed to retrieve no restricted mode packages from transport");
}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index 3a6e1cafa505..82232a653858 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -741,7 +741,7 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
final IBackupAgent agent;
try {
agent =
- mBackupManagerService.bindToAgentSynchronous(
+ mBackupManagerService.getBackupAgentConnectionManager().bindToAgentSynchronous(
packageInfo.applicationInfo, BACKUP_MODE_INCREMENTAL,
mBackupEligibilityRules.getBackupDestination());
if (agent == null) {
@@ -1302,7 +1302,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
// For PM metadata (for which applicationInfo is null) there is no agent-bound state.
if (mCurrentPackage.applicationInfo != null) {
- mBackupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
+ mBackupManagerService.getBackupAgentConnectionManager().unbindAgent(
+ mCurrentPackage.applicationInfo);
}
mAgent = null;
}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 2d99c96452da..b59e860f81fe 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -410,11 +410,7 @@ public class FullRestoreEngine extends RestoreEngine {
// All set; now set up the IPC and launch the agent
setUpPipes();
- mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
- FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)
- ? ApplicationThreadConstants.BACKUP_MODE_RESTORE
- : ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL,
- mBackupEligibilityRules.getBackupDestination());
+ mAgent = bindToAgent(info);
mAgentPackage = pkg;
} catch (IOException | NameNotFoundException e) {
// fall through to error handling
@@ -805,15 +801,12 @@ public class FullRestoreEngine extends RestoreEngine {
return packages.contains(packageName);
}
- void sendOnRestorePackage(String name) {
- if (mObserver != null) {
- try {
- // TODO: use a more user-friendly name string
- mObserver.onRestorePackage(name);
- } catch (RemoteException e) {
- Slog.w(TAG, "full restore observer went away: restorePackage");
- mObserver = null;
- }
- }
+ private IBackupAgent bindToAgent(FileMetadata info) {
+ return mBackupManagerService.getBackupAgentConnectionManager().bindToAgentSynchronous(
+ mTargetApp,
+ FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)
+ ? ApplicationThreadConstants.BACKUP_MODE_RESTORE
+ : ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL,
+ mBackupEligibilityRules.getBackupDestination());
}
}
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 5ee51a5aa189..e5c7e5cce757 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -814,7 +814,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
// Good to go! Set up and bind the agent...
mAgent =
- backupManagerService.bindToAgentSynchronous(
+ backupManagerService.getBackupAgentConnectionManager().bindToAgentSynchronous(
mCurrentPackage.applicationInfo,
ApplicationThreadConstants.BACKUP_MODE_RESTORE,
mBackupEligibilityRules.getBackupDestination());
@@ -1364,7 +1364,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
backupManagerService.getBackupHandler().removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
// Clear this to avoid using the memory until reboot.
- backupManagerService.clearNoRestrictedModePackages();
+ backupManagerService.getBackupAgentConnectionManager().clearNoRestrictedModePackages();
// If we have a PM token, we must under all circumstances be sure to
// handshake when we've finished.
@@ -1838,7 +1838,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
}
packageNames = transport.getPackagesThatShouldNotUseRestrictedMode(packageNames,
RESTORE);
- backupManagerService.setNoRestrictedModePackages(packageNames, RESTORE);
+ backupManagerService.getBackupAgentConnectionManager().setNoRestrictedModePackages(
+ packageNames, RESTORE);
} catch (RemoteException e) {
Slog.i(TAG, "Failed to retrieve restricted mode packages from transport");
}
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index dbeca82ade89..2d3782fb3181 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -16,6 +16,8 @@
package com.android.server.companion.securechannel;
+import static android.security.attestationverification.AttestationVerificationManager.FLAG_FAILURE_UNKNOWN;
+
import android.annotation.NonNull;
import android.content.Context;
import android.os.Build;
@@ -67,7 +69,7 @@ public class SecureChannel {
private D2DConnectionContextV1 mConnectionContext;
private String mAlias;
- private int mVerificationResult;
+ private int mVerificationResult = FLAG_FAILURE_UNKNOWN;
private boolean mPskVerified;
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 99772c39bef1..03d6c8b695a0 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1318,6 +1318,7 @@ public class SystemConfig {
}
XmlUtils.skipCurrentTag(parser);
} break;
+ case "disabled-in-sku":
case "disabled-until-used-preinstalled-carrier-app": {
if (allowAppConfigs) {
String pkgname = parser.getAttributeValue(null, "package");
@@ -1334,6 +1335,24 @@ public class SystemConfig {
}
XmlUtils.skipCurrentTag(parser);
} break;
+ case "enabled-in-sku-override": {
+ if (allowAppConfigs) {
+ String pkgname = parser.getAttributeValue(null, "package");
+ if (pkgname == null) {
+ Slog.w(TAG,
+ "<" + name + "> without "
+ + "package in " + permFile + " at "
+ + parser.getPositionDescription());
+ } else if (!mDisabledUntilUsedPreinstalledCarrierApps.remove(pkgname)) {
+ Slog.w(TAG,
+ "<" + name + "> packagename:" + pkgname + " not included"
+ + "in disabled-in-sku");
+ }
+ } else {
+ logNotAllowedInPartition(name, permFile, parser);
+ }
+ XmlUtils.skipCurrentTag(parser);
+ } break;
case "privapp-permissions": {
if (allowPrivappPermissions) {
// privapp permissions from system, apex, vendor, product and
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 06e6c8b1ec53..2012f5632a64 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -48,7 +48,6 @@ import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
-import android.net.vcn.Flags;
import android.net.vcn.IVcnManagementService;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -890,20 +889,11 @@ public class VcnManagementService extends IVcnManagementService.Stub {
while (configsIterator.hasNext()) {
final ParcelUuid subGrp = configsIterator.next();
- if (Flags.fixConfigGarbageCollection()) {
- if (!subGroups.contains(subGrp)) {
- // Trim subGrps with no more subscriptions; must have moved to another subGrp
- logDbg("Garbage collect VcnConfig for group=" + subGrp);
- configsIterator.remove();
- shouldWrite = true;
- }
- } else {
- final List<SubscriptionInfo> subscriptions = subMgr.getSubscriptionsInGroup(subGrp);
- if (subscriptions == null || subscriptions.isEmpty()) {
- // Trim subGrps with no more subscriptions; must have moved to another subGrp
- configsIterator.remove();
- shouldWrite = true;
- }
+ if (!subGroups.contains(subGrp)) {
+ // Trim subGrps with no more subscriptions; must have moved to another subGrp
+ logDbg("Garbage collect VcnConfig for group=" + subGrp);
+ configsIterator.remove();
+ shouldWrite = true;
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 679c7ac3ceac..3ce645158fe4 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -16,6 +16,10 @@
package com.android.server.accounts;
+import static android.Manifest.permission.COPY_ACCOUNTS;
+import static android.Manifest.permission.REMOVE_ACCOUNTS;
+import static android.app.admin.flags.Flags.splitCreateManagedProfileEnabled;
+
import android.Manifest;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
@@ -1739,9 +1743,11 @@ public class AccountManagerService
public void copyAccountToUser(final IAccountManagerResponse response, final Account account,
final int userFrom, int userTo) {
int callingUid = Binder.getCallingUid();
- if (isCrossUser(callingUid, UserHandle.USER_ALL)) {
+ if (isCrossUser(callingUid, UserHandle.USER_ALL)
+ && !hasCopyAccountsPermission()) {
throw new SecurityException("Calling copyAccountToUser requires "
- + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL
+ + " or " + COPY_ACCOUNTS);
}
final UserAccounts fromAccounts = getUserAccounts(userFrom);
final UserAccounts toAccounts = getUserAccounts(userTo);
@@ -1793,6 +1799,12 @@ public class AccountManagerService
}
}
+ private boolean hasCopyAccountsPermission() {
+ return splitCreateManagedProfileEnabled()
+ && mContext.checkCallingOrSelfPermission(COPY_ACCOUNTS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
@Override
public boolean accountAuthenticated(final Account account) {
final int callingUid = Binder.getCallingUid();
@@ -2346,7 +2358,8 @@ public class AccountManagerService
UserHandle user = UserHandle.of(userId);
if (!isAccountManagedByCaller(account.type, callingUid, user.getIdentifier())
&& !isSystemUid(callingUid)
- && !isProfileOwner(callingUid)) {
+ && !isProfileOwner(callingUid)
+ && !hasRemoveAccountsPermission()) {
String msg = String.format(
"uid %s cannot remove accounts of type: %s",
callingUid,
@@ -2408,6 +2421,12 @@ public class AccountManagerService
}
}
+ private boolean hasRemoveAccountsPermission() {
+ return splitCreateManagedProfileEnabled()
+ && mContext.checkCallingOrSelfPermission(REMOVE_ACCOUNTS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
@Override
public boolean removeAccountExplicitly(Account account) {
final int callingUid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3f540ad43da1..ab3ab159ba12 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -115,6 +115,7 @@ import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_
import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM;
import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__BIND;
import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__START;
+import static com.android.media.flags.Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
@@ -9319,6 +9320,46 @@ public final class ActiveServices {
}
}
+ /**
+ * Handles notifications from MediaSessionService about inactive media foreground services.
+ * This method evaluates the provided information and determines whether to stop the
+ * corresponding foreground service.
+ *
+ * @param packageName The package name of the app running the foreground service.
+ * @param userId The user ID associated with the foreground service.
+ * @param notificationId The ID of the media notification associated with the foreground
+ * service.
+ */
+ void notifyInactiveMediaForegroundServiceLocked(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId) {
+ if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ return;
+ }
+
+ final ServiceMap smap = mServiceMap.get(userId);
+ if (smap == null) {
+ return;
+ }
+ final int serviceSize = smap.mServicesByInstanceName.size();
+ for (int i = 0; i < serviceSize; i++) {
+ final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
+ if (sr.appInfo.packageName.equals(packageName) && sr.isForeground) {
+ if (sr.foregroundServiceType
+ == ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
+ && sr.foregroundId == notificationId) {
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.d(TAG, "Forcing media foreground service to background for package "
+ + packageName);
+ }
+ setServiceForegroundInnerLocked(sr, /* id */ 0,
+ /* notification */ null, /* flags */ 0,
+ /* foregroundServiceType */ 0, /* callingUidStart */ 0);
+ }
+ }
+ }
+ }
+
+
private static void getClientPackages(ServiceRecord sr, ArraySet<String> output) {
var connections = sr.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e166807083ff..5c5361bacf5a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17923,6 +17923,15 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void notifyInactiveMediaForegroundService(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId) {
+ synchronized (ActivityManagerService.this) {
+ mServices.notifyInactiveMediaForegroundServiceLocked(packageName, userId,
+ notificationId);
+ }
+ }
+
+ @Override
public ArraySet<String> getClientPackages(String servicePackageName) {
synchronized (ActivityManagerService.this) {
return mServices.getClientPackagesLocked(servicePackageName);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 02e2c391bb27..d3d3fc968ae6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -39,6 +39,8 @@ import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRI
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL;
+import static com.android.media.flags.Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange;
+import static com.android.media.flags.Flags.FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE;
import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -445,6 +447,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
return runCapabilities(pw);
case "set-app-zygote-preload-timeout":
return runSetAppZygotePreloadTimeout(pw);
+ case "set-media-foreground-service":
+ return runSetMediaForegroundService(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -454,6 +458,48 @@ final class ActivityManagerShellCommand extends ShellCommand {
return -1;
}
+ int runSetMediaForegroundService(PrintWriter pw) throws RemoteException {
+ mInternal.enforceCallingPermission(
+ android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE,
+ "runSetMediaForegroundService()");
+ final PrintWriter err = getErrPrintWriter();
+ if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ err.println("Error: flag "
+ + FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE
+ + " not enabled");
+ return -1;
+ }
+ int userId = UserHandle.USER_CURRENT;
+ final String cmd = getNextArgRequired();
+ if ("inactive".equals(cmd)) {
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ if (userId == UserHandle.USER_ALL) {
+ err.println(
+ "Error: Can't set media fgs inactive with user 'all'");
+ return -1;
+ }
+ } else {
+ err.println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ final String pkgName = getNextArgRequired();
+ final int notificationId = Integer.parseInt(getNextArgRequired());
+ if (notificationId == 0) {
+ err.println("Error: notification id cannot be zero");
+ return -1;
+ }
+ mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
+ userId, notificationId);
+ return 0;
+ }
+ err.println("Error: Unknown set-media-foreground-service command: " + cmd);
+ return -1;
+ }
+
int runSetAppZygotePreloadTimeout(PrintWriter pw) throws RemoteException {
final String timeout = getNextArgRequired();
final int timeoutMs = Integer.parseInt(timeout);
@@ -4637,6 +4683,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" --protobuf: format output using protobuffer");
pw.println(" set-app-zygote-preload-timeout <TIMEOUT_IN_MS>");
pw.println(" Set the timeout for preloading code in the app-zygote");
+ pw.println(" set-media-foreground-service inactive [--user USER_ID]"
+ + " <PACKAGE> <NOTIFICATION_ID>");
+ pw.println(" Set an app's media foreground service inactive.");
Intent.printIntentArgsHelp(pw, "");
}
}
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 3913d2f2ea92..961022b7231b 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -634,12 +634,20 @@ public final class AppStartInfoTracker {
}
final ApplicationStartInfo info = new ApplicationStartInfo(raw);
+ int uid = raw.getRealUid();
- AppStartInfoContainer container = mData.get(raw.getPackageName(), raw.getRealUid());
+ // Isolated process starts won't be reasonably accessible if stored by their uid, don't
+ // store them.
+ if (com.android.server.am.Flags.appStartInfoIsolatedProcess()
+ && UserHandle.isIsolated(uid)) {
+ return null;
+ }
+
+ AppStartInfoContainer container = mData.get(raw.getPackageName(), uid);
if (container == null) {
container = new AppStartInfoContainer(mAppStartInfoHistoryListSize);
- container.mUid = info.getRealUid();
- mData.put(raw.getPackageName(), raw.getRealUid(), container);
+ container.mUid = uid;
+ mData.put(raw.getPackageName(), uid, container);
}
container.addStartInfoLocked(info);
@@ -1010,6 +1018,17 @@ public final class AppStartInfoTracker {
new AppStartInfoContainer(mAppStartInfoHistoryListSize);
int uid = container.readFromProto(proto, AppsStartInfoProto.Package.USERS,
pkgName);
+
+ // If the isolated process flag is enabled and the uid is that of an isolated
+ // process, then break early so that the container will not be added to mData.
+ // This is expected only as a one time mitigation, records added after this flag
+ // is enabled should always return false for isIsolated and thereby always
+ // continue on.
+ if (com.android.server.am.Flags.appStartInfoIsolatedProcess()
+ && UserHandle.isIsolated(uid)) {
+ break;
+ }
+
synchronized (mLock) {
mData.put(pkgName, uid, container);
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index ef5296eef492..78c4f74f3afa 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -257,6 +257,7 @@ public class SettingsToPropertiesMapper {
"wear_systems",
"wear_sysui",
"wear_system_managed_surfaces",
+ "wear_watchfaces",
"window_surfaces",
"windowing_frontend",
"xr",
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index c59c40fc9cd8..6d247d227774 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -270,3 +270,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "app_start_info_isolated_process"
+ namespace: "system_performance"
+ description: "Adjust handling of isolated process records to be discarded."
+ bug: "374032823"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
index 5283eddd90fb..473691874262 100644
--- a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
+++ b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
@@ -24,6 +24,7 @@ import static android.Manifest.permission.CAPTURE_AUDIO_OUTPUT;
import static android.Manifest.permission.CAPTURE_MEDIA_OUTPUT;
import static android.Manifest.permission.CAPTURE_TUNER_AUDIO_INPUT;
import static android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT;
+import static android.Manifest.permission.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION;
import static android.Manifest.permission.MODIFY_AUDIO_ROUTING;
import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS;
import static android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS;
@@ -37,7 +38,6 @@ import android.os.Trace;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IntArray;
-import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.media.permission.INativePermissionController;
@@ -82,6 +82,8 @@ public class AudioServerPermissionProvider {
MONITORED_PERMS[PermissionEnum.CAPTURE_VOICE_COMMUNICATION_OUTPUT] =
CAPTURE_VOICE_COMMUNICATION_OUTPUT;
MONITORED_PERMS[PermissionEnum.BLUETOOTH_CONNECT] = BLUETOOTH_CONNECT;
+ MONITORED_PERMS[PermissionEnum.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION] =
+ BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION;
}
private final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 6e6bf80e8c09..40d5f86f8094 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -49,6 +49,7 @@ import static android.media.AudioManager.RINGER_MODE_VIBRATE;
import static android.media.AudioManager.STREAM_SYSTEM;
import static android.media.audio.Flags.autoPublicVolumeApiHardening;
import static android.media.audio.Flags.automaticBtDeviceType;
+import static android.media.audio.Flags.concurrentAudioRecordBypassPermission;
import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency;
import static android.media.audio.Flags.focusFreezeTestApi;
import static android.media.audio.Flags.roForegroundAudioControl;
@@ -4888,6 +4889,8 @@ public class AudioService extends IAudioService.Stub
+ equalScoLeaVcIndexRange());
pw.println("\tcom.android.media.audio.ringMyCar:"
+ ringMyCar());
+ pw.println("\tandroid.media.audio.Flags.concurrentAudioRecordBypassPermission:"
+ + concurrentAudioRecordBypassPermission());
}
private void dumpAudioMode(PrintWriter pw) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 82d5d4d8141d..e8786be4d8e6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -677,10 +677,11 @@ public class BiometricScheduler<T, U> {
* Start the timeout for the watchdog.
*/
public void startWatchdog() {
- if (mCurrentOperation == null) {
+ final BiometricSchedulerOperation operation = mCurrentOperation;
+ if (operation == null) {
+ Slog.e(TAG, "Current operation is null,no need to start watchdog");
return;
}
- final BiometricSchedulerOperation operation = mCurrentOperation;
mHandler.postDelayed(() -> {
if (operation == mCurrentOperation && !operation.isFinished()) {
Counter.logIncrement("biometric.value_scheduler_watchdog_triggered_count");
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 448c42b71731..805357e79565 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -1280,7 +1280,7 @@ public class AutomaticBrightnessController {
private boolean shouldApplyDozeScaleFactor() {
// We don't apply the doze scale factor if we have a designated brightness curve for doze.
- return (mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()
+ return (mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
? (!mUseNormalBrightnessForDoze && mDisplayPolicy == POLICY_DOZE)
|| Display.isDozeState(mDisplayState) : Display.isDozeState(mDisplayState))
&& getMode() != AUTO_BRIGHTNESS_MODE_DOZE;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 62fcccf13da9..ae74dbecc5f8 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -177,6 +177,7 @@ import com.android.server.display.feature.DisplayManagerFlags;
import com.android.server.display.layout.Layout;
import com.android.server.display.mode.DisplayModeDirector;
import com.android.server.display.notifications.DisplayNotificationManager;
+import com.android.server.display.plugin.PluginManager;
import com.android.server.display.utils.DebugUtils;
import com.android.server.display.utils.SensorUtils;
import com.android.server.input.InputManagerInternal;
@@ -583,6 +584,7 @@ public final class DisplayManagerService extends SystemService {
private final DisplayNotificationManager mDisplayNotificationManager;
private final ExternalDisplayStatsService mExternalDisplayStatsService;
+ private final PluginManager mPluginManager;
// Manages the relative placement of extended displays
@Nullable
@@ -669,6 +671,7 @@ public final class DisplayManagerService extends SystemService {
} else {
mDisplayTopologyCoordinator = null;
}
+ mPluginManager = new PluginManager(mContext, mFlags);
}
public void setupSchedulerPolicies() {
@@ -739,6 +742,7 @@ public final class DisplayManagerService extends SystemService {
mLogicalDisplayMapper.onBootCompleted();
mDisplayNotificationManager.onBootCompleted();
mExternalDisplayPolicy.onBootCompleted();
+ mPluginManager.onBootCompleted();
}
}
@@ -3552,6 +3556,9 @@ public final class DisplayManagerService extends SystemService {
SparseArray<DisplayPowerController> displayPowerControllersLocal = new SparseArray<>();
int displayPowerControllerCount;
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ ipw.increaseIndent();
+
synchronized (mSyncRoot) {
brightnessTrackerLocal = mBrightnessTracker;
@@ -3599,9 +3606,6 @@ public final class DisplayManagerService extends SystemService {
pw.println(" Display SdrBrightness=" + brightnessPair.sdrBrightness);
}
- IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
- ipw.increaseIndent();
-
pw.println();
pw.println("Display Adapters: size=" + mDisplayAdapters.size());
pw.println("------------------------");
@@ -3664,6 +3668,8 @@ public final class DisplayManagerService extends SystemService {
pw.println();
mDisplayTopologyCoordinator.dump(pw);
}
+ pw.println();
+ mPluginManager.dump(ipw);
pw.println();
mFlags.dump(pw);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 2948ae4d83fa..945365dcf8fe 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1399,7 +1399,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Use doze brightness if one of following is true:
// 1. The target `state` isDozeState.
// 2. Doze power request(POLICY_DOZE) if there's no exception(useNormalBrightnessForDoze).
- final boolean useDozeBrightness = mFlags.isNormalBrightnessForDozeParameterEnabled()
+ final boolean useDozeBrightness = mFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
? (!mPowerRequest.useNormalBrightnessForDoze && mPowerRequest.policy == POLICY_DOZE)
|| Display.isDozeState(state) : Display.isDozeState(state);
DisplayBrightnessState displayBrightnessState =
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
index a0ad49dd9f24..2c6f37448735 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
@@ -109,6 +109,8 @@ public class DisplayBrightnessStrategySelector {
private final int mDisplayId;
+ private final Context mContext;
+
/**
* The constructor of DozeBrightnessStrategy.
*/
@@ -117,6 +119,7 @@ public class DisplayBrightnessStrategySelector {
if (injector == null) {
injector = new Injector();
}
+ mContext = context;
mDisplayManagerFlags = flags;
mDisplayId = displayId;
mDozeBrightnessStrategy = injector.getDozeBrightnessStrategy();
@@ -348,7 +351,7 @@ public class DisplayBrightnessStrategySelector {
// a user can define a different display state(displayPowerRequest.dozeScreenState) too
// in the request with the Doze policy and user might request an override to force certain
// brightness.
- return (!mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()
+ return (!mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
|| !displayPowerRequest.useNormalBrightnessForDoze)
&& displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
&& !mAllowAutoBrightnessWhileDozing
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index ff73693d803b..94522d197429 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -525,7 +525,7 @@ public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2
}
final boolean shouldUseDozeMode =
- mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()
+ mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)
? (!useNormalBrightnessForDoze && policy == POLICY_DOZE)
|| Display.isDozeState(state)
: Display.isDozeState(state);
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 1a7d74ae1713..7f46bbbf0507 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -16,6 +16,7 @@
package com.android.server.display.feature;
+import android.content.Context;
import android.os.Build;
import android.os.SystemProperties;
import android.text.TextUtils;
@@ -461,8 +462,9 @@ public class DisplayManagerFlags {
/**
* @return Whether the useDozeBrightness parameter should be used
*/
- public boolean isNormalBrightnessForDozeParameterEnabled() {
- return mNormalBrightnessForDozeParameter.isEnabled();
+ public boolean isNormalBrightnessForDozeParameterEnabled(Context context) {
+ return mNormalBrightnessForDozeParameter.isEnabled() && context.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowNormalBrightnessForDozePolicy);
}
/**
diff --git a/services/core/java/com/android/server/display/plugin/Plugin.java b/services/core/java/com/android/server/display/plugin/Plugin.java
new file mode 100644
index 000000000000..1bef4641b9ad
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/Plugin.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin;
+
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+import java.io.PrintWriter;
+
+/**
+ * Interface that OEMs should implement in order to inject custom code to system process.
+ * Communication between OEM Plugin and Framework is implemented via {@link PluginStorage}.
+ * OEM Plugin pushes values to PluginStorage, that are picked up by
+ * {@link PluginManager.PluginChangeListener}, implemented on Framework side.
+ * Avoid calling heavy operations in constructor - it will be called during boot and will
+ * negatively impact boot time. Use onBootComplete and separate thread for long running operations.
+ */
+@KeepForApi
+public interface Plugin {
+
+ /**
+ * Called when device boot completed
+ */
+ void onBootCompleted();
+
+ /**
+ * Print the object's state and debug information into the given stream.
+ */
+ void dump(PrintWriter pw);
+}
+
diff --git a/services/core/java/com/android/server/display/plugin/PluginManager.java b/services/core/java/com/android/server/display/plugin/PluginManager.java
new file mode 100644
index 000000000000..d4099975cafa
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginManager.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.SystemServerClassLoaderFactory;
+import com.android.server.display.feature.DisplayManagerFlags;
+
+import dalvik.system.PathClassLoader;
+
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Responsible for loading Plugins. Plugins and PluginSupplier are loaded from
+ * standalone system jar.
+ * Plugin manager will look for PROVIDER_IMPL_CLASS in configured jar.
+ * After device booted, PluginManager will delegate this call to each Plugin
+ */
+public class PluginManager {
+ private static final String PROVIDER_IMPL_CLASS =
+ "com.android.server.display.plugin.PluginsProviderImpl";
+ private static final String TAG = "PluginManager";
+
+ private final DisplayManagerFlags mFlags;
+ private final PluginStorage mPluginStorage;
+ private final List<Plugin> mPlugins;
+
+ public PluginManager(Context context, DisplayManagerFlags flags) {
+ this(context, flags, new Injector());
+ }
+
+ @VisibleForTesting
+ PluginManager(Context context, DisplayManagerFlags flags, Injector injector) {
+ mFlags = flags;
+ mPluginStorage = injector.getPluginStorage();
+ if (mFlags.isPluginManagerEnabled()) {
+ mPlugins = Collections.unmodifiableList(injector.loadPlugins(context, mPluginStorage));
+ Slog.d(TAG, "loaded Plugins:" + mPlugins);
+ } else {
+ mPlugins = List.of();
+ Slog.d(TAG, "PluginManager disabled");
+ }
+ }
+
+ /**
+ * Forwards boot completed event to Plugins
+ */
+ public void onBootCompleted() {
+ mPlugins.forEach(Plugin::onBootCompleted);
+ }
+
+ /**
+ * Adds change listener for particular plugin type
+ */
+ public <T> void subscribe(PluginType<T> type, PluginChangeListener<T> listener) {
+ mPluginStorage.addListener(type, listener);
+ }
+
+ /**
+ * Removes change listener
+ */
+ public <T> void unsubscribe(PluginType<T> type, PluginChangeListener<T> listener) {
+ mPluginStorage.removeListener(type, listener);
+ }
+
+ /**
+ * Print the object's state and debug information into the given stream.
+ */
+ public void dump(PrintWriter pw) {
+ pw.println("PluginManager:");
+ mPluginStorage.dump(pw);
+ for (Plugin plugin : mPlugins) {
+ plugin.dump(pw);
+ }
+ }
+
+ /**
+ * Listens for changes in PluginStorage for a particular type
+ * @param <T> plugin value type
+ */
+ public interface PluginChangeListener<T> {
+ /**
+ * Called when Plugin value changed
+ */
+ void onChanged(@Nullable T value);
+ }
+
+ static class Injector {
+ PluginStorage getPluginStorage() {
+ return new PluginStorage();
+ }
+
+ List<Plugin> loadPlugins(Context context, PluginStorage storage) {
+ String providerJarPath = context
+ .getString(com.android.internal.R.string.config_pluginsProviderJarPath);
+ Slog.d(TAG, "loading plugins from:" + providerJarPath);
+ if (TextUtils.isEmpty(providerJarPath)) {
+ return List.of();
+ }
+ try {
+ PathClassLoader pathClassLoader =
+ SystemServerClassLoaderFactory.getOrCreateClassLoader(
+ providerJarPath, getClass().getClassLoader(), false);
+ @SuppressWarnings("PrivateApi")
+ Class<? extends PluginsProvider> cp = pathClassLoader.loadClass(PROVIDER_IMPL_CLASS)
+ .asSubclass(PluginsProvider.class);
+ PluginsProvider provider = cp.getDeclaredConstructor().newInstance();
+ return provider.getPlugins(context, storage);
+ } catch (ClassNotFoundException e) {
+ Slog.e(TAG, "loading failed: " + PROVIDER_IMPL_CLASS + " is not found in"
+ + providerJarPath, e);
+ } catch (InvocationTargetException | InstantiationException | IllegalAccessException
+ | NoSuchMethodException e) {
+ Slog.e(TAG, "Class instantiation failed", e);
+ }
+ return List.of();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginStorage.java b/services/core/java/com/android/server/display/plugin/PluginStorage.java
new file mode 100644
index 000000000000..2bcea777e681
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginStorage.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin;
+
+import android.annotation.Nullable;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Stores values pushed by Plugins and forwards them to corresponding listener.
+ */
+public class PluginStorage {
+ private static final String TAG = "PluginStorage";
+
+ private final Object mLock = new Object();
+ @GuardedBy("mLock")
+ private final Map<PluginType<?>, Object> mValues = new HashMap<>();
+ @GuardedBy("mLock")
+ private final Map<PluginType<?>, ListenersContainer<?>> mListeners = new HashMap<>();
+
+ /**
+ * Updates value in storage and forwards it to corresponding listeners.
+ * Should be called by OEM Plugin implementation in order to provide communicate with Framework
+ */
+ @KeepForApi
+ public <T> void updateValue(PluginType<T> type, @Nullable T value) {
+ Slog.d(TAG, "updateValue, type=" + type.mName + "; value=" + value);
+ Set<PluginManager.PluginChangeListener<T>> localListeners;
+ synchronized (mLock) {
+ mValues.put(type, value);
+ ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
+ localListeners = new LinkedHashSet<>(container.mListeners);
+ }
+ Slog.d(TAG, "updateValue, notifying listeners=" + localListeners);
+ localListeners.forEach(l -> l.onChanged(value));
+ }
+
+ /**
+ * Adds listener for PluginType. If storage already has value for this type, listener will
+ * be notified immediately.
+ */
+ <T> void addListener(PluginType<T> type, PluginManager.PluginChangeListener<T> listener) {
+ T value = null;
+ synchronized (mLock) {
+ ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
+ if (container.mListeners.add(listener)) {
+ value = getValueForTypeLocked(type);
+ }
+ }
+ if (value != null) {
+ listener.onChanged(value);
+ }
+ }
+
+ /**
+ * Removes listener
+ */
+ <T> void removeListener(PluginType<T> type, PluginManager.PluginChangeListener<T> listener) {
+ synchronized (mLock) {
+ ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
+ container.mListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Print the object's state and debug information into the given stream.
+ */
+ void dump(PrintWriter pw) {
+ Map<PluginType<?>, Object> localValues;
+ @SuppressWarnings("rawtypes")
+ Map<PluginType, Set> localListeners = new HashMap<>();
+ synchronized (mLock) {
+ localValues = new HashMap<>(mValues);
+ mListeners.forEach((type, container) -> localListeners.put(type, container.mListeners));
+ }
+ pw.println("PluginStorage:");
+ pw.println("values=" + localValues);
+ pw.println("listeners=" + localListeners);
+ }
+
+ @GuardedBy("mLock")
+ @SuppressWarnings("unchecked")
+ private <T> T getValueForTypeLocked(PluginType<T> type) {
+ Object value = mValues.get(type);
+ if (value == null) {
+ return null;
+ } else if (type.mType == value.getClass()) {
+ return (T) value;
+ } else {
+ Slog.d(TAG, "getValueForType: unexpected value type=" + value.getClass().getName()
+ + ", expected=" + type.mType.getName());
+ return null;
+ }
+ }
+
+ @GuardedBy("mLock")
+ @SuppressWarnings("unchecked")
+ private <T> ListenersContainer<T> getListenersContainerForTypeLocked(PluginType<T> type) {
+ ListenersContainer<?> container = mListeners.get(type);
+ if (container == null) {
+ ListenersContainer<T> lc = new ListenersContainer<>();
+ mListeners.put(type, lc);
+ return lc;
+ } else {
+ return (ListenersContainer<T>) container;
+ }
+ }
+
+ private static final class ListenersContainer<T> {
+ private final Set<PluginManager.PluginChangeListener<T>> mListeners = new LinkedHashSet<>();
+ }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginType.java b/services/core/java/com/android/server/display/plugin/PluginType.java
new file mode 100644
index 000000000000..fb60833d259e
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginType.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin;
+
+import com.android.internal.annotations.Keep;
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Represent customisation entry point to Framework. OEM and Framework team should define
+ * new PluginTypes together, after that, Framework team can integrate listener and OEM team
+ * create Plugin implementation
+ *
+ * @param <T> type of plugin value
+ */
+@Keep
+public class PluginType<T> {
+
+ final Class<T> mType;
+ final String mName;
+
+ @VisibleForTesting
+ PluginType(Class<T> type, String name) {
+ mType = type;
+ mName = name;
+ }
+
+ @Override
+ public String toString() {
+ return "PluginType{"
+ + "mType=" + mType
+ + ", mName=" + mName
+ + '}';
+ }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginsProvider.java b/services/core/java/com/android/server/display/plugin/PluginsProvider.java
new file mode 100644
index 000000000000..9ad85f67bc8b
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginsProvider.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import com.android.tools.r8.keepanno.annotations.KeepForApi;
+
+import java.util.List;
+
+/**
+ * Interface that OEMs should implement in order to supply Plugins to PluginManager
+ */
+@KeepForApi
+public interface PluginsProvider {
+ /**
+ * Provides list of Plugins to PluginManager
+ */
+ @NonNull
+ List<Plugin> getPlugins(Context context, PluginStorage storage);
+}
diff --git a/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java b/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java
index b0e93989d463..f9a1cebc952f 100644
--- a/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java
+++ b/services/core/java/com/android/server/hdmi/RequestActiveSourceAction.java
@@ -25,8 +25,8 @@ import com.android.internal.annotations.VisibleForTesting;
* Feature action that sends <Request Active Source> message and waits for <Active Source>.
*
* For TV panels, this action has a delay before sending <Request Active Source>. This is because it
- * should wait for a possible request from LauncherX and can be cancelled if an <Active Source>
- * message was received or the TV switched to another input.
+ * should wait for a possible request from LauncherX or TIF (TV Input Framework) and can be
+ * cancelled if an <Active Source> message was received or the TV switched to another input.
*/
public class RequestActiveSourceAction extends HdmiCecFeatureAction {
private static final String TAG = "RequestActiveSourceAction";
@@ -40,9 +40,9 @@ public class RequestActiveSourceAction extends HdmiCecFeatureAction {
// Number of retries <Request Active Source> is sent if no device answers this message.
private static final int MAX_SEND_RETRY_COUNT = 1;
- // Timeout to wait for the LauncherX API call to be completed.
+ // Timeout to wait for LauncherX or TIF to call the CEC API.
@VisibleForTesting
- protected static final int TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS = 10000;
+ protected static final int TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS = 15000;
private int mSendRetryCount = 0;
@@ -67,7 +67,7 @@ public class RequestActiveSourceAction extends HdmiCecFeatureAction {
// We wait for default timeout to allow the message triggered by the LauncherX API call to
// be sent by the TV and another default timeout in case the message has to be answered
// (e.g. TV sent a <Set Stream Path> or <Routing Change>).
- addTimer(mState, TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+ addTimer(mState, TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
return true;
}
diff --git a/services/core/java/com/android/server/input/AppLaunchShortcutManager.java b/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
index f3820e5935d4..8c028bc92841 100644
--- a/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
+++ b/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
@@ -210,16 +210,16 @@ final class AppLaunchShortcutManager {
/**
* Handle the shortcut to {@link IShortcutService}
- * @param keyCode The key code of the event.
- * @param metaState The meta key modifier state.
- * @return True if invoked the shortcut, otherwise false.
+ * @return true if invoked the shortcut, otherwise false.
*/
- private boolean handleShortcutService(int keyCode, int metaState) {
- final long shortcutCodeMeta = metaState & SHORTCUT_CODE_META_MASK;
+ public boolean handleShortcutService(KeyEvent event) {
+ // TODO(b/358569822): Ideally shortcut service custom shortcuts should be either
+ // migrated to bookmarks or customizable shortcut APIs.
+ final long shortcutCodeMeta = event.getMetaState() & SHORTCUT_CODE_META_MASK;
if (shortcutCodeMeta == 0) {
return false;
}
- long shortcutCode = keyCode | (shortcutCodeMeta << Integer.SIZE);
+ long shortcutCode = event.getKeyCode() | (shortcutCodeMeta << Integer.SIZE);
IShortcutService shortcutService = mShortcutKeyServices.get(shortcutCode);
if (shortcutService != null) {
try {
@@ -292,7 +292,6 @@ final class AppLaunchShortcutManager {
return InterceptKeyResult.DO_NOTHING;
}
- final int metaState = event.getModifiers();
final int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
@@ -313,15 +312,7 @@ final class AppLaunchShortcutManager {
}
// Intercept shortcuts defined in bookmarks or through application launch keycodes
- AppLaunchData appLaunchData = interceptShortcut(event);
-
- // TODO(b/358569822): Ideally shortcut service custom shortcuts should be either
- // migrated to bookmarks or customizable shortcut APIs.
- if (appLaunchData == null && handleShortcutService(keyCode, metaState)) {
- return InterceptKeyResult.CONSUME_KEY;
- }
-
- return new InterceptKeyResult(/* consumed =*/ false, appLaunchData);
+ return new InterceptKeyResult(/* consumed =*/ false, interceptShortcut(event));
}
/**
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index edad2473061c..1adf1c99024a 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -19,6 +19,7 @@ package com.android.server.input;
import static android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW;
import static android.content.PermissionChecker.PERMISSION_GRANTED;
import static android.content.PermissionChecker.PID_UNKNOWN;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.provider.DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -136,6 +137,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
+import com.android.server.SystemService;
import com.android.server.Watchdog;
import com.android.server.input.InputManagerInternal.LidSwitchCallback;
import com.android.server.input.debug.FocusEventDebugView;
@@ -3031,6 +3033,19 @@ public class InputManagerService extends IInputManager.Stub
return mKeyGestureController.getAppLaunchBookmarks();
}
+ @Override
+ public void resetLockedModifierState() {
+ mNative.resetLockedModifierState();
+ }
+
+ private void onUserSwitching(@NonNull SystemService.TargetUser from,
+ @NonNull SystemService.TargetUser to) {
+ if (DEBUG) {
+ Slog.d(TAG, "onUserSwitching from=" + from + " to=" + to);
+ }
+ mHandler.obtainMessage(MSG_CURRENT_USER_CHANGED, to.getUserIdentifier()).sendToTarget();
+ }
+
private void handleCurrentUserChanged(@UserIdInt int userId) {
mCurrentUserId = userId;
mKeyGestureController.setCurrentUserId(userId);
@@ -3391,6 +3406,42 @@ public class InputManagerService extends IInputManager.Stub
}
}
+ /**
+ * {@link SystemService} used to publish and manage the lifecycle of {@link InputManagerService}
+ */
+ public static final class Lifecycle extends SystemService {
+
+ private final InputManagerService mService;
+
+ public Lifecycle(@NonNull Context context) {
+ super(context);
+ mService = new InputManagerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.INPUT_SERVICE, mService,
+ /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ // Called on ActivityManager thread.
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+ mService.systemRunning();
+ }
+ }
+
+ @Override
+ public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+ mService.onUserSwitching(from, to);
+ }
+
+ public InputManagerService getService() {
+ return mService;
+ }
+ }
+
private final class LocalService extends InputManagerInternal {
@Override
public void setDisplayViewports(List<DisplayViewport> viewports) {
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 420db9041dc2..3b2305cec9db 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -117,7 +117,10 @@ class InputSettingsObserver extends ContentObserver {
Map.entry(Settings.System.getUriFor(Settings.System.POINTER_STROKE_STYLE),
(reason) -> updatePointerStrokeStyleFromSettings()),
Map.entry(Settings.System.getUriFor(Settings.System.POINTER_SCALE),
- (reason) -> updatePointerScaleFromSettings()));
+ (reason) -> updatePointerScaleFromSettings()),
+ Map.entry(Settings.System.getUriFor(
+ Settings.System.TOUCHPAD_THREE_FINGER_TAP_CUSTOMIZATION),
+ (reason) -> updateTouchpadThreeFingerTapShortcutEnabled()));
}
/**
@@ -143,10 +146,6 @@ class InputSettingsObserver extends ContentObserver {
observer.accept("just booted");
}
- // TODO(b/365063048): add an entry to mObservers that calls this instead, once we have a
- // setting that can be observed.
- updateTouchpadThreeFingerTapShortcutEnabled();
-
configureUserActivityPokeInterval();
}
diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java
index 98330163a693..5bc08a0ff85d 100644
--- a/services/core/java/com/android/server/input/InputShellCommand.java
+++ b/services/core/java/com/android/server/input/InputShellCommand.java
@@ -475,6 +475,7 @@ public class InputShellCommand extends ShellCommand {
}
}
}
+ event = KeyEvent.changeTimeRepeat(event, SystemClock.uptimeMillis(), 0);
injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP), async);
}
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index bb0b19009962..55d2de2b6865 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -793,6 +793,11 @@ final class KeyGestureController {
return true;
}
+ // Handle shortcuts through shortcut services
+ if (mAppLaunchShortcutManager.handleShortcutService(event)) {
+ return true;
+ }
+
// Handle custom shortcuts
if (firstDown) {
InputGestureData customGesture;
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 8903c27b491a..728e44062e82 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -98,6 +98,8 @@ interface NativeInputManagerService {
void toggleCapsLock(int deviceId);
+ void resetLockedModifierState();
+
void displayRemoved(int displayId);
void setInputDispatchMode(boolean enabled, boolean frozen);
@@ -370,6 +372,9 @@ interface NativeInputManagerService {
public native void toggleCapsLock(int deviceId);
@Override
+ public native void resetLockedModifierState();
+
+ @Override
public native void displayRemoved(int displayId);
@Override
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d8483f721306..b7af9a4b17bd 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1310,7 +1310,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// Do not reset the default (current) IME when it is a 3rd-party IME
String selectedMethodId = bindingController.getSelectedMethodId();
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- if (selectedMethodId != null
+ if (selectedMethodId != null && settings.getMethodMap().get(selectedMethodId) != null
&& !settings.getMethodMap().get(selectedMethodId).isSystem()) {
return;
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java
index 0fdd0ae641df..5248a051404d 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java
@@ -237,15 +237,16 @@ import java.util.function.Consumer;
if (message.isBroadcastMessage()) {
if (message.isReliable()) {
- Log.e(TAG, "Received reliable broadcast message from " + message.getNanoAppId());
+ Log.e(TAG, "Received reliable broadcast message from 0x"
+ + Long.toHexString(message.getNanoAppId()));
return ErrorCode.PERMANENT_ERROR;
}
// Broadcast messages shouldn't be sent with any permissions tagged per CHRE API
// requirements.
if (!messagePermissions.isEmpty()) {
- Log.e(TAG, "Received broadcast message with permissions from "
- + message.getNanoAppId());
+ Log.e(TAG, "Received broadcast message with permissions from 0x"
+ + Long.toHexString(message.getNanoAppId()));
return ErrorCode.PERMANENT_ERROR;
}
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 946e89604553..76049ca824c2 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -325,9 +325,16 @@ public class ContextHubService extends IContextHubService.Stub {
return;
}
- if (Flags.offloadApi()) {
- mHubInfoRegistry = new HubInfoRegistry(mContextHubWrapper);
- Log.i(TAG, "Enabling generic offload API");
+ if (Flags.offloadApi() && Flags.offloadImplementation()) {
+ HubInfoRegistry registry;
+ try {
+ registry = new HubInfoRegistry(mContextHubWrapper);
+ Log.i(TAG, "Enabling generic offload API");
+ } catch (UnsupportedOperationException e) {
+ registry = null;
+ Log.w(TAG, "Generic offload API not supported, disabling");
+ }
+ mHubInfoRegistry = registry;
} else {
mHubInfoRegistry = null;
Log.i(TAG, "Disabling generic offload API");
@@ -520,8 +527,8 @@ public class ContextHubService extends IContextHubService.Stub {
try {
mContextHubWrapper.registerEndpointCallback(
new ContextHubHalEndpointCallback(mHubInfoRegistry));
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException while registering IEndpointCallback", e);
+ } catch (RemoteException | UnsupportedOperationException e) {
+ Log.e(TAG, "Exception while registering IEndpointCallback", e);
}
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index fce008c23350..df5ecf872df4 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -1006,9 +1006,9 @@ public final class MediaProjectionManagerService extends SystemService
// Host app has 5 minutes to begin using the token before it is invalid.
// Some apps show a dialog for the user to interact with (selecting recording resolution)
// before starting capture, but after requesting consent.
- final long mDefaultTimeoutMs = Duration.ofMinutes(5).toMillis();
+ final long mDefaultTimeoutMillis = Duration.ofMinutes(5).toMillis();
// The creation timestamp in milliseconds, measured by {@link SystemClock#uptimeMillis}.
- private final long mCreateTimeMs;
+ private final long mCreateTimeMillis;
public final int uid;
public final String packageName;
public final UserHandle userHandle;
@@ -1017,7 +1017,7 @@ public final class MediaProjectionManagerService extends SystemService
private final int mType;
// Values for tracking token validity.
// Timeout value to compare creation time against.
- private final long mTimeoutMs = mDefaultTimeoutMs;
+ private final long mTimeoutMillis = mDefaultTimeoutMillis;
private final int mDisplayId;
private IMediaProjectionCallback mCallback;
@@ -1048,7 +1048,7 @@ public final class MediaProjectionManagerService extends SystemService
userHandle = new UserHandle(UserHandle.getUserId(uid));
mTargetSdkVersion = targetSdkVersion;
mIsPrivileged = isPrivileged;
- mCreateTimeMs = mClock.uptimeMillis();
+ mCreateTimeMillis = mClock.uptimeMillis();
mActivityManagerInternal.notifyMediaProjectionEvent(uid, asBinder(),
MEDIA_PROJECTION_TOKEN_EVENT_CREATED);
mDisplayId = displayId;
@@ -1209,7 +1209,7 @@ public final class MediaProjectionManagerService extends SystemService
}
}
Slog.d(TAG, "Content Recording: handling stopping this projection token"
- + " createTime= " + mCreateTimeMs
+ + " createTime= " + mCreateTimeMillis
+ " countStarts= " + mCountStarts);
stopProjectionLocked(this);
mToken.unlinkToDeath(mDeathEater, 0);
@@ -1273,7 +1273,7 @@ public final class MediaProjectionManagerService extends SystemService
}
long getCreateTimeMillis() {
- return mCreateTimeMs;
+ return mCreateTimeMillis;
}
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@@ -1281,8 +1281,8 @@ public final class MediaProjectionManagerService extends SystemService
public boolean isValid() {
isValid_enforcePermission();
synchronized (mLock) {
- final long curMs = mClock.uptimeMillis();
- final boolean hasTimedOut = curMs - mCreateTimeMs > mTimeoutMs;
+ final long curMillis = mClock.uptimeMillis();
+ final boolean hasTimedOut = curMillis - mCreateTimeMillis > mTimeoutMillis;
final boolean virtualDisplayCreated = mVirtualDisplayId != INVALID_DISPLAY;
final boolean isValid =
!hasTimedOut && (mCountStarts <= 1) && !virtualDisplayCreated;
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index 00bab8af44f3..c7e00d3cbb24 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -28,6 +28,7 @@ import android.media.quality.ISoundProfileCallback;
import android.media.quality.MediaQualityContract;
import android.media.quality.ParamCapability;
import android.media.quality.PictureProfile;
+import android.media.quality.PictureProfileHandle;
import android.media.quality.SoundProfile;
import android.os.PersistableBundle;
import android.util.Log;
@@ -249,6 +250,11 @@ public class MediaQualityService extends SystemService {
}
@Override
+ public PictureProfileHandle getPictureProfileHandle(String id) {
+ return null;
+ }
+
+ @Override
public SoundProfile createSoundProfile(SoundProfile pp) {
// TODO: implement
return pp;
@@ -352,5 +358,10 @@ public class MediaQualityService extends SystemService {
public boolean isAutoSoundQualityEnabled() {
return false;
}
+
+ @Override
+ public boolean isAmbientBacklightEnabled() {
+ return false;
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 7fd962003ce9..f9145514a4e0 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -755,36 +755,7 @@ public class GroupHelper {
Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild"
+ record);
}
-
- ArrayMap<String, NotificationAttributes> ungrouped =
- mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
- new ArrayMap<>());
- ungrouped.put(record.getKey(), new NotificationAttributes(
- record.getFlags(),
- record.getNotification().getSmallIcon(),
- record.getNotification().color,
- record.getNotification().visibility,
- record.getNotification().getGroupAlertBehavior(),
- record.getChannel().getId()));
- mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
- // Create/update summary and group if >= mAutoGroupAtCount notifications
- // or if aggregate group exists
- boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
- new ArrayMap<>()).isEmpty();
- if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
- if (DEBUG) {
- if (ungrouped.size() >= mAutoGroupAtCount) {
- Log.i(TAG,
- "Found >=" + mAutoGroupAtCount
- + " ungrouped notifications => force grouping");
- } else {
- Log.i(TAG, "Found aggregate summary => force grouping");
- }
- }
- aggregateUngroupedNotifications(fullAggregateGroupKey, sbn.getKey(),
- ungrouped, hasSummary, sectioner.mSummaryId);
- }
-
+ addToUngroupedAndMaybeAggregate(record, fullAggregateGroupKey, sectioner);
return;
}
@@ -815,6 +786,38 @@ public class GroupHelper {
}
}
+ @GuardedBy("mAggregatedNotifications")
+ private void addToUngroupedAndMaybeAggregate(NotificationRecord record,
+ FullyQualifiedGroupKey fullAggregateGroupKey, NotificationSectioner sectioner) {
+ ArrayMap<String, NotificationAttributes> ungrouped =
+ mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
+ new ArrayMap<>());
+ ungrouped.put(record.getKey(), new NotificationAttributes(
+ record.getFlags(),
+ record.getNotification().getSmallIcon(),
+ record.getNotification().color,
+ record.getNotification().visibility,
+ record.getNotification().getGroupAlertBehavior(),
+ record.getChannel().getId()));
+ mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+ // Create/update summary and group if >= mAutoGroupAtCount notifications
+ // or if aggregate group exists
+ boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
+ new ArrayMap<>()).isEmpty();
+ if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
+ if (DEBUG) {
+ if (ungrouped.size() >= mAutoGroupAtCount) {
+ Slog.i(TAG, "Found >=" + mAutoGroupAtCount
+ + " ungrouped notifications => force grouping");
+ } else {
+ Slog.i(TAG, "Found aggregate summary => force grouping");
+ }
+ }
+ aggregateUngroupedNotifications(fullAggregateGroupKey, record.getKey(),
+ ungrouped, hasSummary, sectioner.mSummaryId);
+ }
+ }
+
private static boolean isGroupChildBundled(final NotificationRecord record,
final Map<String, NotificationRecord> summaryByGroupKey) {
final StatusBarNotification sbn = record.getSbn();
@@ -897,6 +900,73 @@ public class GroupHelper {
}
}
+ /**
+ * Called when a child notification is removed, after some delay, so that this helper can
+ * trigger a forced grouping if the group has become sparse/singleton
+ * or only the summary is left.
+ *
+ * see also {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+ *
+ * @param summaryRecord the group summary of the notification that was removed
+ * @param notificationList the full notification list from NotificationManagerService
+ * @param summaryByGroupKey the map of group summaries from NotificationManagerService
+ */
+ @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+ protected void onGroupedNotificationRemovedWithDelay(final NotificationRecord summaryRecord,
+ final List<NotificationRecord> notificationList,
+ final Map<String, NotificationRecord> summaryByGroupKey) {
+ final StatusBarNotification sbn = summaryRecord.getSbn();
+ if (!sbn.isAppGroup()) {
+ return;
+ }
+
+ if (summaryRecord.isCanceled) {
+ return;
+ }
+
+ if (mIsTestHarnessExempted) {
+ return;
+ }
+
+ final NotificationSectioner sectioner = getSection(summaryRecord);
+ if (sectioner == null) {
+ if (DEBUG) {
+ Slog.i(TAG,
+ "Skipping autogrouping for " + summaryRecord + " no valid section found.");
+ }
+ return;
+ }
+
+ final String pkgName = sbn.getPackageName();
+ final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+ summaryRecord.getUserId(), pkgName, sectioner);
+
+ // This notification is already aggregated
+ if (summaryRecord.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+ return;
+ }
+
+ synchronized (mAggregatedNotifications) {
+ if (isGroupSummaryWithoutChildren(summaryRecord, notificationList)) {
+ if (DEBUG) {
+ Slog.i(TAG, "isGroupSummaryWithoutChild " + summaryRecord);
+ }
+ addToUngroupedAndMaybeAggregate(summaryRecord, fullAggregateGroupKey, sectioner);
+ return;
+ }
+
+ // Check if notification removal turned this group into a sparse/singleton group
+ if (Flags.notificationForceGroupSingletons()) {
+ try {
+ groupSparseGroups(summaryRecord, notificationList, summaryByGroupKey, sectioner,
+ fullAggregateGroupKey);
+ } catch (Throwable e) {
+ Slog.wtf(TAG, "Failed to group sparse groups", e);
+ }
+ }
+ }
+ }
+
private record NotificationMoveOp(NotificationRecord record, FullyQualifiedGroupKey oldGroup,
FullyQualifiedGroupKey newGroup) { }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5182dfe60fcc..e019267f21cd 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -26,6 +26,7 @@ import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OP_RECEIVE_SENSITIVE_NOTIFICATIONS;
import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR;
import static android.app.Flags.lifetimeExtensionRefactor;
+import static android.app.Flags.notificationClassificationUi;
import static android.app.Flags.sortSectionByTime;
import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
@@ -4225,6 +4226,22 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public @NonNull String[] getTypeAdjustmentDeniedPackages() {
+ checkCallerIsSystemOrSystemUiOrShell();
+ return mAssistants.getTypeAdjustmentDeniedPackages();
+ }
+
+ @Override
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) {
+ checkCallerIsSystemOrSystemUiOrShell();
+ mAssistants.setTypeAdjustmentForPackageState(pkg, enabled);
+
+ handleSavePolicyFile();
+ }
+
+ @Override
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
public boolean appCanBePromoted(String pkg, int uid) {
checkCallerIsSystemOrSystemUiOrShell();
@@ -7006,6 +7023,10 @@ public class NotificationManagerService extends SystemService {
if (notificationClassification() && adjustments.containsKey(KEY_TYPE)) {
if (!mAssistants.isAdjustmentKeyTypeAllowed(adjustments.getInt(KEY_TYPE))) {
toRemove.add(potentialKey);
+ } else if (notificationClassificationUi()
+ && !mAssistants.isTypeAdjustmentAllowedForPackage(
+ r.getSbn().getPackageName())) {
+ toRemove.add(potentialKey);
}
}
}
@@ -10500,6 +10521,27 @@ public class NotificationManagerService extends SystemService {
mGroupHelper.onNotificationRemoved(r, mNotificationList);
}
});
+
+ // Wait 3 seconds so that the app has a chance to cancel/post
+ // a group summary or children
+ final NotificationRecord groupSummary = mSummaryByGroupKey.get(r.getGroupKey());
+ if (groupSummary != null
+ && !GroupHelper.isAggregatedGroup(groupSummary)
+ && !groupSummary.getKey().equals(canceledKey)) {
+ // We only care about app-provided valid group summaries
+ final String summaryKey = groupSummary.getKey();
+ mHandler.removeCallbacksAndEqualMessages(summaryKey);
+ mHandler.postDelayed(() -> {
+ synchronized (mNotificationLock) {
+ NotificationRecord summaryRecord = mNotificationsByKey.get(
+ summaryKey);
+ if (summaryRecord != null) {
+ mGroupHelper.onGroupedNotificationRemovedWithDelay(
+ summaryRecord, mNotificationList, mSummaryByGroupKey);
+ }
+ }
+ }, summaryKey, DELAY_FORCE_REGROUP_TIME);
+ }
} else {
mHandler.post(new Runnable() {
@Override
@@ -11643,6 +11685,7 @@ public class NotificationManagerService extends SystemService {
private static final String ATT_DENIED = "denied_adjustments";
private static final String ATT_ENABLED_TYPES = "enabled_key_types";
private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments";
+ private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps";
private final Object mLock = new Object();
@@ -11658,6 +11701,9 @@ public class NotificationManagerService extends SystemService {
@GuardedBy("mLock")
private Map<Integer, HashSet<String>> mNasUnsupported = new ArrayMap<>();
+ @GuardedBy("mLock")
+ private Set<String> mClassificationTypeDeniedPackages = new ArraySet<>();
+
protected ComponentName mDefaultFromConfig = null;
@Override
@@ -11857,6 +11903,44 @@ public class NotificationManagerService extends SystemService {
}
}
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ protected @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) {
+ synchronized (mLock) {
+ if (notificationClassificationUi()) {
+ return !mClassificationTypeDeniedPackages.contains(pkg);
+ }
+ }
+ return true;
+ }
+
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ protected @NonNull String[] getTypeAdjustmentDeniedPackages() {
+ synchronized (mLock) {
+ if (notificationClassificationUi()) {
+ return mClassificationTypeDeniedPackages.toArray(new String[0]);
+ }
+ }
+ return new String[]{};
+ }
+
+ /**
+ * Set whether a particular package can have its notification channels adjusted to have a
+ * different type by NotificationAssistants.
+ */
+ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) {
+ if (!notificationClassificationUi()) {
+ return;
+ }
+ synchronized (mLock) {
+ if (enabled) {
+ mClassificationTypeDeniedPackages.remove(pkg);
+ } else {
+ mClassificationTypeDeniedPackages.add(pkg);
+ }
+ }
+ }
+
protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
ArrayList<String> keys = new ArrayList<>(records.size());
@@ -11953,8 +12037,10 @@ public class NotificationManagerService extends SystemService {
assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel(),
update);
}
+ } catch (DeadObjectException ex) {
+ Slog.wtf(TAG, "unable to notify assistant (enqueued): " + info, ex);
} catch (RemoteException ex) {
- Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (enqueued): " + info, ex);
}
}
}
@@ -12075,19 +12161,21 @@ public class NotificationManagerService extends SystemService {
r.getSbn(),
r.getNotificationType(),
true /* sameUserOnly */,
- (assistant, sbnToPost) -> {
+ (info, sbnToPost) -> {
try {
if (android.app.Flags.noSbnholder()) {
- assistant.onNotificationSnoozedUntilContextFull(
+ info.onNotificationSnoozedUntilContextFull(
sbnToPost, snoozeCriterionId);
} else {
final StatusBarNotificationHolder sbnHolder =
new StatusBarNotificationHolder(sbnToPost);
- assistant.onNotificationSnoozedUntilContext(
+ info.onNotificationSnoozedUntilContext(
sbnHolder, snoozeCriterionId);
}
+ } catch (DeadObjectException ex) {
+ Slog.wtf(TAG, "unable to notify assistant (snoozed): " + info, ex);
} catch (RemoteException ex) {
- Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex);
+ Slog.e(TAG, "unable to notify assistant (snoozed): " + info, ex);
}
});
}
@@ -12315,6 +12403,12 @@ public class NotificationManagerService extends SystemService {
out.attribute(null, ATT_TYPES,
TextUtils.join(",", mAllowedAdjustmentKeyTypes));
out.endTag(null, ATT_ENABLED_TYPES);
+ if (notificationClassificationUi()) {
+ out.startTag(null, ATT_TYPES_DENIED_APPS);
+ out.attribute(null, ATT_TYPES,
+ TextUtils.join(",", mClassificationTypeDeniedPackages));
+ out.endTag(null, ATT_TYPES_DENIED_APPS);
+ }
}
}
@@ -12346,6 +12440,14 @@ public class NotificationManagerService extends SystemService {
}
}
}
+ } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) {
+ final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES);
+ synchronized (mLock) {
+ mClassificationTypeDeniedPackages.clear();
+ if (!TextUtils.isEmpty(apps)) {
+ mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(",")));
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index e6f784c71ef3..749952e3336f 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -184,6 +184,7 @@ public class PreferencesHelper implements RankingConfig {
private static final boolean DEFAULT_SHOW_BADGE = true;
private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE = false;
+ private static final boolean DEFAULT_CAN_HAVE_PROMOTED_NOTIFS = true;
static final boolean DEFAULT_BUBBLES_ENABLED = true;
@VisibleForTesting
@@ -369,8 +370,8 @@ public class PreferencesHelper implements RankingConfig {
null, ATT_USER_DEMOTED_INVALID_MSG_APP, false);
r.hasSentValidBubble = parser.getAttributeBoolean(null, ATT_SENT_VALID_BUBBLE, false);
if (android.app.Flags.uiRichOngoing()) {
- r.canHavePromotedNotifs =
- parser.getAttributeBoolean(null, ATT_PROMOTE_NOTIFS, false);
+ r.canHavePromotedNotifs = parser.getAttributeBoolean(null, ATT_PROMOTE_NOTIFS,
+ DEFAULT_CAN_HAVE_PROMOTED_NOTIFS);
}
final int innerDepth = parser.getDepth();
@@ -748,7 +749,7 @@ public class PreferencesHelper implements RankingConfig {
r.userDemotedMsgApp);
out.attributeBoolean(null, ATT_SENT_VALID_BUBBLE, r.hasSentValidBubble);
if (android.app.Flags.uiRichOngoing()) {
- if (r.canHavePromotedNotifs) {
+ if (r.canHavePromotedNotifs != DEFAULT_CAN_HAVE_PROMOTED_NOTIFS) {
out.attributeBoolean(null, ATT_PROMOTE_NOTIFS, r.canHavePromotedNotifs);
}
}
@@ -2331,7 +2332,8 @@ public class PreferencesHelper implements RankingConfig {
pw.print(" fixedImportance=");
pw.print(r.fixedImportance);
}
- if (android.app.Flags.uiRichOngoing() && r.canHavePromotedNotifs) {
+ if (android.app.Flags.uiRichOngoing()
+ && r.canHavePromotedNotifs != DEFAULT_CAN_HAVE_PROMOTED_NOTIFS) {
pw.print(" promoted=");
pw.print(r.canHavePromotedNotifs);
}
@@ -3184,7 +3186,8 @@ public class PreferencesHelper implements RankingConfig {
long creationTime;
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
- boolean canHavePromotedNotifs = false;
+ // Until we enable the UI, we should return false.
+ boolean canHavePromotedNotifs = android.app.Flags.uiRichOngoing();
@UserIdInt int userId;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 81dc38a02191..dc173b124884 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1941,7 +1941,17 @@ public class ZenModeHelper {
@Nullable
public Policy getNotificationPolicy(UserHandle user) {
synchronized (mConfigLock) {
- return getNotificationPolicy(getConfigLocked(user));
+ if (Flags.modesMultiuser()) {
+ // Return a fallback (default) policy for users without a zen config.
+ // Note that zen updates (setPolicy, setFilter) won't be applied, so this is mostly
+ // about preventing NPEs for careless callers.
+ ZenModeConfig config = getConfigLocked(user);
+ return config != null
+ ? getNotificationPolicy(config)
+ : getNotificationPolicy(mDefaultConfig);
+ } else {
+ return getNotificationPolicy(getConfigLocked(user));
+ }
}
}
diff --git a/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java b/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
index b532d5a8f8fc..bef3f8048da1 100644
--- a/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
+++ b/services/core/java/com/android/server/ondeviceintelligence/InferenceInfoStore.java
@@ -20,8 +20,8 @@ import android.app.ondeviceintelligence.InferenceInfo;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
-import android.util.Slog;
import android.util.Base64;
+import android.util.Slog;
import java.io.IOException;
import java.util.Comparator;
@@ -36,12 +36,12 @@ public class InferenceInfoStore {
public InferenceInfoStore(long maxAgeMs) {
this.maxAgeMs = maxAgeMs;
this.inferenceInfos = new TreeSet<>(
- Comparator.comparingLong(InferenceInfo::getStartTimeMs));
+ Comparator.comparingLong(InferenceInfo::getStartTimeMillis));
}
public List<InferenceInfo> getLatestInferenceInfo(long startTimeEpochMillis) {
return inferenceInfos.stream().filter(
- info -> info.getStartTimeMs() > startTimeEpochMillis).toList();
+ info -> info.getStartTimeMillis() > startTimeEpochMillis).toList();
}
public void addInferenceInfoFromBundle(PersistableBundle pb) {
@@ -85,7 +85,7 @@ public class InferenceInfoStore {
private synchronized void add(com.android.server.ondeviceintelligence.nano.InferenceInfo info) {
while (!inferenceInfos.isEmpty()
- && System.currentTimeMillis() - inferenceInfos.first().getStartTimeMs()
+ && System.currentTimeMillis() - inferenceInfos.first().getStartTimeMillis()
> maxAgeMs) {
inferenceInfos.pollFirst();
}
@@ -94,8 +94,8 @@ public class InferenceInfoStore {
private static InferenceInfo toInferenceInfo(
com.android.server.ondeviceintelligence.nano.InferenceInfo info) {
- return new InferenceInfo.Builder().setUid(info.uid).setStartTimeMs(
- info.startTimeMs).setEndTimeMs(info.endTimeMs).setSuspendedTimeMs(
+ return new InferenceInfo.Builder(info.uid).setStartTimeMillis(
+ info.startTimeMs).setEndTimeMillis(info.endTimeMs).setSuspendedTimeMillis(
info.suspendedTimeMs).build();
}
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index e8fc577d9f0f..62b89f3252e6 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -38,19 +38,19 @@ per-file SELinuxMMAC* = alanstokes@google.com, cbrubaker@google.com, jeffv@googl
per-file SaferIntentUtils.java = topjohnwu@google.com
# shortcuts
-per-file LauncherAppsService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShareTargetInfo.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutBitmapSaver.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutDumpFiles.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutLauncher.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutNonPersistentUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutPackage.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutPackageInfo.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutPackageItem.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutParser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
+per-file LauncherAppsService.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShareTargetInfo.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutBitmapSaver.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutDumpFiles.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutLauncher.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutNonPersistentUser.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutPackage.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutPackageInfo.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutPackageItem.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutParser.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutRequestPinProcessor.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutService.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutUser.java = pinyaoting@google.com, sunnygoyal@google.com
# background install control service
-per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS \ No newline at end of file
+per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS
diff --git a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java
index 99eac37b0933..ea37d8e5d3c9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java
@@ -79,8 +79,6 @@ public final class PackageInstallerHistoricalSession {
private final String mSessionErrorMessage;
private final String mPreVerifiedDomains;
private final String mPackageName;
- private final int mInitialVerificationPolicy;
- private final int mCurrentVerificationPolicy;
PackageInstallerHistoricalSession(int sessionId, int userId, int originalInstallerUid,
String originalInstallerPackageName, InstallSource installSource, int installerUid,
@@ -92,8 +90,7 @@ public final class PackageInstallerHistoricalSession {
int[] childSessionIds, boolean sessionApplied, boolean sessionFailed,
boolean sessionReady, int sessionErrorCode, String sessionErrorMessage,
PreapprovalDetails preapprovalDetails, DomainSet preVerifiedDomains,
- String packageNameFromApk, int initialVerificationPolicy,
- int currentVerificationPolicy) {
+ String packageNameFromApk) {
this.sessionId = sessionId;
this.userId = userId;
this.mOriginalInstallerUid = originalInstallerUid;
@@ -143,8 +140,6 @@ public final class PackageInstallerHistoricalSession {
this.mPackageName = preapprovalDetails != null ? preapprovalDetails.getPackageName()
: packageNameFromApk != null ? packageNameFromApk : params.appPackageName;
- this.mInitialVerificationPolicy = initialVerificationPolicy;
- this.mCurrentVerificationPolicy = currentVerificationPolicy;
}
void dump(IndentingPrintWriter pw) {
@@ -189,8 +184,6 @@ public final class PackageInstallerHistoricalSession {
pw.printPair("mPreapprovalDetails", mPreapprovalDetails);
pw.printPair("mPreVerifiedDomains", mPreVerifiedDomains);
pw.printPair("mAppPackageName", mPackageName);
- pw.printPair("mInitialVerificationPolicy", mInitialVerificationPolicy);
- pw.printPair("mCurrentVerificationPolicy", mCurrentVerificationPolicy);
pw.println();
pw.decreaseIndent();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 9b44f93467ed..a4152a724d64 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -25,22 +25,18 @@ import static android.content.pm.PackageInstaller.UNARCHIVAL_ERROR_NO_CONNECTIVI
import static android.content.pm.PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED;
import static android.content.pm.PackageInstaller.UNARCHIVAL_GENERIC_ERROR;
import static android.content.pm.PackageInstaller.UNARCHIVAL_OK;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_WARN;
import static android.content.pm.PackageManager.DELETE_ARCHIVE;
import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
-import static android.os.UserHandle.USER_SYSTEM;
import static com.android.server.pm.PackageArchiver.isArchivingEnabled;
-import static com.android.server.pm.PackageInstallerSession.isValidVerificationPolicy;
import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.Manifest;
-import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -89,7 +85,6 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelableException;
-import android.os.PermissionEnforcer;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
@@ -131,7 +126,6 @@ import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.utils.RequestThrottle;
-import com.android.server.pm.verify.pkg.VerifierController;
import libcore.io.IoUtils;
@@ -219,7 +213,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
private final StagingManager mStagingManager;
private AppOpsManager mAppOps;
- private final VerifierController mVerifierController;
private final InstallDependencyHelper mInstallDependencyHelper;
private final HandlerThread mInstallThread;
@@ -281,14 +274,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
};
- /**
- * Default verification policy for incoming installation sessions, mapped from userId to policy.
- */
- @GuardedBy("mVerificationPolicyPerUser")
- private final SparseIntArray mVerificationPolicyPerUser = new SparseIntArray(1);
- // TODO(b/360129657): update the default policy.
- private static final int DEFAULT_VERIFICATION_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-
private static final class Lifecycle extends SystemService {
private final PackageInstallerService mPackageInstallerService;
@@ -318,8 +303,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
public PackageInstallerService(Context context, PackageManagerService pm,
Supplier<PackageParser2> apexParserSupplier) {
- super(PermissionEnforcer.fromContext(context));
-
mContext = context;
mPm = pm;
@@ -343,10 +326,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
mGentleUpdateHelper = new GentleUpdateHelper(
context, mInstallThread.getLooper(), new AppStateHelper(context));
mPackageArchiver = new PackageArchiver(mContext, mPm);
- mVerifierController = new VerifierController(mContext, mInstallHandler);
- synchronized (mVerificationPolicyPerUser) {
- mVerificationPolicyPerUser.put(USER_SYSTEM, DEFAULT_VERIFICATION_POLICY);
- }
mInstallDependencyHelper = new InstallDependencyHelper(mContext,
mPm.mInjector.getSharedLibrariesImpl());
@@ -546,7 +525,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
session = PackageInstallerSession.readFromXml(in, mInternalCallback,
mContext, mPm, mInstallThread.getLooper(), mStagingManager,
mSessionsDir, this, mSilentUpdatePolicy,
- mVerifierController, mInstallDependencyHelper);
+ mInstallDependencyHelper);
} catch (Exception e) {
Slog.e(TAG, "Could not read session", e);
continue;
@@ -1058,17 +1037,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
InstallSource installSource = InstallSource.create(installerPackageName,
originatingPackageName, requestedInstallerPackageName, requestedInstallerPackageUid,
requestedInstallerPackageName, installerAttributionTag, params.packageSource);
- final int verificationPolicy;
- synchronized (mVerificationPolicyPerUser) {
- verificationPolicy = mVerificationPolicyPerUser.get(
- userId, DEFAULT_VERIFICATION_POLICY);
- }
session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
mSilentUpdatePolicy, mInstallThread.getLooper(), mStagingManager, sessionId,
userId, callingUid, installSource, params, createdMillis, 0L, stageDir, stageCid,
null, null, false, false, false, false, null, SessionInfo.INVALID_ID,
false, false, false, PackageManager.INSTALL_UNKNOWN, "", null,
- mVerifierController, verificationPolicy, verificationPolicy,
mInstallDependencyHelper);
synchronized (mSessions) {
@@ -1079,7 +1052,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
mCallbacks.notifySessionCreated(session.sessionId, session.userId);
mSettingsWriteRequest.schedule();
-
if (LOGD) {
Slog.d(TAG, "Created session id=" + sessionId + " staged=" + params.isStaged);
}
@@ -1893,58 +1865,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
}
- @Override
- @EnforcePermission(android.Manifest.permission.VERIFICATION_AGENT)
- public @PackageInstaller.VerificationPolicy int getVerificationPolicy(int userId) {
- getVerificationPolicy_enforcePermission();
- synchronized (mVerificationPolicyPerUser) {
- if (mVerificationPolicyPerUser.indexOfKey(userId) < 0) {
- throw new IllegalStateException(
- "Verification policy for user " + userId + " does not exist."
- + " Does the user exist?");
- }
- return mVerificationPolicyPerUser.get(userId);
- }
- }
-
- @Override
- @EnforcePermission(android.Manifest.permission.VERIFICATION_AGENT)
- public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy,
- int userId) {
- setVerificationPolicy_enforcePermission();
- final int callingUid = getCallingUid();
- // Only the verifier currently bound by the system can change the policy, except for Shell
- if (!PackageManagerServiceUtils.isRootOrShell(callingUid)) {
- mVerifierController.assertCallerIsCurrentVerifier(callingUid);
- }
- if (!isValidVerificationPolicy(policy)) {
- return false;
- }
- synchronized (mVerificationPolicyPerUser) {
- if (mVerificationPolicyPerUser.indexOfKey(userId) < 0) {
- throw new IllegalStateException(
- "Verification policy for user " + userId + " does not exist."
- + " Does the user exist?");
- }
- if (policy != mVerificationPolicyPerUser.get(userId)) {
- mVerificationPolicyPerUser.put(userId, policy);
- }
- }
- return true;
- }
-
- void onUserAdded(int userId) {
- synchronized (mVerificationPolicyPerUser) {
- mVerificationPolicyPerUser.put(userId, DEFAULT_VERIFICATION_POLICY);
- }
- }
-
- void onUserRemoved(int userId) {
- synchronized (mVerificationPolicyPerUser) {
- mVerificationPolicyPerUser.delete(userId);
- }
- }
-
private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
int installerUid) {
int count = 0;
@@ -2341,9 +2261,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
mSilentUpdatePolicy.dump(pw);
mGentleUpdateHelper.dump(pw);
- synchronized (mVerificationPolicyPerUser) {
- pw.printPair("VerificationPolicyPerUser", mVerificationPolicyPerUser.toString());
- }
}
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 505b7e6205df..8f8802e66004 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -21,17 +21,9 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_INSTA
import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_UPDATED_BY_DO;
import static android.content.pm.DataLoaderType.INCREMENTAL;
import static android.content.pm.DataLoaderType.STREAMING;
-import static android.content.pm.PackageInstaller.EXTRA_VERIFICATION_FAILURE_REASON;
import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageInstaller.UNARCHIVAL_OK;
import static android.content.pm.PackageInstaller.UNARCHIVAL_STATUS_UNSET;
-import static android.content.pm.PackageInstaller.VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE;
-import static android.content.pm.PackageInstaller.VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED;
-import static android.content.pm.PackageInstaller.VERIFICATION_FAILED_REASON_UNKNOWN;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_OPEN;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_WARN;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_NONE;
import static android.content.pm.PackageItemInfo.MAX_SAFE_LABEL_LENGTH;
import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE;
@@ -46,7 +38,6 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_VERIFICATION_FAIL
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
-import static android.content.pm.verify.pkg.VerificationSession.VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE;
import static android.os.Process.INVALID_UID;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
import static android.system.OsConstants.O_CREAT;
@@ -117,9 +108,7 @@ import android.content.pm.PackageInstaller.UserActionReason;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.SharedLibraryInfo;
import android.content.pm.SigningDetails;
-import android.content.pm.SigningInfo;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.parsing.ApkLite;
import android.content.pm.parsing.ApkLiteParseUtils;
@@ -127,7 +116,6 @@ import android.content.pm.parsing.PackageLite;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.pm.verify.domain.DomainSet;
-import android.content.pm.verify.pkg.VerificationStatus;
import android.content.res.ApkAssets;
import android.content.res.AssetManager;
import android.content.res.Configuration;
@@ -135,7 +123,6 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.icu.util.ULocale;
-import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -148,7 +135,6 @@ import android.os.Message;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
-import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
@@ -206,7 +192,6 @@ import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.verify.pkg.VerifierController;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
@@ -321,8 +306,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String ATTR_APPLICATION_ENABLED_SETTING_PERSISTENT =
"applicationEnabledSettingPersistent";
private static final String ATTR_DOMAIN = "domain";
- private static final String ATTR_INITIAL_VERIFICATION_POLICY = "initialVerificationPolicy";
- private static final String ATTR_CURRENT_VERIFICATION_POLICY = "currentVerificationPolicy";
private static final String PROPERTY_NAME_INHERIT_NATIVE = "pi.inherit_native_on_dont_kill";
private static final int[] EMPTY_CHILD_SESSION_ARRAY = EmptyArray.INT;
@@ -420,19 +403,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private final PackageSessionProvider mSessionProvider;
private final SilentUpdatePolicy mSilentUpdatePolicy;
/**
- * The initial verification policy assigned to this session when it was first created.
- */
- private final int mInitialVerificationPolicy;
- /**
- * The active verification policy, which might be different from the initial verification policy
- * assigned to this session or the default policy currently used by the system.
- */
- private final AtomicInteger mCurrentVerificationPolicy;
- /**
* Note all calls must be done outside {@link #mLock} to prevent lock inversion.
*/
private final StagingManager mStagingManager;
- @NonNull private final VerifierController mVerifierController;
private final InstallDependencyHelper mInstallDependencyHelper;
@@ -812,8 +785,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (errorMsg != null) {
Slog.e(TAG, "verifySession error: " + errorMsg);
setSessionFailed(INSTALL_FAILED_INTERNAL_ERROR, errorMsg);
- onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR, errorMsg,
- /* extras= */ null);
+ onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR, errorMsg);
return false;
}
return true;
@@ -1092,6 +1064,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
== PackageManager.PERMISSION_GRANTED);
+ boolean isInstallDependencyPackagesPermissionGranted = false;
+ if (Flags.sdkDependencyInstaller()) {
+ isInstallDependencyPackagesPermissionGranted = (snapshot.checkUidPermission(
+ android.Manifest.permission.INSTALL_DEPENDENCY_SHARED_LIBRARIES, mInstallerUid)
+ == PackageManager.PERMISSION_GRANTED);
+ }
// Also query the package uid for archived packages, so that the user confirmation
// dialog can be displayed for updating archived apps.
final int targetPackageUid = snapshot.getPackageUid(packageName,
@@ -1113,10 +1091,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final boolean isSelfUpdate = targetPackageUid == mInstallerUid;
final boolean isEmergencyInstall =
isEmergencyInstallerEnabled(packageName, snapshot, userId, mInstallerUid);
+ boolean isSdkOrStaticLibraryInstall = false;
+ synchronized (mLock) {
+ if (mPackageLite != null) {
+ isSdkOrStaticLibraryInstall =
+ mPackageLite.isIsSdkLibrary() || mPackageLite.isIsStaticLibrary();
+ }
+ }
final boolean isPermissionGranted = isInstallPermissionGranted
|| (isUpdatePermissionGranted && isUpdate)
|| (isSelfUpdatePermissionGranted && isSelfUpdate)
- || (isInstallDpcPackagesPermissionGranted && hasDeviceAdminReceiver);
+ || (isInstallDpcPackagesPermissionGranted && hasDeviceAdminReceiver)
+ || (isInstallDependencyPackagesPermissionGranted && isSdkOrStaticLibraryInstall);
final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
final boolean isInstallerSystem = (mInstallerUid == Process.SYSTEM_UID);
final boolean isInstallerShell = (mInstallerUid == Process.SHELL_UID);
@@ -1189,9 +1175,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@Nullable int[] childSessionIds, int parentSessionId, boolean isReady,
boolean isFailed, boolean isApplied, int sessionErrorCode,
String sessionErrorMessage, DomainSet preVerifiedDomains,
- @NonNull VerifierController verifierController,
- @PackageInstaller.VerificationPolicy int initialVerificationPolicy,
- @PackageInstaller.VerificationPolicy int currentVerificationPolicy,
InstallDependencyHelper installDependencyHelper) {
mCallback = callback;
mContext = context;
@@ -1201,9 +1184,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mSilentUpdatePolicy = silentUpdatePolicy;
mHandler = new Handler(looper, mHandlerCallback);
mStagingManager = stagingManager;
- mVerifierController = verifierController;
- mInitialVerificationPolicy = initialVerificationPolicy;
- mCurrentVerificationPolicy = new AtomicInteger(currentVerificationPolicy);
mInstallDependencyHelper = installDependencyHelper;
this.sessionId = sessionId;
@@ -1289,14 +1269,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Archived installation can only use Streaming System DataLoader.");
}
}
-
- if (shouldUseVerificationService()) {
- // Start binding to the verification service, if not bound already.
- mVerifierController.bindToVerifierServiceIfNeeded(mPm::snapshotComputer, userId);
- if (!TextUtils.isEmpty(params.appPackageName)) {
- mVerifierController.notifyPackageNameAvailable(params.appPackageName);
- }
- }
}
PackageInstallerHistoricalSession createHistoricalSession() {
@@ -1314,8 +1286,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mStageDirInUse, mDestroyed, mFds.size(), mBridges.size(), mFinalStatus,
mFinalMessage, params, mParentSessionId, getChildSessionIdsLocked(),
mSessionApplied, mSessionFailed, mSessionReady, mSessionErrorCode,
- mSessionErrorMessage, mPreapprovalDetails, mPreVerifiedDomains, mPackageName,
- mInitialVerificationPolicy, mCurrentVerificationPolicy.get());
+ mSessionErrorMessage, mPreapprovalDetails, mPreVerifiedDomains, mPackageName);
}
}
@@ -2610,10 +2581,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
dispatchSessionFinished(error, detailMessage, null);
}
- private void onSessionVerificationFailure(int error, String msg, Bundle extras) {
+ private void onSessionVerificationFailure(int error, String msg) {
Slog.e(TAG, "Failed to verify session " + sessionId);
// Dispatch message to remove session from PackageInstallerService.
- dispatchSessionFinished(error, msg, extras);
+ dispatchSessionFinished(error, msg, null);
maybeFinishChildSessions(error, msg);
}
@@ -2893,60 +2864,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
final String errorMsg = PackageManager.installStatusToString(e.error, completeMsg);
setSessionFailed(e.error, errorMsg);
- onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null);
- }
- if (shouldUseVerificationService()) {
- final SigningInfo signingInfo;
- final List<SharedLibraryInfo> declaredLibraries;
- synchronized (mLock) {
- signingInfo = new SigningInfo(mSigningDetails);
- declaredLibraries =
- mPackageLite == null ? null : mPackageLite.getDeclaredLibraries();
- }
- // Send the request to the verifier and wait for its response before the rest of
- // the installation can proceed.
- final VerifierCallback verifierCallback = new VerifierCallback();
- if (!mVerifierController.startVerificationSession(mPm::snapshotComputer, userId,
- sessionId, getPackageName(), Uri.fromFile(stageDir), signingInfo,
- declaredLibraries, mCurrentVerificationPolicy.get(),
- /* extensionParams= */ null, verifierCallback, /* retry= */ false)) {
- // A verifier is installed but cannot be connected.
- verifierCallback.onConnectionFailed();
- }
- } else {
- // No need to check with verifier. Proceed with the rest of the verification.
- resumeVerify();
- }
- }
-
- private boolean shouldUseVerificationService() {
- if (!Flags.verificationService()) {
- // Feature is not enabled.
- return false;
- }
- if ((params.installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
- // adb installs are exempted from verification unless explicitly requested
- if (!params.forceVerification) {
- return false;
- }
- }
- final String verifierPackageName = mVerifierController.getVerifierPackageName(
- mPm::snapshotComputer, userId);
- if (verifierPackageName == null) {
- // Feature is enabled but no verifier installed.
- return false;
+ onSessionVerificationFailure(e.error, errorMsg);
}
- synchronized (mLock) {
- if (verifierPackageName.equals(mPackageName)) {
- // The verifier itself is being updated. Skip.
- Slog.w(TAG, "Skipping verification service because the verifier is being updated");
- return false;
- }
- }
- return true;
- }
- private void resumeVerify() {
if (mVerificationInProgress) {
Slog.w(TAG, "Verification is already in progress for session " + sessionId);
return;
@@ -2975,143 +2895,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
final String errorMsg = PackageManager.installStatusToString(e.error, completeMsg);
setSessionFailed(e.error, errorMsg);
- onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null);
- }
- }
-
- /**
- * Used for the VerifierController to report status back.
- */
- public class VerifierCallback {
- /**
- * Called by the VerifierController when the verifier requests to get the current
- * verification policy for this session.
- */
- public @PackageInstaller.VerificationPolicy int getVerificationPolicy() {
- return mCurrentVerificationPolicy.get();
- }
- /**
- * Called by the VerifierController when the verifier requests to change the verification
- * policy for this session.
- */
- public boolean setVerificationPolicy(@PackageInstaller.VerificationPolicy int policy) {
- if (!isValidVerificationPolicy(policy)) {
- return false;
- }
- mCurrentVerificationPolicy.set(policy);
- return true;
- }
- /**
- * Called by the VerifierController when the connection has failed.
- */
- public void onConnectionFailed() {
- // TODO(b/360129657): prompt user on fail warning
- handleNonPackageBlockedFailure(
- /* onFailWarning= */ PackageInstallerSession.this::resumeVerify,
- /* onFailClosed= */ () -> {
- Bundle bundle = new Bundle();
- bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON,
- VERIFICATION_FAILED_REASON_UNKNOWN);
- onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
- "A verifier agent is available on device but cannot be connected.",
- bundle);
- });
- }
- /**
- * Called by the VerifierController when the verification request has timed out.
- */
- public void onTimeout() {
- // Always notify the verifier, regardless of the policy.
- mVerifierController.notifyVerificationTimeout(sessionId);
- // TODO(b/360129657): prompt user on fail warning
- handleNonPackageBlockedFailure(
- /* onFailWarning= */ PackageInstallerSession.this::resumeVerify,
- /* onFailClosed= */ () -> {
- Bundle bundle = new Bundle();
- bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON,
- VERIFICATION_FAILED_REASON_UNKNOWN);
- onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
- "Verification timed out; missing a response from the verifier"
- + " within the time limit", bundle);
- });
- }
- /**
- * Called by the VerifierController when the verification request has received a complete
- * response.
- */
- public void onVerificationCompleteReceived(@NonNull VerificationStatus statusReceived,
- @Nullable PersistableBundle extensionResponse) {
- // TODO: handle extension response
- mHandler.post(() -> {
- if (statusReceived.isVerified()
- || mCurrentVerificationPolicy.get() == VERIFICATION_POLICY_NONE) {
- // Continue with the rest of the verification and installation.
- resumeVerify();
- return;
- }
- // Package is blocked.
- StringBuilder sb = new StringBuilder("Verifier rejected the installation");
- if (!TextUtils.isEmpty(statusReceived.getFailureMessage())) {
- sb.append(" with message: ").append(statusReceived.getFailureMessage());
- }
- Bundle bundle = new Bundle();
- bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON,
- VERIFICATION_FAILED_REASON_PACKAGE_BLOCKED);
- onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
- sb.toString(), bundle);
- });
- }
- /**
- * Called by the VerifierController when the verification request has received an incomplete
- * response.
- */
- public void onVerificationIncompleteReceived(int incompleteReason) {
- // TODO(b/360129657): prompt user on fail warning
- handleNonPackageBlockedFailure(
- /* onFailWarning= */ PackageInstallerSession.this::resumeVerify,
- /* onFailClosed= */ () -> {
- final int failureReason;
- StringBuilder sb = new StringBuilder(
- "Verification cannot be completed because of ");
- if (incompleteReason == VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE) {
- failureReason = VERIFICATION_FAILED_REASON_NETWORK_UNAVAILABLE;
- sb.append("unavailable network.");
- } else {
- failureReason = VERIFICATION_FAILED_REASON_UNKNOWN;
- sb.append("unknown reasons.");
- }
- Bundle bundle = new Bundle();
- bundle.putInt(EXTRA_VERIFICATION_FAILURE_REASON, failureReason);
- onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
- sb.toString(), bundle);
- });
- }
-
- private void handleNonPackageBlockedFailure(Runnable onFailWarning, Runnable onFailClosed) {
- final Runnable r = switch (mCurrentVerificationPolicy.get()) {
- case VERIFICATION_POLICY_NONE, VERIFICATION_POLICY_BLOCK_FAIL_OPEN ->
- PackageInstallerSession.this::resumeVerify;
- case VERIFICATION_POLICY_BLOCK_FAIL_WARN -> onFailWarning;
- case VERIFICATION_POLICY_BLOCK_FAIL_CLOSED -> onFailClosed;
- default -> {
- Log.wtf(TAG, "Unknown verification policy: "
- + mCurrentVerificationPolicy.get());
- yield onFailClosed;
- }
- };
- mHandler.post(r);
+ onSessionVerificationFailure(e.error, errorMsg);
}
}
- /**
- * Returns whether a policy is a valid verification policy.
- */
- public static boolean isValidVerificationPolicy(
- @PackageInstaller.VerificationPolicy int policy) {
- return policy >= VERIFICATION_POLICY_NONE
- && policy <= VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
- }
-
private IntentSender getRemoteStatusReceiver() {
synchronized (mLock) {
return mRemoteStatusReceiver;
@@ -3287,7 +3074,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (error == INSTALL_SUCCEEDED) {
onVerificationComplete();
} else {
- onSessionVerificationFailure(error, msg, /* extras= */ null);
+ onSessionVerificationFailure(error, msg);
}
});
});
@@ -5486,23 +5273,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- /**
- * @return the initial policy for the verification request assigned to the session when created.
- */
- @VisibleForTesting
- public @PackageInstaller.VerificationPolicy int getInitialVerificationPolicy() {
- assertCallerIsOwnerOrRoot();
- return mInitialVerificationPolicy;
- }
-
- /**
- * @return the current policy for the verification request associated with this session.
- */
- @VisibleForTesting
- public @PackageInstaller.VerificationPolicy int getCurrentVerificationPolicy() {
- assertCallerIsOwnerOrRoot();
- return mCurrentVerificationPolicy.get();
- }
void setSessionReady() {
synchronized (mLock) {
@@ -5673,14 +5443,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
} catch (InstallerException ignored) {
}
- if (shouldUseVerificationService()
- && !TextUtils.isEmpty(params.appPackageName)
- && !isCommitted()) {
- // Only notify for the cancellation if the verification request has not
- // been sent out, which happens right after commit() is called.
- mVerifierController.notifyVerificationCancelled(
- params.appPackageName);
- }
}
void dump(IndentingPrintWriter pw) {
@@ -5741,8 +5503,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (mPreVerifiedDomains != null) {
pw.printPair("mPreVerifiedDomains", mPreVerifiedDomains);
}
- pw.printPair("mInitialVerificationPolicy", mInitialVerificationPolicy);
- pw.printPair("mCurrentVerificationPolicy", mCurrentVerificationPolicy.get());
pw.println();
pw.decreaseIndent();
@@ -5808,10 +5568,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (!ArrayUtils.isEmpty(warnings)) {
fillIn.putStringArrayListExtra(PackageInstaller.EXTRA_WARNINGS, warnings);
}
- if (extras.containsKey(EXTRA_VERIFICATION_FAILURE_REASON)) {
- fillIn.putExtra(EXTRA_VERIFICATION_FAILURE_REASON,
- extras.getInt(EXTRA_VERIFICATION_FAILURE_REASON));
- }
}
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
@@ -5967,9 +5723,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
out.attributeInt(null, ATTR_INSTALL_REASON, params.installReason);
writeBooleanAttribute(out, ATTR_APPLICATION_ENABLED_SETTING_PERSISTENT,
params.applicationEnabledSettingPersistent);
- out.attributeInt(null, ATTR_INITIAL_VERIFICATION_POLICY, mInitialVerificationPolicy);
- out.attributeInt(null, ATTR_CURRENT_VERIFICATION_POLICY,
- mCurrentVerificationPolicy.get());
final boolean isDataLoader = params.dataLoaderParams != null;
writeBooleanAttribute(out, ATTR_IS_DATALOADER, isDataLoader);
@@ -6090,7 +5843,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@NonNull StagingManager stagingManager, @NonNull File sessionsDir,
@NonNull PackageSessionProvider sessionProvider,
@NonNull SilentUpdatePolicy silentUpdatePolicy,
- @NonNull VerifierController verifierController,
@NonNull InstallDependencyHelper installDependencyHelper)
throws IOException, XmlPullParserException {
final int sessionId = in.getAttributeInt(null, ATTR_SESSION_ID);
@@ -6121,10 +5873,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final boolean sealed = in.getAttributeBoolean(null, ATTR_SEALED, false);
final int parentSessionId = in.getAttributeInt(null, ATTR_PARENT_SESSION_ID,
SessionInfo.INVALID_ID);
- final int initialVerificationPolicy = in.getAttributeInt(null,
- ATTR_INITIAL_VERIFICATION_POLICY, VERIFICATION_POLICY_NONE);
- final int currentVerificationPolicy = in.getAttributeInt(null,
- ATTR_CURRENT_VERIFICATION_POLICY, VERIFICATION_POLICY_NONE);
final SessionParams params = new SessionParams(
SessionParams.MODE_INVALID);
@@ -6299,7 +6047,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
installerUid, installSource, params, createdMillis, committedMillis, stageDir,
stageCid, fileArray, checksumsMap, prepared, committed, destroyed, sealed,
childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied,
- sessionErrorCode, sessionErrorMessage, preVerifiedDomains, verifierController,
- initialVerificationPolicy, currentVerificationPolicy, installDependencyHelper);
+ sessionErrorCode, sessionErrorMessage, preVerifiedDomains,
+ installDependencyHelper);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9d48efe954bb..807445ef062d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4421,7 +4421,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mPendingBroadcasts.remove(userId);
mAppsFilter.onUserDeleted(snapshotComputer(), userId);
mPermissionManager.onUserRemoved(userId);
- mInstallerService.onUserRemoved(userId);
}
mInstantAppRegistry.onUserRemoved(userId);
mPackageMonitorCallbackHelper.onUserRemoved(userId);
@@ -4472,7 +4471,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mLegacyPermissionManager.grantDefaultPermissions(userId);
mPermissionManager.setDefaultPermissionGrantFingerprint(Build.FINGERPRINT, userId);
mDomainVerificationManager.clearUser(userId);
- mInstallerService.onUserAdded(userId);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 961b4b3c91e3..aa235c2258ac 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -399,10 +399,6 @@ class PackageManagerShellCommand extends ShellCommand {
return runUnarchive();
case "get-domain-verification-agent":
return runGetDomainVerificationAgent();
- case "get-verification-policy":
- return runGetVerificationPolicy();
- case "set-verification-policy":
- return runSetVerificationPolicy();
default: {
if (ART_SERVICE_COMMANDS.contains(cmd)) {
return runArtServiceCommand();
@@ -3603,12 +3599,9 @@ class PackageManagerShellCommand extends ShellCommand {
.setCompilerFilter(sessionParams.dexoptCompilerFilter)
.build();
break;
- case "--force-verification":
- sessionParams.setForceVerification();
- break;
case "--disable-auto-install-dependencies":
if (Flags.sdkDependencyInstaller()) {
- sessionParams.setEnableAutoInstallDependencies(false);
+ sessionParams.setAutoInstallDependenciesEnabled(false);
} else {
throw new IllegalArgumentException("Unknown option " + opt);
}
@@ -4656,87 +4649,6 @@ class PackageManagerShellCommand extends ShellCommand {
return 0;
}
- private int runGetVerificationPolicy() throws RemoteException {
- final PrintWriter pw = getOutPrintWriter();
- int userId = UserHandle.USER_ALL;
-
- String opt;
- while ((opt = getNextOption()) != null) {
- if (opt.equals("--user")) {
- userId = UserHandle.parseUserArg(getNextArgRequired());
- if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT) {
- UserManagerInternal umi =
- LocalServices.getService(UserManagerInternal.class);
- UserInfo userInfo = umi.getUserInfo(userId);
- if (userInfo == null) {
- pw.println("Failure [user " + userId + " doesn't exist]");
- return 1;
- }
- }
- } else {
- pw.println("Error: Unknown option: " + opt);
- return 1;
- }
- }
- final int translatedUserId =
- translateUserId(userId, UserHandle.USER_SYSTEM, "runGetVerificationPolicy");
- try {
- final IPackageInstaller installer = mInterface.getPackageInstaller();
- // TODO(b/360129657): global verification policy should be per user
- final int policy = installer.getVerificationPolicy(translatedUserId);
- pw.println(policy);
- } catch (Exception e) {
- pw.println("Failure [" + e.getMessage() + "]");
- return 1;
- }
- return 0;
- }
-
- private int runSetVerificationPolicy() throws RemoteException {
- final PrintWriter pw = getOutPrintWriter();
- int userId = UserHandle.USER_ALL;
-
- String opt;
- while ((opt = getNextOption()) != null) {
- if (opt.equals("--user")) {
- userId = UserHandle.parseUserArg(getNextArgRequired());
- if (userId != UserHandle.USER_ALL && userId != UserHandle.USER_CURRENT) {
- UserManagerInternal umi =
- LocalServices.getService(UserManagerInternal.class);
- UserInfo userInfo = umi.getUserInfo(userId);
- if (userInfo == null) {
- pw.println("Failure [user " + userId + " doesn't exist]");
- return 1;
- }
- }
- } else {
- pw.println("Error: Unknown option: " + opt);
- return 1;
- }
- }
- final String policyStr = getNextArg();
- if (policyStr == null) {
- pw.println("Error: policy not specified");
- return 1;
- }
- final int translatedUserId =
- translateUserId(userId, UserHandle.USER_SYSTEM, "runSetVerificationPolicy");
- try {
- final IPackageInstaller installer = mInterface.getPackageInstaller();
- // TODO(b/360129657): global verification policy should be per user
- final boolean success = installer.setVerificationPolicy(Integer.parseInt(policyStr),
- translatedUserId);
- if (!success) {
- pw.println("Failure setting verification policy.");
- return 1;
- }
- } catch (Exception e) {
- pw.println("Failure [" + e.getMessage() + "]");
- return 1;
- }
- return 0;
- }
-
@Override
public void onHelp() {
final PrintWriter pw = getOutPrintWriter();
@@ -4900,7 +4812,6 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" https://source.android.com/docs/core/runtime/configure"
+ "#compiler_filters");
pw.println(" or 'skip'");
- pw.println(" --force-verification: if set, enable the verification for this install");
if (Flags.sdkDependencyInstaller()) {
pw.println(" --disable-auto-install-dependencies: if set, any missing shared");
pw.println(" library dependencies will not be auto-installed");
@@ -5169,14 +5080,6 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" --user: return the agent of the given user (SYSTEM_USER if unspecified)");
pw.println(" get-package-storage-stats [--user <USER_ID>] <PACKAGE>");
pw.println(" Return the storage stats for the given app, if present");
- pw.println(" get-verification-policy [--user USER_ID]");
- pw.println(" Display current verification enforcement policy which will be applied to");
- pw.println(" all the future installation sessions");
- pw.println(" --user: show the policy of the given user (SYSTEM_USER if unspecified)");
- pw.println(" set-verification-policy POLICY [--user USER_ID]");
- pw.println(" Sets the verification policy of all the future installation sessions.");
- pw.println(" --user: set the policy of the given user (SYSTEM_USER if unspecified)");
- pw.println("");
pw.println("");
printArtServiceHelp();
pw.println("");
diff --git a/services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java b/services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java
deleted file mode 100644
index 67ac2a7572d8..000000000000
--- a/services/core/java/com/android/server/pm/verify/pkg/VerificationStatusTracker.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.verify.pkg;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * This class keeps record of the current timeout status of a verification request.
- */
-public final class VerificationStatusTracker {
- private final @CurrentTimeMillisLong long mStartTime;
- private @CurrentTimeMillisLong long mTimeoutTime;
- private final @CurrentTimeMillisLong long mMaxTimeoutTime;
- @NonNull
- private final VerifierController.Injector mInjector;
-
- /**
- * By default, the timeout time is the default timeout duration plus the current time (when
- * the timer starts for a verification request). Both the default timeout time and the max
- * timeout time cannot be changed after the timer has started, but the actual timeout time
- * can be extended via {@link #extendTimeRemaining} to the maximum allowed.
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
- public VerificationStatusTracker(long defaultTimeoutMillis, long maxExtendedTimeoutMillis,
- @NonNull VerifierController.Injector injector) {
- mStartTime = injector.getCurrentTimeMillis();
- mTimeoutTime = mStartTime + defaultTimeoutMillis;
- mMaxTimeoutTime = mStartTime + maxExtendedTimeoutMillis;
- mInjector = injector;
- }
-
- /**
- * Used by the controller to inform the verifier agent about the timestamp when the verification
- * request will timeout.
- */
- public @CurrentTimeMillisLong long getTimeoutTime() {
- return mTimeoutTime;
- }
-
- /**
- * Used by the controller to decide when to check for timeout again.
- * @return 0 if the timeout time has been reached, otherwise the remaining time in milliseconds
- * before the timeout is reached.
- */
- public @CurrentTimeMillisLong long getRemainingTime() {
- final long remainingTime = mTimeoutTime - mInjector.getCurrentTimeMillis();
- if (remainingTime < 0) {
- return 0;
- }
- return remainingTime;
- }
-
- /**
- * Used by the controller to extend the timeout duration of the verification request, upon
- * receiving the callback from the verifier agent.
- * @return the amount of time in millis that the timeout has been extended, subject to the max
- * amount allowed.
- */
- public long extendTimeRemaining(@CurrentTimeMillisLong long additionalMs) {
- if (mTimeoutTime + additionalMs > mMaxTimeoutTime) {
- additionalMs = mMaxTimeoutTime - mTimeoutTime;
- }
- mTimeoutTime += additionalMs;
- return additionalMs;
- }
-
- /**
- * Used by the controller to get the timeout status of the request.
- * @return False if the request still has some time left before timeout, otherwise return True.
- */
- public boolean isTimeout() {
- return mInjector.getCurrentTimeMillis() >= mTimeoutTime;
- }
-}
diff --git a/services/core/java/com/android/server/pm/verify/pkg/VerifierController.java b/services/core/java/com/android/server/pm/verify/pkg/VerifierController.java
deleted file mode 100644
index 78849d286ebe..000000000000
--- a/services/core/java/com/android/server/pm/verify/pkg/VerifierController.java
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.verify.pkg;
-
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
-import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
-import static android.os.Process.INVALID_UID;
-import static android.os.Process.SYSTEM_UID;
-import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.content.pm.verify.pkg.IVerificationSessionInterface;
-import android.content.pm.verify.pkg.IVerifierService;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.PersistableBundle;
-import android.os.Process;
-import android.os.UserHandle;
-import android.provider.DeviceConfig;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.infra.AndroidFuture;
-import com.android.internal.infra.ServiceConnector;
-import com.android.server.pm.Computer;
-import com.android.server.pm.PackageInstallerSession;
-import com.android.server.pm.pkg.PackageStateInternal;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-/**
- * This class manages the bind to the verifier agent installed on the device that implements
- * {@link android.content.pm.verify.pkg.VerifierService} and handles all its interactions.
- */
-public class VerifierController {
- private static final String TAG = "VerifierController";
- private static final boolean DEBUG = false;
-
- /**
- * Configurable maximum amount of time in milliseconds to wait for a verifier to respond to
- * a verification request.
- * Flag type: {@code long}
- * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
- */
- private static final String PROPERTY_VERIFICATION_REQUEST_TIMEOUT_MILLIS =
- "verification_request_timeout_millis";
- // Default duration to wait for a verifier to respond to a verification request.
- private static final long DEFAULT_VERIFICATION_REQUEST_TIMEOUT_MILLIS =
- TimeUnit.MINUTES.toMillis(1);
- /**
- * Configurable maximum amount of time in milliseconds that the verifier can request to extend
- * the verification request timeout duration to. This is the maximum amount of time the system
- * can wait for a request before it times out.
- * Flag type: {@code long}
- * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
- */
- private static final String PROPERTY_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS =
- "max_verification_request_extended_timeout_millis";
- // Max duration allowed to wait for a verifier to respond to a verification request.
- private static final long DEFAULT_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS =
- TimeUnit.MINUTES.toMillis(10);
- /**
- * Configurable maximum amount of time in milliseconds for the system to wait from the moment
- * when the installation session requires a verification, till when the request is delivered to
- * the verifier, pending the connection to be established. If the request has not been delivered
- * to the verifier within this amount of time, e.g., because the verifier has crashed or ANR'd,
- * the controller then sends a failure status back to the installation session.
- * Flag type: {@code long}
- * Namespace: NAMESPACE_PACKAGE_MANAGER_SERVICE
- */
- private static final String PROPERTY_VERIFIER_CONNECTION_TIMEOUT_MILLIS =
- "verifier_connection_timeout_millis";
- // The maximum amount of time to wait from the moment when the session requires a verification,
- // till when the request is delivered to the verifier, pending the connection to be established.
- private static final long DEFAULT_VERIFIER_CONNECTION_TIMEOUT_MILLIS =
- TimeUnit.SECONDS.toMillis(10);
-
- // The maximum amount of time to wait before the system unbinds from the verifier.
- private static final long UNBIND_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(6);
-
- private final Context mContext;
- private final Handler mHandler;
- // Guards the remote service object, as well as the verifier name and UID, which should all be
- // changed at the same time.
- private final Object mLock = new Object();
- @Nullable
- @GuardedBy("mLock")
- private ServiceConnector<IVerifierService> mRemoteService;
- @Nullable
- @GuardedBy("mLock")
- private ComponentName mRemoteServiceComponentName;
- @GuardedBy("mLock")
- private int mRemoteServiceUid = INVALID_UID;
- @NonNull
- private Injector mInjector;
-
- // Repository of active verification sessions and their status, mapping from id to status.
- @NonNull
- @GuardedBy("mVerificationStatus")
- private final SparseArray<VerificationStatusTracker> mVerificationStatus = new SparseArray<>();
-
- public VerifierController(@NonNull Context context, @NonNull Handler handler) {
- this(context, handler, new Injector());
- }
-
- @VisibleForTesting
- public VerifierController(@NonNull Context context, @NonNull Handler handler,
- @NonNull Injector injector) {
- mContext = context;
- mHandler = handler;
- mInjector = injector;
- }
-
- /**
- * Used by the installation session to get the package name of the installed verifier.
- */
- @Nullable
- public String getVerifierPackageName(Supplier<Computer> snapshotSupplier, int userId) {
- synchronized (mLock) {
- if (isVerifierConnectedLocked()) {
- // Verifier is connected or is being connected, so it must be installed.
- return mRemoteServiceComponentName.getPackageName();
- }
- }
- // Verifier has been disconnected, or it hasn't been connected. Check if it's installed.
- return mInjector.getVerifierPackageName(snapshotSupplier.get(), userId);
- }
-
- /**
- * Called to start querying and binding to a qualified verifier agent.
- *
- * @return False if a qualified verifier agent doesn't exist on device, so that the system can
- * handle this situation immediately after the call.
- * <p>
- * Notice that since this is an async call, even if this method returns true, it doesn't
- * necessarily mean that the binding connection was successful. However, the system will only
- * try to bind once per installation session, so that it doesn't waste resource by repeatedly
- * trying to bind if the verifier agent isn't available during a short amount of time.
- * <p>
- * If the verifier agent exists but cannot be started for some reason, all the notify* methods
- * in this class will fail asynchronously and quietly. The system will learn about the failure
- * after receiving the failure from
- * {@link PackageInstallerSession.VerifierCallback#onConnectionFailed}.
- */
- public boolean bindToVerifierServiceIfNeeded(Supplier<Computer> snapshotSupplier, int userId) {
- if (DEBUG) {
- Slog.i(TAG, "Requesting to bind to the verifier service.");
- }
- if (mRemoteService != null) {
- // Already connected
- if (DEBUG) {
- Slog.i(TAG, "Verifier service is already connected.");
- }
- return true;
- }
- Computer snapshot = snapshotSupplier.get();
- Pair<ServiceConnector<IVerifierService>, ComponentName> result =
- mInjector.getRemoteService(snapshot, mContext, userId, mHandler);
- if (result == null || result.first == null) {
- if (DEBUG) {
- Slog.i(TAG, "Unable to find a qualified verifier.");
- }
- return false;
- }
- final int verifierUid = snapshot.getPackageUidInternal(
- result.second.getPackageName(), 0, userId, /* callingUid= */ SYSTEM_UID);
- if (verifierUid == INVALID_UID) {
- if (DEBUG) {
- Slog.i(TAG, "Unable to find the UID of the qualified verifier.");
- }
- return false;
- }
- synchronized (mLock) {
- mRemoteService = result.first;
- mRemoteServiceComponentName = result.second;
- mRemoteServiceUid = verifierUid;
- }
-
- if (DEBUG) {
- Slog.i(TAG, "Connecting to a qualified verifier: " + mRemoteServiceComponentName);
- }
- mRemoteService.setServiceLifecycleCallbacks(
- new ServiceConnector.ServiceLifecycleCallbacks<>() {
- @Override
- public void onConnected(@NonNull IVerifierService service) {
- Slog.i(TAG, "Verifier " + mRemoteServiceComponentName + " is connected");
- }
-
- @Override
- public void onDisconnected(@NonNull IVerifierService service) {
- Slog.w(TAG,
- "Verifier " + mRemoteServiceComponentName + " is disconnected");
- destroy();
- }
-
- @Override
- public void onBinderDied() {
- Slog.w(TAG, "Verifier " + mRemoteServiceComponentName + " has died");
- destroy();
- }
-
- private void destroy() {
- synchronized (mLock) {
- if (isVerifierConnectedLocked()) {
- mRemoteService.unbind();
- mRemoteService = null;
- mRemoteServiceComponentName = null;
- mRemoteServiceUid = INVALID_UID;
- }
- }
- }
- });
- AndroidFuture<IVerifierService> unusedFuture = mRemoteService.connect();
- return true;
- }
-
- @GuardedBy("mLock")
- private boolean isVerifierConnectedLocked() {
- return mRemoteService != null && mRemoteServiceComponentName != null;
- }
-
- /**
- * Called to notify the bound verifier agent that a package name is available and will soon be
- * requested for verification.
- */
- public void notifyPackageNameAvailable(@NonNull String packageName) {
- synchronized (mLock) {
- if (!isVerifierConnectedLocked()) {
- if (DEBUG) {
- Slog.i(TAG, "Verifier is not connected. Not notifying package name available");
- }
- return;
- }
- // Best effort. We don't check for the result.
- mRemoteService.run(service -> {
- if (DEBUG) {
- Slog.i(TAG, "Notifying package name available for " + packageName);
- }
- service.onPackageNameAvailable(packageName);
- });
- }
- }
-
- /**
- * Called to notify the bound verifier agent that a package previously notified via
- * {@link android.content.pm.verify.pkg.VerifierService#onPackageNameAvailable(String)}
- * will no longer be requested for verification, possibly because the installation is canceled.
- */
- public void notifyVerificationCancelled(@NonNull String packageName) {
- synchronized (mLock) {
- if (!isVerifierConnectedLocked()) {
- if (DEBUG) {
- Slog.i(TAG, "Verifier is not connected. Not notifying verification cancelled");
- }
- return;
- }
- // Best effort. We don't check for the result.
- mRemoteService.run(service -> {
- if (DEBUG) {
- Slog.i(TAG, "Notifying verification cancelled for " + packageName);
- }
- service.onVerificationCancelled(packageName);
- });
- }
- }
-
- /**
- * Called to notify the bound verifier agent that a package that's pending installation needs
- * to be verified right now.
- * <p>The verification request must be sent to the verifier as soon as the verifier is
- * connected. If the connection cannot be made within the specified time limit from
- * when the request is sent out, we consider the verification to be failed and notify the
- * installation session.</p>
- * <p>If a response is not returned from the verifier agent within a timeout duration from the
- * time the request is sent to the verifier, the verification will be considered a failure.</p>
- *
- * @param retry whether this request is for retrying a previously incomplete verification.
- */
- public boolean startVerificationSession(Supplier<Computer> snapshotSupplier, int userId,
- int installationSessionId, String packageName,
- Uri stagedPackageUri, SigningInfo signingInfo,
- List<SharedLibraryInfo> declaredLibraries,
- @PackageInstaller.VerificationPolicy int verificationPolicy,
- PersistableBundle extensionParams, PackageInstallerSession.VerifierCallback callback,
- boolean retry) {
- // Try connecting to the verifier if not already connected
- if (!bindToVerifierServiceIfNeeded(snapshotSupplier, userId)) {
- return false;
- }
- // For now, the verification id is the same as the installation session id.
- final int verificationId = installationSessionId;
- synchronized (mLock) {
- if (!isVerifierConnectedLocked()) {
- if (DEBUG) {
- Slog.i(TAG, "Verifier is not connected. Not notifying verification required");
- }
- // Normally this should not happen because we just tried to bind. But if the
- // verifier just crashed or just became unavailable, we should notify the
- // installation session so it can finish with a verification failure.
- return false;
- }
- final VerificationSession session = new VerificationSession(
- /* id= */ verificationId,
- /* installSessionId= */ installationSessionId,
- packageName, stagedPackageUri, signingInfo, declaredLibraries, extensionParams,
- verificationPolicy, new VerificationSessionInterface(callback));
- AndroidFuture<Void> unusedFuture = mRemoteService.post(service -> {
- if (!retry) {
- if (DEBUG) {
- Slog.i(TAG, "Notifying verification required for session "
- + verificationId);
- }
- service.onVerificationRequired(session);
- } else {
- if (DEBUG) {
- Slog.i(TAG, "Notifying verification retry for session "
- + verificationId);
- }
- service.onVerificationRetry(session);
- }
- }).orTimeout(mInjector.getVerifierConnectionTimeoutMillis(), TimeUnit.MILLISECONDS)
- .whenComplete((res, err) -> {
- if (err != null) {
- Slog.e(TAG, "Error notifying verification request for session "
- + verificationId, err);
- // Notify the installation session so it can finish with verification
- // failure.
- callback.onConnectionFailed();
- }
- });
- }
- // Keep track of the session status with the ID. Start counting down the session timeout.
- final long defaultTimeoutMillis = mInjector.getVerificationRequestTimeoutMillis();
- final long maxExtendedTimeoutMillis = mInjector.getMaxVerificationExtendedTimeoutMillis();
- final VerificationStatusTracker tracker = new VerificationStatusTracker(
- defaultTimeoutMillis, maxExtendedTimeoutMillis, mInjector);
- synchronized (mVerificationStatus) {
- mVerificationStatus.put(verificationId, tracker);
- }
- startTimeoutCountdown(verificationId, tracker, callback, defaultTimeoutMillis);
- return true;
- }
-
- private void startTimeoutCountdown(int verificationId, VerificationStatusTracker tracker,
- PackageInstallerSession.VerifierCallback callback, long delayMillis) {
- mHandler.postDelayed(() -> {
- if (DEBUG) {
- Slog.i(TAG, "Checking request timeout for " + verificationId);
- }
- if (!tracker.isTimeout()) {
- if (DEBUG) {
- Slog.i(TAG, "Timeout is not met for " + verificationId + "; check later.");
- }
- // If the current session is not timed out yet, check again later.
- startTimeoutCountdown(verificationId, tracker, callback,
- /* delayMillis= */ tracker.getRemainingTime());
- } else {
- if (DEBUG) {
- Slog.i(TAG, "Request " + verificationId + " has timed out.");
- }
- // The request has timed out. Notify the installation session.
- callback.onTimeout();
- // Remove status tracking and stop the timeout countdown
- removeStatusTracker(verificationId);
- }
- }, /* token= */ tracker, delayMillis);
- }
-
- /**
- * Called to notify the bound verifier agent that a verification request has timed out.
- */
- public void notifyVerificationTimeout(int verificationId) {
- synchronized (mLock) {
- if (!isVerifierConnectedLocked()) {
- if (DEBUG) {
- Slog.i(TAG,
- "Verifier is not connected. Not notifying timeout for "
- + verificationId);
- }
- return;
- }
- AndroidFuture<Void> unusedFuture = mRemoteService.post(service -> {
- if (DEBUG) {
- Slog.i(TAG, "Notifying timeout for " + verificationId);
- }
- service.onVerificationTimeout(verificationId);
- }).whenComplete((res, err) -> {
- if (err != null) {
- Slog.e(TAG, "Error notifying VerificationTimeout for session "
- + verificationId, err);
- }
- });
- }
- }
-
- /**
- * Remove a status tracker after it's no longer needed.
- */
- private void removeStatusTracker(int verificationId) {
- if (DEBUG) {
- Slog.i(TAG, "Removing status tracking for verification " + verificationId);
- }
- synchronized (mVerificationStatus) {
- VerificationStatusTracker tracker = mVerificationStatus.removeReturnOld(verificationId);
- // Cancel the timeout counters if there's any
- if (tracker != null) {
- mInjector.stopTimeoutCountdown(mHandler, tracker);
- }
- }
- }
-
- /**
- * Assert that the calling UID is the same as the UID of the currently connected verifier.
- */
- public void assertCallerIsCurrentVerifier(int callingUid) {
- synchronized (mLock) {
- if (!isVerifierConnectedLocked()) {
- throw new IllegalStateException(
- "Unable to proceed because the verifier has been disconnected.");
- }
- if (callingUid != mRemoteServiceUid) {
- throw new IllegalStateException(
- "Calling uid " + callingUid + " is not the current verifier.");
- }
- }
- }
-
- // This class handles requests from the remote verifier
- private class VerificationSessionInterface extends IVerificationSessionInterface.Stub {
- private final PackageInstallerSession.VerifierCallback mCallback;
-
- VerificationSessionInterface(PackageInstallerSession.VerifierCallback callback) {
- mCallback = callback;
- }
-
- @Override
- public long getTimeoutTime(int verificationId) {
- assertCallerIsCurrentVerifier(getCallingUid());
- synchronized (mVerificationStatus) {
- final VerificationStatusTracker tracker = mVerificationStatus.get(verificationId);
- if (tracker == null) {
- throw new IllegalStateException("Verification session " + verificationId
- + " doesn't exist or has finished");
- }
- return tracker.getTimeoutTime();
- }
- }
-
- @Override
- public long extendTimeRemaining(int verificationId, long additionalMs) {
- assertCallerIsCurrentVerifier(getCallingUid());
- synchronized (mVerificationStatus) {
- final VerificationStatusTracker tracker = mVerificationStatus.get(verificationId);
- if (tracker == null) {
- throw new IllegalStateException("Verification session " + verificationId
- + " doesn't exist or has finished");
- }
- return tracker.extendTimeRemaining(additionalMs);
- }
- }
-
- @Override
- public boolean setVerificationPolicy(int verificationId,
- @PackageInstaller.VerificationPolicy int policy) {
- assertCallerIsCurrentVerifier(getCallingUid());
- synchronized (mVerificationStatus) {
- final VerificationStatusTracker tracker = mVerificationStatus.get(verificationId);
- if (tracker == null) {
- throw new IllegalStateException("Verification session " + verificationId
- + " doesn't exist or has finished");
- }
- }
- return mCallback.setVerificationPolicy(policy);
- }
-
- @Override
- public void reportVerificationIncomplete(int id, int reason) {
- assertCallerIsCurrentVerifier(getCallingUid());
- final VerificationStatusTracker tracker;
- synchronized (mVerificationStatus) {
- tracker = mVerificationStatus.get(id);
- if (tracker == null) {
- throw new IllegalStateException("Verification session " + id
- + " doesn't exist or has finished");
- }
- }
- mCallback.onVerificationIncompleteReceived(reason);
- // Remove status tracking and stop the timeout countdown
- removeStatusTracker(id);
- }
-
- @Override
- public void reportVerificationComplete(int id, VerificationStatus verificationStatus,
- @Nullable PersistableBundle extensionResponse) {
- assertCallerIsCurrentVerifier(getCallingUid());
- final VerificationStatusTracker tracker;
- synchronized (mVerificationStatus) {
- tracker = mVerificationStatus.get(id);
- if (tracker == null) {
- throw new IllegalStateException("Verification session " + id
- + " doesn't exist or has finished");
- }
- }
- mCallback.onVerificationCompleteReceived(verificationStatus, extensionResponse);
- // Remove status tracking and stop the timeout countdown
- removeStatusTracker(id);
- }
- }
-
- @VisibleForTesting
- public static class Injector {
- /**
- * Mock this method to inject the remote service to enable unit testing.
- */
- @Nullable
- public Pair<ServiceConnector<IVerifierService>, ComponentName> getRemoteService(
- @NonNull Computer snapshot, @NonNull Context context, int userId,
- @NonNull Handler handler) {
- final ComponentName verifierComponent = resolveVerifierComponentName(snapshot, userId);
- if (verifierComponent == null) {
- return null;
- }
- final Intent intent = new Intent(PackageManager.ACTION_VERIFY_PACKAGE);
- intent.setComponent(verifierComponent);
- return new Pair<>(new ServiceConnector.Impl<IVerifierService>(
- context, intent, Context.BIND_AUTO_CREATE, userId,
- IVerifierService.Stub::asInterface) {
- @Override
- protected Handler getJobHandler() {
- return handler;
- }
-
- @Override
- protected long getRequestTimeoutMs() {
- return getVerificationRequestTimeoutMillis();
- }
-
- @Override
- protected long getAutoDisconnectTimeoutMs() {
- return UNBIND_TIMEOUT_MILLIS;
- }
- }, verifierComponent);
- }
-
- /**
- * Return the package name of the verifier installed on this device.
- */
- @Nullable
- public String getVerifierPackageName(Computer snapshot, int userId) {
- final ComponentName componentName = resolveVerifierComponentName(snapshot, userId);
- if (componentName == null) {
- return null;
- }
- return componentName.getPackageName();
- }
-
- /**
- * Find the ComponentName of the verifier service agent, using the intent action.
- * If multiple qualified verifier services are present, the one with the highest intent
- * filter priority will be chosen.
- */
- private static @Nullable ComponentName resolveVerifierComponentName(Computer snapshot,
- int userId) {
- final Intent intent = new Intent(PackageManager.ACTION_VERIFY_PACKAGE);
- final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
- final List<ResolveInfo> matchedServices = snapshot.queryIntentServicesInternal(
- intent, null,
- resolveFlags, userId, SYSTEM_UID, Process.INVALID_PID,
- /*includeInstantApps*/ false, /*resolveForStart*/ false);
- if (matchedServices.isEmpty()) {
- Slog.w(TAG,
- "Failed to find any matching verifier service agent");
- return null;
- }
- ResolveInfo best = null;
- int numMatchedServices = matchedServices.size();
- for (int i = 0; i < numMatchedServices; i++) {
- ResolveInfo cur = matchedServices.get(i);
- if (!isQualifiedVerifier(snapshot, cur, userId)) {
- continue;
- }
- if (best == null || cur.priority > best.priority) {
- best = cur;
- }
- }
- if (best != null) {
- Slog.i(TAG, "Found verifier service agent: "
- + best.getComponentInfo().getComponentName().toShortString());
- return best.getComponentInfo().getComponentName();
- }
- Slog.w(TAG, "Didn't find any qualified verifier service agent.");
- return null;
- }
-
- @SuppressLint("AndroidFrameworkRequiresPermission")
- private static boolean isQualifiedVerifier(Computer snapshot, ResolveInfo ri, int userId) {
- // Basic null checks
- if (ri.getComponentInfo() == null) {
- return false;
- }
- final ApplicationInfo applicationInfo = ri.getComponentInfo().applicationInfo;
- if (applicationInfo == null) {
- return false;
- }
- // Check for installed state
- PackageStateInternal ps = snapshot.getPackageStateInternal(
- ri.getComponentInfo().packageName, SYSTEM_UID);
- if (ps == null || !ps.getUserStateOrDefault(userId).isInstalled()) {
- return false;
- }
- // Check for enabled state
- if (!snapshot.isComponentEffectivelyEnabled(ri.getComponentInfo(),
- UserHandle.of(userId))) {
- return false;
- }
- // Allow binding to a non-privileged app on an ENG build
- // TODO: think of a better way to test it on non-eng builds
- if (Build.IS_ENG) {
- return true;
- }
- // Check if the app is platform-signed or is privileged
- if (!applicationInfo.isSignedWithPlatformKey() && !applicationInfo.isPrivilegedApp()) {
- return false;
- }
- // Check for permission
- return (snapshot.checkUidPermission(
- android.Manifest.permission.VERIFICATION_AGENT, applicationInfo.uid)
- != PackageManager.PERMISSION_GRANTED);
- }
-
- /**
- * This is added so we can mock timeouts in the unit tests.
- */
- public long getCurrentTimeMillis() {
- return System.currentTimeMillis();
- }
-
- /**
- * This is added so that we don't need to mock Handler.removeCallbacksAndEqualMessages
- * which is final.
- */
- public void stopTimeoutCountdown(Handler handler, Object token) {
- handler.removeCallbacksAndEqualMessages(token);
- }
-
- /**
- * This is added so that we can mock the verification request timeout duration without
- * calling into DeviceConfig.
- */
- public long getVerificationRequestTimeoutMillis() {
- return getVerificationRequestTimeoutMillisFromDeviceConfig();
- }
-
- /**
- * This is added so that we can mock the maximum request timeout duration without
- * calling into DeviceConfig.
- */
- public long getMaxVerificationExtendedTimeoutMillis() {
- return getMaxVerificationExtendedTimeoutMillisFromDeviceConfig();
- }
-
- /**
- * This is added so that we can mock the maximum connection timeout duration without
- * calling into DeviceConfig.
- */
- public long getVerifierConnectionTimeoutMillis() {
- return getVerifierConnectionTimeoutMillisFromDeviceConfig();
- }
-
- private static long getVerificationRequestTimeoutMillisFromDeviceConfig() {
- return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
- PROPERTY_VERIFICATION_REQUEST_TIMEOUT_MILLIS,
- DEFAULT_VERIFICATION_REQUEST_TIMEOUT_MILLIS);
- }
-
- private static long getMaxVerificationExtendedTimeoutMillisFromDeviceConfig() {
- return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
- PROPERTY_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS,
- DEFAULT_MAX_VERIFICATION_REQUEST_EXTENDED_TIMEOUT_MILLIS);
- }
-
- private static long getVerifierConnectionTimeoutMillisFromDeviceConfig() {
- return DeviceConfig.getLong(NAMESPACE_PACKAGE_MANAGER_SERVICE,
- PROPERTY_VERIFIER_CONNECTION_TIMEOUT_MILLIS,
- DEFAULT_VERIFIER_CONNECTION_TIMEOUT_MILLIS);
- }
- }
-}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 85e7cfe33c0e..8e7302322d47 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -85,6 +85,7 @@ import static android.view.contentprotection.flags.Flags.createAccessibilityOver
import static com.android.hardware.input.Flags.enableNew25q2Keycodes;
import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
+import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.modifierShortcutDump;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
@@ -7106,7 +7107,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (modifierShortcutManagerMultiuser()) {
mModifierShortcutManager.setCurrentUser(UserHandle.of(newUserId));
}
- mInputManagerInternal.setCurrentUser(newUserId);
+ if (!inputManagerLifecycleSupport()) {
+ mInputManagerInternal.setCurrentUser(newUserId);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/power/hint/Android.bp b/services/core/java/com/android/server/power/hint/Android.bp
index 6dadf8f16390..da594048da44 100644
--- a/services/core/java/com/android/server/power/hint/Android.bp
+++ b/services/core/java/com/android/server/power/hint/Android.bp
@@ -7,6 +7,15 @@ aconfig_declarations {
],
}
+aconfig_declarations {
+ name: "adpf_flags",
+ package: "android.adpf",
+ container: "system",
+ srcs: [
+ "adpf_flags.aconfig",
+ ],
+}
+
java_aconfig_library {
name: "power_hint_flags_lib",
aconfig_declarations: "power_hint_flags",
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 17459df2bc1a..71f67d82dbec 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -52,6 +52,7 @@ import android.os.PerformanceHintManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SessionCreationConfig;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -70,6 +71,7 @@ import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.power.hint.HintManagerService.AppHintSession.SessionModes;
import com.android.server.utils.Slogf;
import java.io.FileDescriptor;
@@ -102,6 +104,8 @@ public final class HintManagerService extends SystemService {
@VisibleForTesting final long mHintSessionPreferredRate;
+ @VisibleForTesting static final int MAX_GRAPHICS_PIPELINE_THREADS_COUNT = 5;
+
// Multi-level map storing all active AppHintSessions.
// First level is keyed by the UID of the client process creating the session.
// Second level is keyed by an IBinder passed from client process. This is used to observe
@@ -129,6 +133,14 @@ public final class HintManagerService extends SystemService {
@GuardedBy("mSessionSnapshotMapLock")
private ArrayMap<Integer, ArrayMap<Integer, AppHintSessionSnapshot>> mSessionSnapshotMap;
+ /*
+ * App UID to Thread mapping.
+ * Thread is a sub class bookkeeping TID, thread mode (especially graphics pipeline mode)
+ * This is to bookkeep and track the thread usage.
+ */
+ @GuardedBy("mThreadsUsageObject")
+ private ArrayMap<Integer, ArraySet<ThreadUsageTracker>> mThreadsUsageMap;
+
/** Lock to protect mActiveSessions and the UidObserver. */
private final Object mLock = new Object();
@@ -144,6 +156,9 @@ public final class HintManagerService extends SystemService {
*/
private final Object mSessionSnapshotMapLock = new Object();
+ /** Lock to protect mThreadsUsageMap. */
+ private final Object mThreadsUsageObject = new Object();
+
@GuardedBy("mNonIsolatedTidsLock")
private final Map<Integer, Set<Long>> mNonIsolatedTids;
@@ -262,6 +277,7 @@ public final class HintManagerService extends SystemService {
mActiveSessions = new ArrayMap<>();
mChannelMap = new ArrayMap<>();
mSessionSnapshotMap = new ArrayMap<>();
+ mThreadsUsageMap = new ArrayMap<>();
mNativeWrapper = injector.createNativeWrapper();
mNativeWrapper.halInit();
mHintSessionPreferredRate = mNativeWrapper.halGetHintSessionPreferredRate();
@@ -357,6 +373,36 @@ public final class HintManagerService extends SystemService {
}
}
+ private static class ThreadUsageTracker {
+ /*
+ * Thread object for tracking thread usage per UID
+ */
+ int mTid;
+ boolean mIsGraphicsPipeline;
+
+ ThreadUsageTracker(int tid) {
+ mTid = tid;
+ mIsGraphicsPipeline = false;
+ }
+
+ ThreadUsageTracker(int tid, boolean isGraphicsPipeline) {
+ mTid = tid;
+ mIsGraphicsPipeline = isGraphicsPipeline;
+ }
+
+ public int getTid() {
+ return mTid;
+ }
+
+ public boolean isGraphicsPipeline() {
+ return mIsGraphicsPipeline;
+ }
+
+ public void setGraphicsPipeline(boolean isGraphicsPipeline) {
+ mIsGraphicsPipeline = isGraphicsPipeline;
+ }
+ }
+
private class AppHintSessionSnapshot {
/*
* Per-Uid and Per-SessionTag snapshot that tracks metrics including
@@ -368,6 +414,7 @@ public final class HintManagerService extends SystemService {
int mMaxConcurrentSession;
int mMaxThreadCount;
int mPowerEfficientSessionCount;
+ int mGraphicsPipelineSessionCount;
final int mTargetDurationNsCountPQSize = 100;
PriorityQueue<TargetDurationRecord> mTargetDurationNsCountPQ;
@@ -425,6 +472,7 @@ public final class HintManagerService extends SystemService {
mMaxConcurrentSession = 0;
mMaxThreadCount = 0;
mPowerEfficientSessionCount = 0;
+ mGraphicsPipelineSessionCount = 0;
mTargetDurationNsCountPQ = new PriorityQueue<>(1);
}
@@ -443,6 +491,10 @@ public final class HintManagerService extends SystemService {
mPowerEfficientSessionCount += 1;
}
+ void logGraphicsPipelineSession() {
+ mGraphicsPipelineSessionCount += 1;
+ }
+
void updateThreadCount(int threadCount) {
mMaxThreadCount = Math.max(mMaxThreadCount, threadCount);
}
@@ -473,6 +525,10 @@ public final class HintManagerService extends SystemService {
return mPowerEfficientSessionCount;
}
+ int getGraphicsPipelineSessionCount() {
+ return mGraphicsPipelineSessionCount;
+ }
+
long[] targetDurationNsList() {
final int listSize = 5;
long[] targetDurations = new long[listSize];
@@ -1163,24 +1219,40 @@ public final class HintManagerService extends SystemService {
+ " doesn't belong to the calling application " + callingUid;
}
+ private boolean contains(final int[] array, final int target) {
+ for (int element : array) {
+ if (element == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@VisibleForTesting
final class BinderService extends IHintManager.Stub {
@Override
public IHintSession createHintSessionWithConfig(@NonNull IBinder token,
- @NonNull int[] tids, long durationNanos, @SessionTag int tag,
- SessionConfig config) {
+ @SessionTag int tag, SessionCreationConfig creationConfig,
+ SessionConfig config) {
if (!isHalSupported()) {
throw new UnsupportedOperationException("PowerHAL is not supported!");
}
java.util.Objects.requireNonNull(token);
- java.util.Objects.requireNonNull(tids);
+ java.util.Objects.requireNonNull(creationConfig.tids);
+
+ final int[] tids = creationConfig.tids;
Preconditions.checkArgument(tids.length != 0, "tids should"
+ " not be empty.");
+
final int callingUid = Binder.getCallingUid();
final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid());
final long identity = Binder.clearCallingIdentity();
+ final long durationNanos = creationConfig.targetWorkDurationNanos;
+
+ Preconditions.checkArgument(checkGraphicsPipelineValid(creationConfig, callingUid),
+ "not enough of available graphics pipeline thread.");
try {
final IntArray nonIsolated = powerhintThreadCleanup() ? new IntArray(tids.length)
: null;
@@ -1274,8 +1346,9 @@ public final class HintManagerService extends SystemService {
.computeIfAbsent(tag, k -> new AppHintSessionSnapshot())
.updateUponSessionCreation(tids.length, durationNanos);
}
+ AppHintSession hs = null;
synchronized (mLock) {
- AppHintSession hs = new AppHintSession(callingUid, callingTgid, tag, tids,
+ hs = new AppHintSession(callingUid, callingTgid, tag, tids,
token, halSessionPtr, durationNanos);
ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
mActiveSessions.get(callingUid);
@@ -1290,9 +1363,29 @@ public final class HintManagerService extends SystemService {
}
sessionSet.add(hs);
mUsesFmq = mUsesFmq || hasChannel(callingTgid, callingUid);
+ }
+
+ if (hs != null) {
+ boolean isGraphicsPipeline = false;
+ if (creationConfig.modesToEnable != null) {
+ for (int sessionMode : creationConfig.modesToEnable) {
+ if (sessionMode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+ isGraphicsPipeline = true;
+ }
+ hs.setMode(sessionMode, true);
+ }
+ }
- return hs;
+ synchronized (mThreadsUsageObject) {
+ mThreadsUsageMap.computeIfAbsent(callingUid, k -> new ArraySet<>());
+ ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
+ for (int i = 0; i < tids.length; ++i) {
+ threadsSet.add(new ThreadUsageTracker(tids[i], isGraphicsPipeline));
+ }
+ }
}
+
+ return hs;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1335,6 +1428,11 @@ public final class HintManagerService extends SystemService {
}
@Override
+ public int getMaxGraphicsPipelineThreadsCount() {
+ return MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
+ }
+
+ @Override
public void setHintSessionThreads(@NonNull IHintSession hintSession, @NonNull int[] tids) {
AppHintSession appHintSession = (AppHintSession) hintSession;
appHintSession.setThreads(tids);
@@ -1470,6 +1568,7 @@ public final class HintManagerService extends SystemService {
return;
}
pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
+ pw.println("MaxGraphicsPipelineThreadsCount: " + MAX_GRAPHICS_PIPELINE_THREADS_COUNT);
pw.println("HAL Support: " + isHalSupported());
pw.println("Active Sessions:");
synchronized (mLock) {
@@ -1507,6 +1606,45 @@ public final class HintManagerService extends SystemService {
}
}
+ private boolean checkGraphicsPipelineValid(SessionCreationConfig creationConfig, int uid) {
+ if (creationConfig.modesToEnable == null) {
+ return true;
+ }
+ boolean setGraphicsPipeline = false;
+ for (int modeToEnable : creationConfig.modesToEnable) {
+ if (modeToEnable == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+ setGraphicsPipeline = true;
+ }
+ }
+ if (!setGraphicsPipeline) {
+ return true;
+ }
+
+ synchronized (mThreadsUsageObject) {
+ // count used graphics pipeline threads for the calling UID
+ // consider the case that new tids are overlapping with in session tids
+ ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(uid);
+ if (threadsSet == null) {
+ return true;
+ }
+
+ final int newThreadCount = creationConfig.tids.length;
+ int graphicsPipelineThreadCount = 0;
+ for (ThreadUsageTracker t : threadsSet) {
+ // count graphics pipeline threads in use
+ // and exclude overlapping ones
+ if (t.isGraphicsPipeline()) {
+ graphicsPipelineThreadCount++;
+ if (contains(creationConfig.tids, t.getTid())) {
+ graphicsPipelineThreadCount--;
+ }
+ }
+ }
+ return graphicsPipelineThreadCount + newThreadCount
+ <= MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
+ }
+ }
+
private void logPerformanceHintSessionAtom(int uid, long sessionId,
long targetDuration, int[] tids, @SessionTag int sessionTag) {
FrameworkStatsLog.write(FrameworkStatsLog.PERFORMANCE_HINT_SESSION_REPORTED, uid,
@@ -1537,11 +1675,14 @@ public final class HintManagerService extends SystemService {
protected boolean mUpdateAllowedByProcState;
protected int[] mNewThreadIds;
protected boolean mPowerEfficient;
+ protected boolean mGraphicsPipeline;
protected boolean mHasBeenPowerEfficient;
+ protected boolean mHasBeenGraphicsPipeline;
protected boolean mShouldForcePause;
- private enum SessionModes {
+ enum SessionModes {
POWER_EFFICIENCY,
+ GRAPHICS_PIPELINE,
};
protected AppHintSession(
@@ -1556,7 +1697,9 @@ public final class HintManagerService extends SystemService {
mTargetDurationNanos = durationNanos;
mUpdateAllowedByProcState = true;
mPowerEfficient = false;
+ mGraphicsPipeline = false;
mHasBeenPowerEfficient = false;
+ mHasBeenGraphicsPipeline = false;
mShouldForcePause = false;
final boolean allowed = mUidObserver.isUidForeground(mUid);
updateHintAllowedByProcState(allowed);
@@ -1677,6 +1820,25 @@ public final class HintManagerService extends SystemService {
}
sessionSnapshot.updateUponSessionClose();
}
+
+ if (mGraphicsPipeline) {
+ synchronized (mThreadsUsageObject) {
+ ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(mUid);
+ if (threadsSet == null) {
+ Slogf.w(TAG, "Threads Set is null for uid " + mUid);
+ return;
+ }
+ // remove all tids associated with this session
+ for (int i = 0; i < threadsSet.size(); ++i) {
+ if (contains(mThreadIds, threadsSet.valueAt(i).getTid())) {
+ threadsSet.removeAt(i);
+ }
+ }
+ if (threadsSet.isEmpty()) {
+ mThreadsUsageMap.remove(mUid);
+ }
+ }
+ }
if (powerhintThreadCleanup()) {
synchronized (mNonIsolatedTidsLock) {
final int[] tids = getTidsInternal();
@@ -1713,6 +1875,33 @@ public final class HintManagerService extends SystemService {
throw new IllegalArgumentException("Thread id list can't be empty.");
}
+
+ final int callingUid = Binder.getCallingUid();
+ if (mGraphicsPipeline) {
+ synchronized (mThreadsUsageObject) {
+ // replace original tids with new tids
+ ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
+ int graphicsPipelineThreadCount = 0;
+ if (threadsSet != null) {
+ // We count the graphics pipeline threads that are
+ // *not* in this session, since those in this session
+ // will be replaced. Then if the count plus the new tids
+ // is over max available graphics pipeline threads we raise
+ // an exception.
+ for (ThreadUsageTracker t : threadsSet) {
+ if (t.isGraphicsPipeline() && !contains(mThreadIds, t.getTid())) {
+ graphicsPipelineThreadCount++;
+ }
+ }
+ if (graphicsPipelineThreadCount + tids.length
+ > MAX_GRAPHICS_PIPELINE_THREADS_COUNT) {
+ throw new IllegalArgumentException(
+ "Not enough available graphics pipeline threads.");
+ }
+ }
+ }
+ }
+
synchronized (this) {
if (mHalSessionPtr == 0) {
return;
@@ -1724,7 +1913,6 @@ public final class HintManagerService extends SystemService {
return;
}
if (checkTid) {
- final int callingUid = Binder.getCallingUid();
final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid());
final IntArray nonIsolated = powerhintThreadCleanup() ? new IntArray() : null;
final long identity = Binder.clearCallingIdentity();
@@ -1770,6 +1958,23 @@ public final class HintManagerService extends SystemService {
}
}
mNativeWrapper.halSetThreads(mHalSessionPtr, tids);
+
+ synchronized (mThreadsUsageObject) {
+ // replace old tids with new ones
+ ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
+ if (threadsSet == null) {
+ mThreadsUsageMap.put(callingUid, new ArraySet<ThreadUsageTracker>());
+ threadsSet = mThreadsUsageMap.get(callingUid);
+ }
+ for (int i = 0; i < threadsSet.size(); ++i) {
+ if (contains(mThreadIds, threadsSet.valueAt(i).getTid())) {
+ threadsSet.removeAt(i);
+ }
+ }
+ for (int tid : tids) {
+ threadsSet.add(new ThreadUsageTracker(tid, mGraphicsPipeline));
+ }
+ }
mThreadIds = tids;
mNewThreadIds = null;
// if the update is allowed but the session is force paused by tid clean up, then
@@ -1831,26 +2036,49 @@ public final class HintManagerService extends SystemService {
+ " greater than zero.");
if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
mPowerEfficient = enabled;
+ } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+ mGraphicsPipeline = enabled;
}
mNativeWrapper.halSetMode(mHalSessionPtr, mode, enabled);
}
- if (enabled && (mode == SessionModes.POWER_EFFICIENCY.ordinal())) {
- if (!mHasBeenPowerEfficient) {
- mHasBeenPowerEfficient = true;
- synchronized (mSessionSnapshotMapLock) {
- ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
- mSessionSnapshotMap.get(mUid);
- if (sessionSnapshots == null) {
- Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
- return;
+ if (enabled) {
+ if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
+ if (!mHasBeenPowerEfficient) {
+ mHasBeenPowerEfficient = true;
+ synchronized (mSessionSnapshotMapLock) {
+ ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.get(mUid);
+ if (sessionSnapshots == null) {
+ Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+ return;
+ }
+ AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+ if (sessionSnapshot == null) {
+ Slogf.w(TAG, "Session snapshot is null for uid " + mUid
+ + " and tag " + mTag);
+ return;
+ }
+ sessionSnapshot.logPowerEfficientSession();
}
- AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
- if (sessionSnapshot == null) {
- Slogf.w(TAG, "Session snapshot is null for uid " + mUid
- + " and tag " + mTag);
- return;
+ }
+ } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+ if (!mHasBeenGraphicsPipeline) {
+ mHasBeenGraphicsPipeline = true;
+ synchronized (mSessionSnapshotMapLock) {
+ ArrayMap<Integer, AppHintSessionSnapshot> sessionSnapshots =
+ mSessionSnapshotMap.get(mUid);
+ if (sessionSnapshots == null) {
+ Slogf.w(TAG, "Session snapshot map is null for uid " + mUid);
+ return;
+ }
+ AppHintSessionSnapshot sessionSnapshot = sessionSnapshots.get(mTag);
+ if (sessionSnapshot == null) {
+ Slogf.w(TAG, "Session snapshot is null for uid " + mUid
+ + " and tag " + mTag);
+ return;
+ }
+ sessionSnapshot.logGraphicsPipelineSession();
}
- sessionSnapshot.logPowerEfficientSession();
}
}
}
@@ -1877,6 +2105,12 @@ public final class HintManagerService extends SystemService {
}
}
+ public boolean isGraphicsPipeline() {
+ synchronized (this) {
+ return mGraphicsPipeline;
+ }
+ }
+
public int getUid() {
return mUid;
}
@@ -1964,6 +2198,7 @@ public final class HintManagerService extends SystemService {
pw.println(prefix + "SessionAllowedByProcState: " + mUpdateAllowedByProcState);
pw.println(prefix + "SessionForcePaused: " + mShouldForcePause);
pw.println(prefix + "PowerEfficient: " + (mPowerEfficient ? "true" : "false"));
+ pw.println(prefix + "GraphicsPipeline: " + (mGraphicsPipeline ? "true" : "false"));
}
}
diff --git a/services/core/java/com/android/server/power/hint/adpf_flags.aconfig b/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
new file mode 100644
index 000000000000..147d76bda477
--- /dev/null
+++ b/services/core/java/com/android/server/power/hint/adpf_flags.aconfig
@@ -0,0 +1,7 @@
+# New location for generic ADPF flags across the system
+# This will be moved to the top-level frameworks/base adpf library
+# once it lands
+
+package: "android.adpf"
+container: "system"
+
diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
index e780be490181..e8723b91a541 100644
--- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
+++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
@@ -141,7 +141,7 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
}
@Override
- @EnforcePermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+ @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
public void setAdvancedProtectionEnabled(boolean enabled) {
setAdvancedProtectionEnabled_enforcePermission();
final long identity = Binder.clearCallingIdentity();
@@ -159,7 +159,7 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
}
@Override
- @EnforcePermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+ @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
getAdvancedProtectionFeatures_enforcePermission();
List<AdvancedProtectionFeature> features = new ArrayList<>();
diff --git a/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java b/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java
index b8a4a9c26feb..6798a6146ae0 100644
--- a/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java
+++ b/services/core/java/com/android/server/security/authenticationpolicy/AuthenticationPolicyService.java
@@ -16,8 +16,11 @@
package com.android.server.security.authenticationpolicy;
+import static android.Manifest.permission.MANAGE_SECURE_LOCK_DEVICE;
+
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;
+import android.annotation.EnforcePermission;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -32,9 +35,14 @@ import android.hardware.biometrics.events.AuthenticationStoppedInfo;
import android.hardware.biometrics.events.AuthenticationSucceededInfo;
import android.os.Build;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
+import android.security.authenticationpolicy.AuthenticationPolicyManager;
+import android.security.authenticationpolicy.DisableSecureLockDeviceParams;
+import android.security.authenticationpolicy.EnableSecureLockDeviceParams;
+import android.security.authenticationpolicy.IAuthenticationPolicyService;
import android.util.Log;
import android.util.Slog;
import android.util.SparseIntArray;
@@ -74,6 +82,7 @@ public class AuthenticationPolicyService extends SystemService {
private final KeyguardManager mKeyguardManager;
private final WindowManagerInternal mWindowManager;
private final UserManagerInternal mUserManager;
+ private SecureLockDeviceServiceInternal mSecureLockDeviceService;
@VisibleForTesting
final SparseIntArray mFailedAttemptsForUser = new SparseIntArray();
private final SparseLongArray mLastLockedTimestamp = new SparseLongArray();
@@ -94,10 +103,16 @@ public class AuthenticationPolicyService extends SystemService {
mWindowManager = Objects.requireNonNull(
LocalServices.getService(WindowManagerInternal.class));
mUserManager = Objects.requireNonNull(LocalServices.getService(UserManagerInternal.class));
+ if (android.security.Flags.secureLockdown()) {
+ mSecureLockDeviceService = Objects.requireNonNull(
+ LocalServices.getService(SecureLockDeviceServiceInternal.class));
+ }
}
@Override
- public void onStart() {}
+ public void onStart() {
+ publishBinderService(Context.AUTHENTICATION_POLICY_SERVICE, mService);
+ }
@Override
public void onBootPhase(int phase) {
@@ -294,4 +309,36 @@ public class AuthenticationPolicyService extends SystemService {
// next successful primary or biometric auth happens
mLastLockedTimestamp.put(userId, SystemClock.elapsedRealtime());
}
+
+ private final IBinder mService = new IAuthenticationPolicyService.Stub() {
+ /**
+ * @see AuthenticationPolicyManager#enableSecureLockDevice(EnableSecureLockDeviceParams)
+ * @param params EnableSecureLockDeviceParams for caller to supply params related
+ * to the secure lock device request
+ * @return @EnableSecureLockDeviceRequestStatus int indicating the result of the Secure
+ * Lock Device request
+ */
+ @Override
+ @EnforcePermission(MANAGE_SECURE_LOCK_DEVICE)
+ @AuthenticationPolicyManager.EnableSecureLockDeviceRequestStatus
+ public int enableSecureLockDevice(EnableSecureLockDeviceParams params) {
+ enableSecureLockDevice_enforcePermission();
+ return mSecureLockDeviceService.enableSecureLockDevice(params);
+ }
+
+ /**
+ * @see AuthenticationPolicyManager#disableSecureLockDevice(DisableSecureLockDeviceParams)
+ * @param params @DisableSecureLockDeviceParams for caller to supply params related
+ * to the secure lock device request
+ * @return @DisableSecureLockDeviceRequestStatus int indicating the result of the Secure
+ * Lock Device request
+ */
+ @Override
+ @EnforcePermission(MANAGE_SECURE_LOCK_DEVICE)
+ @AuthenticationPolicyManager.DisableSecureLockDeviceRequestStatus
+ public int disableSecureLockDevice(DisableSecureLockDeviceParams params) {
+ disableSecureLockDevice_enforcePermission();
+ return mSecureLockDeviceService.disableSecureLockDevice(params);
+ }
+ };
}
diff --git a/services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceService.java b/services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceService.java
new file mode 100644
index 000000000000..7b89723deb6c
--- /dev/null
+++ b/services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceService.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.security.authenticationpolicy;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.security.authenticationpolicy.AuthenticationPolicyManager;
+import android.security.authenticationpolicy.AuthenticationPolicyManager.DisableSecureLockDeviceRequestStatus;
+import android.security.authenticationpolicy.AuthenticationPolicyManager.EnableSecureLockDeviceRequestStatus;
+import android.security.authenticationpolicy.DisableSecureLockDeviceParams;
+import android.security.authenticationpolicy.EnableSecureLockDeviceParams;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
+/**
+ * System service for remotely calling secure lock on the device.
+ *
+ * Callers will access this class via
+ * {@link com.android.server.security.authenticationpolicy.AuthenticationPolicyService}.
+ *
+ * @see AuthenticationPolicyService
+ * @see AuthenticationPolicyManager#enableSecureLockDevice
+ * @see AuthenticationPolicyManager#disableSecureLockDevice
+ * @hide
+ */
+public class SecureLockDeviceService extends SecureLockDeviceServiceInternal {
+ private static final String TAG = "SecureLockDeviceService";
+ private final Context mContext;
+
+ public SecureLockDeviceService(@NonNull Context context) {
+ mContext = context;
+ }
+
+ private void start() {
+ // Expose private service for system components to use.
+ LocalServices.addService(SecureLockDeviceServiceInternal.class, this);
+ }
+
+ /**
+ * @see AuthenticationPolicyManager#enableSecureLockDevice
+ * @param params EnableSecureLockDeviceParams for caller to supply params related
+ * to the secure lock device request
+ * @return @EnableSecureLockDeviceRequestStatus int indicating the result of the
+ * secure lock device request
+ *
+ * @hide
+ */
+ @Override
+ @EnableSecureLockDeviceRequestStatus
+ public int enableSecureLockDevice(EnableSecureLockDeviceParams params) {
+ // (1) Call into system_server to lock device, configure allowed auth types
+ // for secure lock
+ // TODO: lock device, configure allowed authentication types for device entry
+ // (2) Call into framework to configure secure lock 2FA lockscreen
+ // update, UI & string updates
+ // TODO: implement 2FA lockscreen when SceneContainerFlag.isEnabled()
+ // TODO: implement 2FA lockscreen when !SceneContainerFlag.isEnabled()
+ // (3) Call into framework to configure keyguard security updates
+ // TODO: implement security updates
+ return AuthenticationPolicyManager.ERROR_UNSUPPORTED;
+ }
+
+ /**
+ * @see AuthenticationPolicyManager#disableSecureLockDevice
+ * @param params @DisableSecureLockDeviceParams for caller to supply params related
+ * to the secure lock device request
+ * @return @DisableSecureLockDeviceRequestStatus int indicating the result of the
+ * secure lock device request
+ *
+ * @hide
+ */
+ @Override
+ @DisableSecureLockDeviceRequestStatus
+ public int disableSecureLockDevice(DisableSecureLockDeviceParams params) {
+ // (1) Call into system_server to reset allowed auth types
+ // TODO: reset allowed authentication types for device entry;
+ // (2) Call into framework to disable secure lock 2FA lockscreen, reset UI
+ // & string updates
+ // TODO: implement reverting to normal lockscreen when SceneContainerFlag.isEnabled()
+ // TODO: implement reverting to normal lockscreen when !SceneContainerFlag.isEnabled()
+ // (3) Call into framework to revert keyguard security updates
+ // TODO: implement reverting security updates
+ return AuthenticationPolicyManager.ERROR_UNSUPPORTED;
+ }
+
+ /**
+ * System service lifecycle.
+ */
+ public static final class Lifecycle extends SystemService {
+ private final SecureLockDeviceService mService;
+
+ public Lifecycle(@NonNull Context context) {
+ super(context);
+ mService = new SecureLockDeviceService(context);
+ }
+
+ @Override
+ public void onStart() {
+ Slog.i(TAG, "Starting SecureLockDeviceService");
+ mService.start();
+ Slog.i(TAG, "Started SecureLockDeviceService");
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceServiceInternal.java b/services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceServiceInternal.java
new file mode 100644
index 000000000000..b90370956d8b
--- /dev/null
+++ b/services/core/java/com/android/server/security/authenticationpolicy/SecureLockDeviceServiceInternal.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.security.authenticationpolicy;
+
+import android.security.authenticationpolicy.AuthenticationPolicyManager;
+import android.security.authenticationpolicy.AuthenticationPolicyManager.DisableSecureLockDeviceRequestStatus;
+import android.security.authenticationpolicy.AuthenticationPolicyManager.EnableSecureLockDeviceRequestStatus;
+import android.security.authenticationpolicy.DisableSecureLockDeviceParams;
+import android.security.authenticationpolicy.EnableSecureLockDeviceParams;
+
+/**
+ * Local system service interface for {@link SecureLockDeviceService}.
+ *
+ * <p>No permission / argument checks will be performed inside.
+ * Callers must check the calling app permission and the calling package name.
+ *
+ * @hide
+ */
+public abstract class SecureLockDeviceServiceInternal {
+ private static final String TAG = "SecureLockDeviceServiceInternal";
+
+ /**
+ * @see AuthenticationPolicyManager#enableSecureLockDevice(EnableSecureLockDeviceParams)
+ * @param params EnableSecureLockDeviceParams for caller to supply params related
+ * to the secure lock request
+ * @return @EnableSecureLockDeviceRequestStatus int indicating the result of the
+ * secure lock request
+ */
+ @EnableSecureLockDeviceRequestStatus
+ public abstract int enableSecureLockDevice(EnableSecureLockDeviceParams params);
+
+ /**
+ * @see AuthenticationPolicyManager#disableSecureLockDevice(DisableSecureLockDeviceParams)
+ * @param params @DisableSecureLockDeviceParams for caller to supply params related
+ * to the secure lock device request
+ * @return @DisableSecureLockDeviceRequestStatus int indicating the result of the
+ * secure lock device request
+ */
+ @DisableSecureLockDeviceRequestStatus
+ public abstract int disableSecureLockDevice(DisableSecureLockDeviceParams params);
+}
diff --git a/services/core/java/com/android/server/security/forensic/OWNERS b/services/core/java/com/android/server/security/forensic/OWNERS
deleted file mode 100644
index 3bc3eb5d1412..000000000000
--- a/services/core/java/com/android/server/security/forensic/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file:platform/frameworks/base:main:/core/java/android/security/forensic/OWNERS
diff --git a/services/core/java/com/android/server/security/forensic/DataAggregator.java b/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
index cc473caa0ee7..06e9dcdcbedd 100644
--- a/services/core/java/com/android/server/security/forensic/DataAggregator.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/DataAggregator.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.security.forensic.ForensicEvent;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -30,22 +30,22 @@ import java.util.ArrayList;
import java.util.List;
public class DataAggregator {
- private static final String TAG = "Forensic DataAggregator";
+ private static final String TAG = "IntrusionDetection DataAggregator";
private static final int MSG_SINGLE_DATA = 0;
private static final int MSG_BATCH_DATA = 1;
private static final int MSG_DISABLE = 2;
private static final int STORED_EVENTS_SIZE_LIMIT = 1024;
- private final ForensicService mForensicService;
+ private final IntrusionDetectionService mIntrusionDetectionService;
private final ArrayList<DataSource> mDataSources;
private Context mContext;
- private List<ForensicEvent> mStoredEvents = new ArrayList<>();
+ private List<IntrusionDetectionEvent> mStoredEvents = new ArrayList<>();
private ServiceThread mHandlerThread;
private Handler mHandler;
- public DataAggregator(Context context, ForensicService forensicService) {
- mForensicService = forensicService;
+ public DataAggregator(Context context, IntrusionDetectionService intrusionDetectionService) {
+ mIntrusionDetectionService = intrusionDetectionService;
mContext = context;
mDataSources = new ArrayList<DataSource>();
}
@@ -83,14 +83,14 @@ public class DataAggregator {
/**
* DataSource calls it to transmit a single event.
*/
- public void addSingleData(ForensicEvent event) {
+ public void addSingleData(IntrusionDetectionEvent event) {
mHandler.obtainMessage(MSG_SINGLE_DATA, event).sendToTarget();
}
/**
* DataSource calls it to transmit list of events.
*/
- public void addBatchData(List<ForensicEvent> events) {
+ public void addBatchData(List<IntrusionDetectionEvent> events) {
mHandler.obtainMessage(MSG_BATCH_DATA, events).sendToTarget();
}
@@ -104,17 +104,17 @@ public class DataAggregator {
}
}
- private void onNewSingleData(ForensicEvent event) {
+ private void onNewSingleData(IntrusionDetectionEvent event) {
if (mStoredEvents.size() < STORED_EVENTS_SIZE_LIMIT) {
mStoredEvents.add(event);
} else {
- mForensicService.addNewData(mStoredEvents);
+ mIntrusionDetectionService.addNewData(mStoredEvents);
mStoredEvents = new ArrayList<>();
}
}
- private void onNewBatchData(List<ForensicEvent> events) {
- mForensicService.addNewData(events);
+ private void onNewBatchData(List<IntrusionDetectionEvent> events) {
+ mIntrusionDetectionService.addNewData(events);
}
private void onDisable() {
@@ -135,10 +135,10 @@ public class DataAggregator {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SINGLE_DATA:
- mDataAggregator.onNewSingleData((ForensicEvent) msg.obj);
+ mDataAggregator.onNewSingleData((IntrusionDetectionEvent) msg.obj);
break;
case MSG_BATCH_DATA:
- mDataAggregator.onNewBatchData((List<ForensicEvent>) msg.obj);
+ mDataAggregator.onNewBatchData((List<IntrusionDetectionEvent>) msg.obj);
break;
case MSG_DISABLE:
mDataAggregator.onDisable();
diff --git a/services/core/java/com/android/server/security/forensic/DataSource.java b/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
index da7ee210281b..0bc448245b76 100644
--- a/services/core/java/com/android/server/security/forensic/DataSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/DataSource.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
public interface DataSource {
/**
diff --git a/services/core/java/com/android/server/security/forensic/ForensicEventTransportConnection.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
index b85199ed9218..82f39b327cea 100644
--- a/services/core/java/com/android/server/security/forensic/ForensicEventTransportConnection.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
-import static android.Manifest.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE;
+import static android.Manifest.permission.BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE;
import android.content.ComponentName;
import android.content.Context;
@@ -27,8 +27,8 @@ import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.security.forensic.ForensicEvent;
-import android.security.forensic.IForensicEventTransport;
+import android.security.intrusiondetection.IIntrusionDetectionEventTransport;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import android.text.TextUtils;
import android.util.Slog;
@@ -40,20 +40,20 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-public class ForensicEventTransportConnection implements ServiceConnection {
- private static final String TAG = "ForensicEventTransportConnection";
+public class IntrusionDetectionEventTransportConnection implements ServiceConnection {
+ private static final String TAG = "IntrusionDetectionEventTransportConnection";
private static final long FUTURE_TIMEOUT_MILLIS = 60 * 1000; // 1 mins
private final Context mContext;
- private String mForensicEventTransportConfig;
- volatile IForensicEventTransport mService;
+ private String mIntrusionDetectionEventTransportConfig;
+ volatile IIntrusionDetectionEventTransport mService;
- public ForensicEventTransportConnection(Context context) {
+ public IntrusionDetectionEventTransportConnection(Context context) {
mContext = context;
mService = null;
}
/**
- * Initialize the ForensicEventTransport binder service.
+ * Initialize the IntrusionDetectionEventTransport binder service.
* @return Whether the initialization succeed.
*/
public boolean initialize() {
@@ -78,11 +78,11 @@ public class ForensicEventTransportConnection implements ServiceConnection {
}
/**
- * Add data to the ForensicEventTransport binder service.
- * @param data List of ForensicEvent.
+ * Add data to the IntrusionDetectionEventTransport binder service.
+ * @param data List of IntrusionDetectionEvent.
* @return Whether the data is added to the binder service.
*/
- public boolean addData(List<ForensicEvent> data) {
+ public boolean addData(List<IntrusionDetectionEvent> data) {
AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
try {
mService.addData(data, resultFuture);
@@ -119,15 +119,15 @@ public class ForensicEventTransportConnection implements ServiceConnection {
}
private boolean bindService() {
- mForensicEventTransportConfig = mContext.getString(
- com.android.internal.R.string.config_forensicEventTransport);
- if (TextUtils.isEmpty(mForensicEventTransportConfig)) {
- Slog.e(TAG, "config_forensicEventTransport is empty");
+ mIntrusionDetectionEventTransportConfig = mContext.getString(
+ com.android.internal.R.string.config_intrusionDetectionEventTransport);
+ if (TextUtils.isEmpty(mIntrusionDetectionEventTransportConfig)) {
+ Slog.e(TAG, "config_intrusionDetectionEventTransport is empty");
return false;
}
ComponentName serviceComponent =
- ComponentName.unflattenFromString(mForensicEventTransportConfig);
+ ComponentName.unflattenFromString(mIntrusionDetectionEventTransportConfig);
if (serviceComponent == null) {
Slog.e(TAG, "Can't get serviceComponent name");
return false;
@@ -136,10 +136,10 @@ public class ForensicEventTransportConnection implements ServiceConnection {
try {
ServiceInfo serviceInfo = mContext.getPackageManager().getServiceInfo(serviceComponent,
0 /* flags */);
- if (!BIND_FORENSIC_EVENT_TRANSPORT_SERVICE.equals(serviceInfo.permission)) {
+ if (!BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE.equals(serviceInfo.permission)) {
Slog.e(TAG, serviceComponent.flattenToShortString()
+ " is not declared with the permission "
- + "\"" + BIND_FORENSIC_EVENT_TRANSPORT_SERVICE + "\"");
+ + "\"" + BIND_INTRUSION_DETECTION_EVENT_TRANSPORT_SERVICE + "\"");
return false;
}
} catch (PackageManager.NameNotFoundException e) {
@@ -163,7 +163,7 @@ public class ForensicEventTransportConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- mService = IForensicEventTransport.Stub.asInterface(service);
+ mService = IIntrusionDetectionEventTransport.Stub.asInterface(service);
}
@Override
diff --git a/services/core/java/com/android/server/security/forensic/ForensicService.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionService.java
index 2be068fa2f83..0287b415b9c2 100644
--- a/services/core/java/com/android/server/security/forensic/ForensicService.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionService.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
-import static android.Manifest.permission.MANAGE_FORENSIC_STATE;
-import static android.Manifest.permission.READ_FORENSIC_STATE;
+import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
+import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
@@ -27,10 +27,10 @@ import android.os.Looper;
import android.os.Message;
import android.os.PermissionEnforcer;
import android.os.RemoteException;
-import android.security.forensic.ForensicEvent;
-import android.security.forensic.IForensicService;
-import android.security.forensic.IForensicServiceCommandCallback;
-import android.security.forensic.IForensicServiceStateCallback;
+import android.security.intrusiondetection.IIntrusionDetectionService;
+import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -43,8 +43,8 @@ import java.util.List;
/**
* @hide
*/
-public class ForensicService extends SystemService {
- private static final String TAG = "ForensicService";
+public class IntrusionDetectionService extends SystemService {
+ private static final String TAG = "IntrusionDetectionService";
private static final int MAX_STATE_CALLBACK_NUM = 16;
private static final int MSG_ADD_STATE_CALLBACK = 0;
@@ -53,39 +53,46 @@ public class ForensicService extends SystemService {
private static final int MSG_DISABLE = 3;
private static final int MSG_TRANSPORT = 4;
- private static final int STATE_UNKNOWN = IForensicServiceStateCallback.State.UNKNOWN;
- private static final int STATE_DISABLED = IForensicServiceStateCallback.State.DISABLED;
- private static final int STATE_ENABLED = IForensicServiceStateCallback.State.ENABLED;
+ private static final int STATE_UNKNOWN =
+ IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
+ private static final int STATE_DISABLED =
+ IIntrusionDetectionServiceStateCallback.State.DISABLED;
+ private static final int STATE_ENABLED =
+ IIntrusionDetectionServiceStateCallback.State.ENABLED;
- private static final int ERROR_UNKNOWN = IForensicServiceCommandCallback.ErrorCode.UNKNOWN;
+ private static final int ERROR_UNKNOWN =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.UNKNOWN;
private static final int ERROR_PERMISSION_DENIED =
- IForensicServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
private static final int ERROR_INVALID_STATE_TRANSITION =
- IForensicServiceCommandCallback.ErrorCode.INVALID_STATE_TRANSITION;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.INVALID_STATE_TRANSITION;
private static final int ERROR_TRANSPORT_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
private final Context mContext;
private final Handler mHandler;
- private final ForensicEventTransportConnection mForensicEventTransportConnection;
+ private final IntrusionDetectionEventTransportConnection
+ mIntrusionDetectionEventTransportConnection;
private final DataAggregator mDataAggregator;
private final BinderService mBinderService;
- private final ArrayList<IForensicServiceStateCallback> mStateCallbacks = new ArrayList<>();
+ private final ArrayList<IIntrusionDetectionServiceStateCallback> mStateCallbacks =
+ new ArrayList<>();
private volatile int mState = STATE_DISABLED;
- public ForensicService(@NonNull Context context) {
+ public IntrusionDetectionService(@NonNull Context context) {
this(new InjectorImpl(context));
}
@VisibleForTesting
- ForensicService(@NonNull Injector injector) {
+ IntrusionDetectionService(@NonNull Injector injector) {
super(injector.getContext());
mContext = injector.getContext();
mHandler = new EventHandler(injector.getLooper(), this);
- mForensicEventTransportConnection = injector.getForensicEventransportConnection();
+ mIntrusionDetectionEventTransportConnection =
+ injector.getIntrusionDetectionEventransportConnection();
mDataAggregator = injector.getDataAggregator(this);
mBinderService = new BinderService(this, injector.getPermissionEnforcer());
}
@@ -95,47 +102,48 @@ public class ForensicService extends SystemService {
mState = state;
}
- private static final class BinderService extends IForensicService.Stub {
- final ForensicService mService;
+ private static final class BinderService extends IIntrusionDetectionService.Stub {
+ final IntrusionDetectionService mService;
- BinderService(ForensicService service, @NonNull PermissionEnforcer permissionEnforcer) {
+ BinderService(IntrusionDetectionService service,
+ @NonNull PermissionEnforcer permissionEnforcer) {
super(permissionEnforcer);
mService = service;
}
@Override
- @EnforcePermission(READ_FORENSIC_STATE)
- public void addStateCallback(IForensicServiceStateCallback callback) {
+ @EnforcePermission(READ_INTRUSION_DETECTION_STATE)
+ public void addStateCallback(IIntrusionDetectionServiceStateCallback callback) {
addStateCallback_enforcePermission();
mService.mHandler.obtainMessage(MSG_ADD_STATE_CALLBACK, callback).sendToTarget();
}
@Override
- @EnforcePermission(READ_FORENSIC_STATE)
- public void removeStateCallback(IForensicServiceStateCallback callback) {
+ @EnforcePermission(READ_INTRUSION_DETECTION_STATE)
+ public void removeStateCallback(IIntrusionDetectionServiceStateCallback callback) {
removeStateCallback_enforcePermission();
mService.mHandler.obtainMessage(MSG_REMOVE_STATE_CALLBACK, callback).sendToTarget();
}
@Override
- @EnforcePermission(MANAGE_FORENSIC_STATE)
- public void enable(IForensicServiceCommandCallback callback) {
+ @EnforcePermission(MANAGE_INTRUSION_DETECTION_STATE)
+ public void enable(IIntrusionDetectionServiceCommandCallback callback) {
enable_enforcePermission();
mService.mHandler.obtainMessage(MSG_ENABLE, callback).sendToTarget();
}
@Override
- @EnforcePermission(MANAGE_FORENSIC_STATE)
- public void disable(IForensicServiceCommandCallback callback) {
+ @EnforcePermission(MANAGE_INTRUSION_DETECTION_STATE)
+ public void disable(IIntrusionDetectionServiceCommandCallback callback) {
disable_enforcePermission();
mService.mHandler.obtainMessage(MSG_DISABLE, callback).sendToTarget();
}
}
private static class EventHandler extends Handler {
- private final ForensicService mService;
+ private final IntrusionDetectionService mService;
- EventHandler(Looper looper, ForensicService service) {
+ EventHandler(Looper looper, IntrusionDetectionService service) {
super(looper);
mService = service;
}
@@ -146,7 +154,7 @@ public class ForensicService extends SystemService {
case MSG_ADD_STATE_CALLBACK:
try {
mService.addStateCallback(
- (IForensicServiceStateCallback) msg.obj);
+ (IIntrusionDetectionServiceStateCallback) msg.obj);
} catch (RemoteException e) {
Slog.e(TAG, "RemoteException", e);
}
@@ -154,27 +162,27 @@ public class ForensicService extends SystemService {
case MSG_REMOVE_STATE_CALLBACK:
try {
mService.removeStateCallback(
- (IForensicServiceStateCallback) msg.obj);
+ (IIntrusionDetectionServiceStateCallback) msg.obj);
} catch (RemoteException e) {
Slog.e(TAG, "RemoteException", e);
}
break;
case MSG_ENABLE:
try {
- mService.enable((IForensicServiceCommandCallback) msg.obj);
+ mService.enable((IIntrusionDetectionServiceCommandCallback) msg.obj);
} catch (RemoteException e) {
Slog.e(TAG, "RemoteException", e);
}
break;
case MSG_DISABLE:
try {
- mService.disable((IForensicServiceCommandCallback) msg.obj);
+ mService.disable((IIntrusionDetectionServiceCommandCallback) msg.obj);
} catch (RemoteException e) {
Slog.e(TAG, "RemoteException", e);
}
break;
case MSG_TRANSPORT:
- mService.transport((List<ForensicEvent>) msg.obj);
+ mService.transport((List<IntrusionDetectionEvent>) msg.obj);
break;
default:
Slog.w(TAG, "Unknown message: " + msg.what);
@@ -182,7 +190,8 @@ public class ForensicService extends SystemService {
}
}
- private void addStateCallback(IForensicServiceStateCallback callback) throws RemoteException {
+ private void addStateCallback(IIntrusionDetectionServiceStateCallback callback)
+ throws RemoteException {
for (int i = 0; i < mStateCallbacks.size(); i++) {
if (mStateCallbacks.get(i).asBinder() == callback.asBinder()) {
return;
@@ -192,7 +201,7 @@ public class ForensicService extends SystemService {
callback.onStateChange(mState);
}
- private void removeStateCallback(IForensicServiceStateCallback callback)
+ private void removeStateCallback(IIntrusionDetectionServiceStateCallback callback)
throws RemoteException {
for (int i = 0; i < mStateCallbacks.size(); i++) {
if (mStateCallbacks.get(i).asBinder() == callback.asBinder()) {
@@ -216,15 +225,16 @@ public class ForensicService extends SystemService {
}
}
- private void enable(IForensicServiceCommandCallback callback) throws RemoteException {
+ private void enable(IIntrusionDetectionServiceCommandCallback callback)
+ throws RemoteException {
if (mState == STATE_ENABLED) {
callback.onSuccess();
return;
}
- // TODO: temporarily disable the following for the CTS ForensicManagerTest.
+ // TODO: temporarily disable the following for the CTS IntrusionDetectionManagerTest.
// Enable it when the transport component is ready.
- // if (!mForensicEventTransportConnection.initialize()) {
+ // if (!mIntrusionDetectionEventTransportConnection.initialize()) {
// callback.onFailure(ERROR_TRANSPORT_UNAVAILABLE);
// return;
// }
@@ -235,15 +245,16 @@ public class ForensicService extends SystemService {
callback.onSuccess();
}
- private void disable(IForensicServiceCommandCallback callback) throws RemoteException {
+ private void disable(IIntrusionDetectionServiceCommandCallback callback)
+ throws RemoteException {
if (mState == STATE_DISABLED) {
callback.onSuccess();
return;
}
- // TODO: temporarily disable the following for the CTS ForensicManagerTest.
+ // TODO: temporarily disable the following for the CTS IntrusionDetectionManagerTest.
// Enable it when the transport component is ready.
- // mForensicEventTransportConnection.release();
+ // mIntrusionDetectionEventTransportConnection.release();
mDataAggregator.disable();
mState = STATE_DISABLED;
notifyStateMonitors();
@@ -251,27 +262,27 @@ public class ForensicService extends SystemService {
}
/**
- * Add a list of ForensicEvent.
+ * Add a list of IntrusionDetectionEvent.
*/
- public void addNewData(List<ForensicEvent> events) {
+ public void addNewData(List<IntrusionDetectionEvent> events) {
mHandler.obtainMessage(MSG_TRANSPORT, events).sendToTarget();
}
- private void transport(List<ForensicEvent> events) {
- mForensicEventTransportConnection.addData(events);
+ private void transport(List<IntrusionDetectionEvent> events) {
+ mIntrusionDetectionEventTransportConnection.addData(events);
}
@Override
public void onStart() {
try {
- publishBinderService(Context.FORENSIC_SERVICE, mBinderService);
+ publishBinderService(Context.INTRUSION_DETECTION_SERVICE, mBinderService);
} catch (Throwable t) {
- Slog.e(TAG, "Could not start the ForensicService.", t);
+ Slog.e(TAG, "Could not start the IntrusionDetectionService.", t);
}
}
@VisibleForTesting
- IForensicService getBinderService() {
+ IIntrusionDetectionService getBinderService() {
return mBinderService;
}
@@ -282,9 +293,9 @@ public class ForensicService extends SystemService {
Looper getLooper();
- ForensicEventTransportConnection getForensicEventransportConnection();
+ IntrusionDetectionEventTransportConnection getIntrusionDetectionEventransportConnection();
- DataAggregator getDataAggregator(ForensicService forensicService);
+ DataAggregator getDataAggregator(IntrusionDetectionService intrusionDetectionService);
}
private static final class InjectorImpl implements Injector {
@@ -314,13 +325,15 @@ public class ForensicService extends SystemService {
}
@Override
- public ForensicEventTransportConnection getForensicEventransportConnection() {
- return new ForensicEventTransportConnection(mContext);
+ public IntrusionDetectionEventTransportConnection
+ getIntrusionDetectionEventransportConnection() {
+ return new IntrusionDetectionEventTransportConnection(mContext);
}
@Override
- public DataAggregator getDataAggregator(ForensicService forensicService) {
- return new DataAggregator(mContext, forensicService);
+ public DataAggregator getDataAggregator(
+ IntrusionDetectionService intrusionDetectionService) {
+ return new DataAggregator(mContext, intrusionDetectionService);
}
}
}
diff --git a/services/core/java/com/android/server/security/intrusiondetection/OWNERS b/services/core/java/com/android/server/security/intrusiondetection/OWNERS
new file mode 100644
index 000000000000..05080670ca2c
--- /dev/null
+++ b/services/core/java/com/android/server/security/intrusiondetection/OWNERS
@@ -0,0 +1 @@
+file:platform/frameworks/base:main:/core/java/android/security/intrusiondetection/OWNERS
diff --git a/services/core/java/com/android/server/security/forensic/SecurityLogSource.java b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
index e1b49c42018b..226f9d879cab 100644
--- a/services/core/java/com/android/server/security/forensic/SecurityLogSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
import android.Manifest.permission;
import android.annotation.RequiresPermission;
import android.app.admin.DevicePolicyManager;
import android.app.admin.SecurityLog.SecurityEvent;
import android.content.Context;
-import android.security.forensic.ForensicEvent;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import java.util.List;
import java.util.concurrent.Executor;
@@ -31,7 +31,7 @@ import java.util.stream.Collectors;
public class SecurityLogSource implements DataSource {
- private static final String TAG = "Forensic SecurityLogSource";
+ private static final String TAG = "IntrusionDetection SecurityLogSource";
private SecurityEventCallback mEventCallback = new SecurityEventCallback();
private DevicePolicyManager mDpm;
@@ -85,12 +85,12 @@ public class SecurityLogSource implements DataSource {
@Override
public void accept(List<SecurityEvent> events) {
- List<ForensicEvent> forensicEvents =
+ List<IntrusionDetectionEvent> intrusionDetectionEvents =
events.stream()
.filter(event -> event != null)
- .map(event -> new ForensicEvent(event))
+ .map(event -> new IntrusionDetectionEvent(event))
.collect(Collectors.toList());
- mDataAggregator.addBatchData(forensicEvents);
+ mDataAggregator.addBatchData(intrusionDetectionEvents);
}
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 4589d26261dc..8bcf1a9be031 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -21,6 +21,7 @@ import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
import static android.media.tv.flags.Flags.tifUnbindInactiveTis;
import static android.media.tv.flags.Flags.kidsModeTvdbSharing;
+import static android.media.tv.flags.Flags.hdmiControlEnhancedBehavior;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -44,8 +45,10 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.graphics.Rect;
+import android.hardware.hdmi.HdmiClient;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.HdmiTvClient;
import android.media.AudioPresentation;
import android.media.PlaybackParams;
import android.media.tv.AdBuffer;
@@ -138,6 +141,8 @@ public final class TvInputManagerService extends SystemService {
private static final String PERMISSION_ACCESS_WATCHED_PROGRAMS =
"com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS";
private static final long UPDATE_HARDWARE_TIS_BINDING_DELAY_IN_MILLIS = 10 * 1000; // 10 seconds
+ private static final long SET_TV_AS_ACTIVE_SOURCE_IF_NO_REQUEST_DELAY_IN_MILLIS
+ = 10 * 1000; // 10 seconds
// There are two different formats of DVB frontend devices. One is /dev/dvb%d.frontend%d,
// another one is /dev/dvb/adapter%d/frontend%d. Followings are the patterns for selecting the
@@ -185,6 +190,8 @@ public final class TvInputManagerService extends SystemService {
private final HashSet<String> mExternalInputLoggingDeviceOnScreenDisplayNames =
new HashSet<String>();
private final List<String> mExternalInputLoggingDeviceBrandNames = new ArrayList<String>();
+ private HdmiControlManager mHdmiControlManager = null;
+ private HdmiTvClient mHdmiTvClient = null;
public TvInputManagerService(Context context) {
super(context);
@@ -197,7 +204,12 @@ public final class TvInputManagerService extends SystemService {
mActivityManager =
(ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-
+ mHdmiControlManager = mContext.getSystemService(HdmiControlManager.class);
+ if (mHdmiControlManager == null) {
+ Slog.w(TAG, "HdmiControlManager is null!");
+ } else {
+ mHdmiTvClient = mHdmiControlManager.getTvClient();
+ }
synchronized (mLock) {
getOrCreateUserStateLocked(mCurrentUserId);
}
@@ -208,6 +220,42 @@ public final class TvInputManagerService extends SystemService {
@Override
public void onStart() {
publishBinderService(Context.TV_INPUT_SERVICE, new BinderService());
+
+ if (!hdmiControlEnhancedBehavior()) {
+ return;
+ }
+
+ // To ensure the TV claims CEC active source status correctly, a receiver is registered to
+ // monitor wake-up and sleep intents. Upon wake-up, this receiver sends a delayed message
+ // triggering a TIF call into a CEC API to claim TV as the active source.
+ // However, the API call is cancelled if the TV switches inputs or goes to sleep.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ switch (action) {
+ case Intent.ACTION_SCREEN_ON:
+ Slog.w(TAG, "The TV woke up.");
+ mMessageHandler.removeMessages(
+ MessageHandler.MSG_CHECK_TV_AS_ACTIVE_SOURCE);
+ Message msg = mMessageHandler
+ .obtainMessage(MessageHandler.MSG_CHECK_TV_AS_ACTIVE_SOURCE);
+ mMessageHandler.sendMessageDelayed(msg,
+ SET_TV_AS_ACTIVE_SOURCE_IF_NO_REQUEST_DELAY_IN_MILLIS);
+ break;
+ case Intent.ACTION_SCREEN_OFF:
+ Slog.w(TAG, "The TV turned off.");
+ mMessageHandler.removeMessages(
+ MessageHandler.MSG_CHECK_TV_AS_ACTIVE_SOURCE);
+ break;
+ default:
+ return;
+ }
+ }
+ }, filter);
}
@Override
@@ -4503,6 +4551,7 @@ public final class TvInputManagerService extends SystemService {
static final int MSG_LOG_WATCH_END = 2;
static final int MSG_SWITCH_CONTENT_RESOLVER = 3;
static final int MSG_UPDATE_HARDWARE_TIS_BINDING = 4;
+ static final int MSG_CHECK_TV_AS_ACTIVE_SOURCE = 5;
private ContentResolver mContentResolver;
@@ -4575,8 +4624,27 @@ public final class TvInputManagerService extends SystemService {
args.recycle();
}
break;
+ case MSG_CHECK_TV_AS_ACTIVE_SOURCE:
+ synchronized (mLock) {
+ if (mOnScreenInputId == null) {
+ assertTvAsCecActiveSourceLocked();
+ break;
+ }
+ // TV that switched to a different input, but not an HDMI input
+ // (e.g. composite) can also assert active source.
+ UserState userState = getOrCreateUserStateLocked(mCurrentUserId);
+ TvInputState inputState = userState.inputMap.get(mOnScreenInputId);
+ if (inputState == null) {
+ Slog.w(TAG, "Unexpected null TvInputState.");
+ break;
+ }
+ if (inputState.info.getType() != TvInputInfo.TYPE_HDMI) {
+ assertTvAsCecActiveSourceLocked();
+ }
+ }
+ break;
default: {
- Slog.w(TAG, "unhandled message code: " + msg.what);
+ Slog.w(TAG, "Unhandled message code: " + msg.what);
break;
}
}
@@ -4822,6 +4890,30 @@ public final class TvInputManagerService extends SystemService {
}
}
+ @GuardedBy("mLock")
+ private void assertTvAsCecActiveSourceLocked() {
+ if (mHdmiTvClient == null) {
+ Slog.w(TAG, "HdmiTvClient is null!");
+ return;
+ }
+ mHdmiTvClient.selectDevice(HdmiDeviceInfo.DEVICE_TV,
+ mContext.getMainExecutor(),
+ new HdmiClient.OnDeviceSelectedListener() {
+ @Override
+ public void onDeviceSelected(int result,
+ int logicalAddress) {
+ if (result == HdmiControlManager.RESULT_SUCCESS) {
+ Slog.w(TAG,
+ "Setting TV as the active CEC device was successful.");
+ } else {
+ Slog.w(TAG,
+ "Setting TV as the active CEC device failed with result "
+ + result);
+ }
+ }
+ });
+ }
+
private static class SessionNotFoundException extends IllegalArgumentException {
public SessionNotFoundException(String name) {
super(name);
diff --git a/services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java b/services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java
new file mode 100644
index 000000000000..54ae047a2858
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/BasicToPwleSegmentAdapter.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.vibrator.IVibrator;
+import android.os.VibratorInfo;
+import android.os.vibrator.BasicPwleSegment;
+import android.os.vibrator.Flags;
+import android.os.vibrator.PwleSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.MathUtils;
+import android.util.Pair;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Adapts {@link BasicPwleSegment} instances to device-specific {@link PwleSegment}
+ * representations, considering device capabilities such as the supported frequency range
+ * (defined by the intersection points of the frequency-acceleration response curve with the
+ * minimum sensitivity threshold) and the maximum achievable sensitivity level.
+ *
+ * <p>The segments will not be changed if the device doesn't have
+ * {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ */
+final class BasicToPwleSegmentAdapter implements VibrationSegmentsAdapter {
+ private static final String TAG = "BasicToPwleSegmentAdapter";
+ private static final int MIN_REQUIRED_SENSITIVITY_DB_SL = 10;
+ /**
+ * An array of (frequency in Hz, minimum perceptible acceleration in dB) pairs.
+ * Each pair represents the minimum output level (in dB) required for a human to perceive the
+ * vibration at the corresponding frequency.
+ */
+ private static final Pair<Float, Float>[] MIN_PERCEPTIBLE_CURVE = new Pair[]{
+ Pair.create(0.4f, -97.81f), Pair.create(2.0f, -69.86f),
+ Pair.create(3.0f, -62.81f), Pair.create(4.0f, -58.81f),
+ Pair.create(5.0f, -56.69f), Pair.create(6.0f, -54.77f),
+ Pair.create(7.2f, -52.85f), Pair.create(8.0f, -51.77f),
+ Pair.create(8.64f, -50.84f), Pair.create(10.0f, -48.90f),
+ Pair.create(10.37f, -48.52f), Pair.create(12.44f, -46.50f),
+ Pair.create(14.93f, -44.43f), Pair.create(15.0f, -44.35f),
+ Pair.create(17.92f, -41.96f), Pair.create(20.0f, -40.36f),
+ Pair.create(21.5f, -39.60f), Pair.create(25.0f, -37.48f),
+ Pair.create(25.8f, -36.93f), Pair.create(30.0f, -34.31f),
+ Pair.create(35.0f, -33.13f), Pair.create(40.0f, -32.81f),
+ Pair.create(50.0f, -31.94f), Pair.create(60.0f, -31.77f),
+ Pair.create(70.0f, -31.59f), Pair.create(72.0f, -31.55f),
+ Pair.create(80.0f, -31.77f), Pair.create(86.4f, -31.94f),
+ Pair.create(90.0f, -31.73f), Pair.create(100.0f, -31.90f),
+ Pair.create(103.68f, -31.77f), Pair.create(124.42f, -31.70f),
+ Pair.create(149.3f, -31.38f), Pair.create(150.0f, -31.35f),
+ Pair.create(179.16f, -31.02f), Pair.create(200.0f, -30.86f),
+ Pair.create(215.0f, -30.35f), Pair.create(250.0f, -28.98f),
+ Pair.create(258.0f, -28.68f), Pair.create(300.0f, -26.81f),
+ Pair.create(400.0f, -19.81f)
+ };
+ private static final float[] sMinPerceptibleFrequenciesHz =
+ new float[MIN_PERCEPTIBLE_CURVE.length];
+ private static final float[] sMinPerceptibleAccelerationsDb =
+ new float[MIN_PERCEPTIBLE_CURVE.length];
+
+ BasicToPwleSegmentAdapter() {
+
+ // Sort the 'MIN_PERCEPTIBLE_LEVEL' data in ascending order based on the
+ // frequency values (first element of each pair).
+ Arrays.sort(MIN_PERCEPTIBLE_CURVE, Comparator.comparing(pair -> pair.first));
+
+ for (int i = 0; i < MIN_PERCEPTIBLE_CURVE.length; i++) {
+ sMinPerceptibleFrequenciesHz[i] = MIN_PERCEPTIBLE_CURVE[i].first;
+ sMinPerceptibleAccelerationsDb[i] = MIN_PERCEPTIBLE_CURVE[i].second;
+ }
+ }
+
+ @Override
+ public int adaptToVibrator(VibratorInfo info, List<VibrationEffectSegment> segments,
+ int repeatIndex) {
+ if (!Flags.normalizedPwleEffects()
+ || !info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ // The vibrator does not have PWLE v2 capability, so keep the segments unchanged.
+ return repeatIndex;
+ }
+
+ VibratorInfo.FrequencyProfile frequencyProfile = info.getFrequencyProfile();
+ float[] frequenciesHz = frequencyProfile.getFrequenciesHz();
+ float[] accelerationsGs = frequencyProfile.getOutputAccelerationsGs();
+
+ Pair<Float, Float> frequencyRangeHz = calculateFrequencyRangeHz(
+ Objects.requireNonNull(frequenciesHz), Objects.requireNonNull(accelerationsGs));
+
+ if (frequencyRangeHz == null) {
+ // Failed to retrieve frequency range, so keep the segments unchanged.
+ return repeatIndex;
+ }
+ float minFrequencyHz = frequencyRangeHz.first;
+ float maxFrequencyHz = frequencyRangeHz.second;
+ float maxSensitivityLevel = getMaxSensitivityLevel(frequenciesHz, accelerationsGs,
+ minFrequencyHz, maxFrequencyHz);
+
+ for (int i = 0; i < segments.size(); i++) {
+ VibrationEffectSegment segment = segments.get(i);
+ if (segment instanceof BasicPwleSegment basicPwleSegment) {
+ PwleSegment pwleSegment = convertBasicToPwleSegment(frequencyProfile,
+ basicPwleSegment, minFrequencyHz, maxFrequencyHz,
+ maxSensitivityLevel);
+ segments.set(i, pwleSegment);
+ }
+ }
+
+ return repeatIndex;
+ }
+
+ /**
+ * Returns the supported frequency range within which {@link BasicPwleSegment}s are created.
+ * This range, also referred to as the "sharpness range", is defined by the
+ * minimum and maximum frequencies where the actuator's output acceleration exceeds the minimum
+ * required sensitivity level.
+ *
+ * <p>The minimum frequency is the first point where the actuator's frequency to output
+ * acceleration response curve intersects the minimum sensitivity threshold. The maximum
+ * frequency is determined by the second intersection point, or the maximum available
+ * frequency if no second intersection exists.
+ *
+ * @return The supported frequency range, or null if the minimum frequency cannot be determined.
+ */
+ @Nullable
+ private static Pair<Float, Float> calculateFrequencyRangeHz(@NonNull float[] frequenciesHz,
+ @NonNull float[] accelerationsGs) {
+ float minFrequencyHz = Float.NaN;
+ float maxFrequencyHz = Float.NaN;
+
+ for (int i = 0; i < frequenciesHz.length; i++) {
+ float minAcceptableOutputAcceleration = convertSensitivityLevelToAccelerationGs(
+ MIN_REQUIRED_SENSITIVITY_DB_SL, frequenciesHz[i]);
+
+ if (Float.isNaN(minFrequencyHz)
+ && minAcceptableOutputAcceleration <= accelerationsGs[i]) {
+ if (i == 0) {
+ minFrequencyHz = frequenciesHz[0];
+ } else {
+ minFrequencyHz = MathUtils.constrainedMap(
+ frequenciesHz[i - 1], frequenciesHz[i],
+ accelerationsGs[i - 1], accelerationsGs[i],
+ minAcceptableOutputAcceleration);
+ } // Found the lower bound
+ } else if (!Float.isNaN(minFrequencyHz)
+ && minAcceptableOutputAcceleration >= accelerationsGs[i]) {
+ maxFrequencyHz = MathUtils.constrainedMap(
+ frequenciesHz[i - 1], frequenciesHz[i],
+ accelerationsGs[i - 1], accelerationsGs[i],
+ minAcceptableOutputAcceleration); // Found the upper bound
+ return new Pair<>(minFrequencyHz, maxFrequencyHz);
+ }
+ }
+
+ if (Float.isNaN(minFrequencyHz)) {
+ // Lower bound was not found
+ Slog.e(TAG,
+ "Failed to retrieve frequency range. A valid frequency range must be "
+ + "available to create envelope vibration effects.");
+ return null;
+ }
+
+ // If only the lower bound was found, set the upper bound to the maximum frequency.
+ maxFrequencyHz = frequenciesHz[frequenciesHz.length - 1];
+
+ return new Pair<>(minFrequencyHz, maxFrequencyHz);
+ }
+
+ /**
+ * Converts the {@link BasicPwleSegment} to its equivalent {@link PwleSegment} based on the
+ * devices capabilities.
+ */
+ private static PwleSegment convertBasicToPwleSegment(
+ @NonNull VibratorInfo.FrequencyProfile frequencyProfile,
+ @NonNull BasicPwleSegment basicPwleSegment, float minFrequencyHz, float maxFrequencyHz,
+ float maxSensitivityLevel) {
+
+ float startFrequency = convertSharpnessToFrequencyHz(basicPwleSegment.getStartSharpness(),
+ minFrequencyHz, maxFrequencyHz);
+ float endFrequency = convertSharpnessToFrequencyHz(basicPwleSegment.getEndSharpness(),
+ minFrequencyHz, maxFrequencyHz);
+
+ float startAmplitude = convertIntensityToAmplitude(frequencyProfile,
+ basicPwleSegment.getStartIntensity(), startFrequency, maxSensitivityLevel);
+ float endAmplitude = convertIntensityToAmplitude(frequencyProfile,
+ basicPwleSegment.getEndIntensity(), endFrequency, maxSensitivityLevel);
+
+ return new PwleSegment(startAmplitude, endAmplitude, startFrequency, endFrequency,
+ basicPwleSegment.getDuration());
+ }
+
+ /**
+ * Calculates the amplitude for the vibrator, ranging [0.0, 1.0], based on the desired
+ * intensity and the vibrator's capabilities at the specified frequency.
+ *
+ * <p>This method first converts the desired intensity to an equivalent acceleration value
+ * based on the maximum sensitivity level within the sharpness range. It then compares this
+ * desired acceleration to the maximum acceleration the vibrator can produce at the given
+ * frequency.
+ *
+ * <p>If the desired acceleration exceeds the vibrator's capability, the method returns
+ * 1.0 (maximum amplitude). Otherwise, it returns a normalized amplitude value, calculated as
+ * the ratio of the desired acceleration to the maximum available acceleration at the given
+ * frequency.
+ */
+ private static float convertIntensityToAmplitude(VibratorInfo.FrequencyProfile frequencyProfile,
+ float intensity, float frequencyHz, float maxSensitivityLevel) {
+ if (intensity == 0) {
+ // Zero intensity should map to zero amplitude (i.e. vibrator off)
+ // instead of 0 db SL (i.e. the minimum perceivable output).
+ // This is for consistency with waveform envelopes, to ensure effects
+ // are able to ramp from/to the vibrator off state.
+ return 0;
+ }
+
+ float desiredAcceleration = convertIntensityToAccelerationGs(intensity, frequencyHz,
+ maxSensitivityLevel);
+ float availableAcceleration = frequencyProfile.getOutputAccelerationGs(
+ frequencyHz);
+ return desiredAcceleration >= availableAcceleration ? 1.0f
+ : desiredAcceleration / availableAcceleration;
+ }
+
+ private static float getMaxSensitivityLevel(float[] frequenciesHz, float[] accelerationsGs,
+ float minFrequencyHz, float maxFrequencyHz) {
+ float maxAccelerationGs = Float.MIN_VALUE;
+ int maxAccelerationIndex = -1;
+ for (int i = 0; i < frequenciesHz.length; i++) {
+ float frequency = frequenciesHz[i];
+ if (frequency < minFrequencyHz) {
+ continue;
+ }
+ if (frequency > maxFrequencyHz) {
+ break;
+ }
+ if (accelerationsGs[i] > maxAccelerationGs) {
+ maxAccelerationGs = accelerationsGs[i];
+ maxAccelerationIndex = i;
+ }
+ }
+
+ return convertDecibelToSensitivityLevel(convertAccelerationToDecibel(maxAccelerationGs),
+ frequenciesHz[maxAccelerationIndex]);
+ }
+
+ private static float convertSharpnessToFrequencyHz(float sharpness, float minFrequencyHz,
+ float maxFrequencyHz) {
+ return minFrequencyHz + sharpness * (maxFrequencyHz - minFrequencyHz);
+ }
+
+ private static float convertIntensityToAccelerationGs(float intensity, float frequencyHz,
+ float maxSensitivityLevel) {
+ return convertSensitivityLevelToAccelerationGs(intensity * maxSensitivityLevel,
+ frequencyHz);
+ }
+
+ private static float convertSensitivityLevelToAccelerationGs(float sensitivityLevel,
+ float frequencyHz) {
+ return convertDecibelToAccelerationGs(
+ convertSensitivityLevelToDecibel(sensitivityLevel, frequencyHz));
+ }
+
+ private static float convertDecibelToAccelerationGs(float db) {
+ return (float) Math.pow(10, db / 20);
+ }
+
+ private static float convertSensitivityLevelToDecibel(float sensitivityLevel,
+ float frequencyHz) {
+ float minPerceptibleDbAtFrequency = getMinPerceptibleAccelerationDb(frequencyHz);
+ return sensitivityLevel + minPerceptibleDbAtFrequency;
+ }
+
+ private static float convertAccelerationToDecibel(float accelerationGs) {
+ return (float) (20 * Math.log10(accelerationGs));
+ }
+
+ private static float convertDecibelToSensitivityLevel(float db, float frequencyHz) {
+ float minPerceptibleDbAtFrequency = getMinPerceptibleAccelerationDb(frequencyHz);
+ return db - minPerceptibleDbAtFrequency;
+ }
+
+ /**
+ * Retrieves the minimum perceptible acceleration, in dB, for the specified frequency (hz).
+ */
+ private static float getMinPerceptibleAccelerationDb(float frequencyHz) {
+
+ if (frequencyHz <= sMinPerceptibleFrequenciesHz[0]) {
+ return sMinPerceptibleAccelerationsDb[0];
+ }
+ if (frequencyHz >= sMinPerceptibleFrequenciesHz[sMinPerceptibleFrequenciesHz.length - 1]) {
+ return sMinPerceptibleAccelerationsDb[sMinPerceptibleAccelerationsDb.length - 1];
+ }
+
+ int idx = Arrays.binarySearch(sMinPerceptibleFrequenciesHz, frequencyHz);
+ if (idx >= 0) {
+ return sMinPerceptibleAccelerationsDb[idx];
+ }
+ // This indicates that the value was not found in the list. Adjust index of the
+ // insertion point to be at the lower bound.
+ idx = -idx - 2;
+
+ return MathUtils.constrainedMap(
+ sMinPerceptibleAccelerationsDb[idx],
+ sMinPerceptibleAccelerationsDb[idx + 1],
+ sMinPerceptibleFrequenciesHz[idx], sMinPerceptibleFrequenciesHz[idx + 1],
+ frequencyHz);
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/DeviceAdapter.java b/services/core/java/com/android/server/vibrator/DeviceAdapter.java
index 370f212957cb..e4542b359476 100644
--- a/services/core/java/com/android/server/vibrator/DeviceAdapter.java
+++ b/services/core/java/com/android/server/vibrator/DeviceAdapter.java
@@ -67,6 +67,8 @@ final class DeviceAdapter implements CombinedVibration.VibratorAdapter {
new SplitSegmentsAdapter(),
// Clip amplitudes and frequencies of final segments based on device bandwidth curve
new ClippingAmplitudeAndFrequencyAdapter(),
+ // Convert BasicPwleSegments to PwleSegments based on device capabilities
+ new BasicToPwleSegmentAdapter(),
// Split Pwle segments based on their duration and device supported limits
new SplitPwleSegmentsAdapter()
);
diff --git a/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java b/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java
index 87369aaabe98..85ba38d60dde 100644
--- a/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java
+++ b/services/core/java/com/android/server/vibrator/PwleSegmentsValidator.java
@@ -18,20 +18,30 @@ package com.android.server.vibrator;
import android.hardware.vibrator.IVibrator;
import android.os.VibratorInfo;
+import android.os.vibrator.BasicPwleSegment;
import android.os.vibrator.PwleSegment;
import android.os.vibrator.VibrationEffectSegment;
import java.util.List;
/**
- * Validates Pwle segments to ensure they are compatible with the device's capabilities
- * and adhere to frequency constraints.
+ * Validates {@link PwleSegment} and {@link BasicPwleSegment} instances to ensure they are
+ * compatible with the device's capabilities.
*
- * <p>The validator verifies that each segment's start and end frequencies fall within
- * the supported range.
- *
- * <p>The segments will be considered invalid of the device does not have
- * {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ * <p>This validator performs the following checks:
+ * <ul>
+ * <li>For {@link PwleSegment}:
+ * <ul>
+ * <li>Verifies that the device supports {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ * <li>Verifies that each segment's start and end frequencies fall within the supported range.
+ * </ul>
+ * </li>
+ * <li>For {@link BasicPwleSegment}:
+ * <ul>
+ * <li>Verifies that the device supports {@link IVibrator#CAP_COMPOSE_PWLE_EFFECTS_V2}.
+ * </ul>
+ * </li>
+ * </ul>
*/
final class PwleSegmentsValidator implements VibrationSegmentsValidator {
@@ -43,16 +53,17 @@ final class PwleSegmentsValidator implements VibrationSegmentsValidator {
float maxFrequency = info.getFrequencyProfile().getMaxFrequencyHz();
for (VibrationEffectSegment segment : segments) {
- if (!(segment instanceof PwleSegment pwleSegment)) {
- continue;
- }
-
- if (!hasPwleCapability || pwleSegment.getStartFrequencyHz() < minFrequency
- || pwleSegment.getStartFrequencyHz() > maxFrequency
- || pwleSegment.getEndFrequencyHz() < minFrequency
- || pwleSegment.getEndFrequencyHz() > maxFrequency) {
+ if (segment instanceof BasicPwleSegment && !hasPwleCapability) {
return false;
}
+ if (segment instanceof PwleSegment pwleSegment) {
+ if (!hasPwleCapability || pwleSegment.getStartFrequencyHz() < minFrequency
+ || pwleSegment.getStartFrequencyHz() > maxFrequency
+ || pwleSegment.getEndFrequencyHz() < minFrequency
+ || pwleSegment.getEndFrequencyHz() > maxFrequency) {
+ return false;
+ }
+ }
}
return true;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 17a254ab85e9..ba0262a8bd19 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -194,12 +194,8 @@ public class WallpaperDataParser {
wallpaper.cropHint.set(0, 0, 0, 0);
wpdData.mPadding.set(0, 0, 0, 0);
wallpaper.name = "";
- if (liveWallpaperContentHandling()) {
- wallpaper.setDescription(new WallpaperDescription.Builder().setComponent(
- mImageWallpaper).build());
- } else {
- wallpaper.setComponent(mImageWallpaper);
- }
+ // TODO (b/379936272) Find a safe value for wallpaper component. mImageComponent
+ // does not work at least on some platforms.
} else {
if (wallpaper.wallpaperId <= 0) {
wallpaper.wallpaperId = makeWallpaperIdLocked();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index bf93f73cd3bc..f70dec175c06 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -630,8 +630,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// The locusId associated with this activity, if set.
private LocusId mLocusId;
- // Whether the activity is requesting to limit the system's educational dialogs
- public boolean mShouldLimitSystemEducationDialogs;
+ // The timestamp of the last request to show the "Open in browser" education
+ public long mRequestOpenInBrowserEducationTimestamp;
// Whether the activity was launched from a bubble.
private boolean mLaunchedFromBubble;
@@ -7342,9 +7342,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return mLocusId;
}
- void setLimitSystemEducationDialogs(boolean limitSystemEducationDialogs) {
- if (mShouldLimitSystemEducationDialogs == limitSystemEducationDialogs) return;
- mShouldLimitSystemEducationDialogs = limitSystemEducationDialogs;
+ void requestOpenInBrowserEducation() {
+ mRequestOpenInBrowserEducationTimestamp = System.currentTimeMillis();
final Task task = getTask();
if (task != null) {
final boolean force = isVisibleRequested() && this == task.getTopNonFinishingActivity();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 198e14a16500..8ff08187c698 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3915,12 +3915,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
- public void setLimitSystemEducationDialogs(
- IBinder appToken, boolean limitSystemEducationDialogs) {
+ public void requestOpenInBrowserEducation(IBinder appToken) {
synchronized (mGlobalLock) {
final ActivityRecord r = ActivityRecord.isInRootTaskLocked(appToken);
if (r != null) {
- r.setLimitSystemEducationDialogs(limitSystemEducationDialogs);
+ r.requestOpenInBrowserEducation();
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 4857b02eaf7c..70a8f563275f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -344,6 +344,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
private ActivityRecord mTopResumedActivity;
/**
+ * Cached value of the topmost resumed activity that reported to the client.
+ */
+ private ActivityRecord mLastReportedTopResumedActivity;
+
+ /**
* Flag indicating whether we're currently waiting for the previous top activity to handle the
* loss of the state and report back before making new activity top resumed.
*/
@@ -2287,15 +2292,13 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
* sent to the new top resumed activity.
*/
ActivityRecord updateTopResumedActivityIfNeeded(String reason) {
- if (!readyToResume()) {
- return mTopResumedActivity;
- }
final ActivityRecord prevTopActivity = mTopResumedActivity;
final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) {
if (topRootTask == null) {
// There's no focused task and there won't have any resumed activity either.
scheduleTopResumedActivityStateLossIfNeeded();
+ mTopResumedActivity = null;
}
if (mService.isSleepingLocked()) {
// There won't be a next resumed activity. The top process should still be updated
@@ -2339,25 +2342,27 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
/** Schedule current top resumed activity state loss */
private void scheduleTopResumedActivityStateLossIfNeeded() {
- if (mTopResumedActivity == null) {
+ if (mLastReportedTopResumedActivity == null) {
return;
}
// mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
// before the prevTopActivity one hasn't reported back yet. So server never sent the top
// resumed state change message to prevTopActivity.
- if (!mTopResumedActivityWaitingForPrev
- && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
- scheduleTopResumedStateLossTimeout(mTopResumedActivity);
+ if (!mTopResumedActivityWaitingForPrev && readyToResume()
+ && mLastReportedTopResumedActivity.scheduleTopResumedActivityChanged(
+ false /* onTop */)) {
+ scheduleTopResumedStateLossTimeout(mLastReportedTopResumedActivity);
mTopResumedActivityWaitingForPrev = true;
+ mLastReportedTopResumedActivity = null;
}
- mTopResumedActivity = null;
}
/** Schedule top resumed state change if previous top activity already reported back. */
private void scheduleTopResumedActivityStateIfNeeded() {
- if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {
+ if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev && readyToResume()) {
mTopResumedActivity.scheduleTopResumedActivityChanged(true /* onTop */);
+ mLastReportedTopResumedActivity = mTopResumedActivity;
}
}
@@ -2611,6 +2616,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
*/
void endDeferResume() {
mDeferResumeCount--;
+ if (readyToResume() && mLastReportedTopResumedActivity != null
+ && mTopResumedActivity != mLastReportedTopResumedActivity) {
+ scheduleTopResumedActivityStateLossIfNeeded();
+ }
}
/** @return True if resume can be called. */
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
index fbf9478b4fd9..9754595581a0 100644
--- a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
@@ -16,10 +16,9 @@
package com.android.server.wm;
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
@@ -33,7 +32,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.AppCompatUtils.isChangeEnabled;
import android.annotation.NonNull;
-import android.app.CameraCompatTaskInfo.FreeformCameraCompatMode;
import com.android.server.wm.utils.OptPropFactory;
import com.android.window.flags.Flags;
@@ -165,13 +163,13 @@ class AppCompatCameraOverrides {
*
* <p>The treatment is enabled when the following conditions are met:
* <ul>
- * <li>Property gating the camera compatibility free-form treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override.
+ * <li>Feature flag gating the camera compatibility free-form treatment is enabled.
+ * <li>Activity is opted in by the device manufacturer with override.
* </ul>
*/
boolean shouldApplyFreeformTreatmentForCameraCompat() {
- return Flags.enableCameraCompatForDesktopWindowing() && !isChangeEnabled(mActivityRecord,
- OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT);
+ return Flags.enableCameraCompatForDesktopWindowing() && isChangeEnabled(mActivityRecord,
+ OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT);
}
boolean isOverrideOrientationOnlyForCameraEnabled() {
@@ -202,22 +200,10 @@ class AppCompatCameraOverrides {
&& !mActivityRecord.shouldCreateAppCompatDisplayInsets();
}
- @FreeformCameraCompatMode
- int getFreeformCameraCompatMode() {
- return mAppCompatCameraOverridesState.mFreeformCameraCompatMode;
- }
-
- void setFreeformCameraCompatMode(@FreeformCameraCompatMode int freeformCameraCompatMode) {
- mAppCompatCameraOverridesState.mFreeformCameraCompatMode = freeformCameraCompatMode;
- }
-
static class AppCompatCameraOverridesState {
// Whether activity "refresh" was requested but not finished in
// ActivityRecord#activityResumedLocked following the camera compat force rotation in
// DisplayRotationCompatPolicy.
private boolean mIsRefreshRequested;
-
- @FreeformCameraCompatMode
- private int mFreeformCameraCompatMode = CAMERA_COMPAT_FREEFORM_NONE;
}
}
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index bce8c2be271e..852a0ac054f4 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -1016,7 +1016,8 @@ public class BackgroundActivityStartController {
}
if (state.mCallingUidHasNonAppVisibleWindow) {
return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW,
- /*background*/ false, "callingUid has non-app visible window");
+ /*background*/ false, "callingUid has non-app visible window "
+ + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mCallingUid));
}
// Don't abort if the callerApp or other processes of that uid are considered to be in the
// foreground.
@@ -1142,7 +1143,8 @@ public class BackgroundActivityStartController {
}
if (state.mRealCallingUidHasNonAppVisibleWindow) {
return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW,
- /*background*/ false, "realCallingUid has non-app visible window");
+ /*background*/ false, "realCallingUid has non-app visible window "
+ + mService.mActiveUids.getNonAppVisibleWindowDetails(state.mRealCallingUid));
}
// Don't abort if the realCallerApp or other processes of that uid are considered to be in
@@ -1894,20 +1896,8 @@ public class BackgroundActivityStartController {
(state.mOriginatingPendingIntent != null));
}
- if (finalVerdict.getRawCode() == BAL_ALLOW_GRACE_PERIOD) {
- if (state.realCallerExplicitOptInOrAutoOptIn()
- && state.mResultForRealCaller.allows()
- && state.mResultForRealCaller.getRawCode() != BAL_ALLOW_GRACE_PERIOD) {
- // real caller could allow with a different exemption
- } else if (state.callerExplicitOptInOrAutoOptIn() && state.mResultForCaller.allows()
- && state.mResultForCaller.getRawCode() != BAL_ALLOW_GRACE_PERIOD) {
- // caller could allow with a different exemption
- } else {
- // log to determine grace period length distribution
- Slog.wtf(TAG, "Activity start ONLY allowed by BAL_ALLOW_GRACE_PERIOD "
- + finalVerdict.mMessage + ": " + state);
- }
- }
+ logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_GRACE_PERIOD);
+ logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW);
if (balImprovedMetrics()) {
if (shouldLogStats(finalVerdict, state)) {
@@ -1946,6 +1936,30 @@ public class BackgroundActivityStartController {
return finalVerdict;
}
+ /**
+ * Logs details about the activity starts if the only reason it is allowed is the provided
+ * {@code balCode}.
+ */
+ private static void logIfOnlyAllowedBy(BalVerdict finalVerdict, BalState state, int balCode) {
+ if (finalVerdict.getRawCode() == balCode) {
+ if (state.realCallerExplicitOptInOrAutoOptIn()
+ && state.mResultForRealCaller != null
+ && state.mResultForRealCaller.allows()
+ && state.mResultForRealCaller.getRawCode() != balCode) {
+ // real caller could allow with a different exemption
+ } else if (state.callerExplicitOptInOrAutoOptIn()
+ && state.mResultForCaller != null
+ && state.mResultForCaller.allows()
+ && state.mResultForCaller.getRawCode() != balCode) {
+ // caller could allow with a different exemption
+ } else {
+ // log to determine grace period length distribution
+ Slog.wtf(TAG, "Activity start ONLY allowed by " + balCodeToString(balCode) + " "
+ + finalVerdict.mMessage + ": " + state);
+ }
+ }
+ }
+
@VisibleForTesting
boolean shouldLogStats(BalVerdict finalVerdict, BalState state) {
if (finalVerdict.getRawCode() == BAL_ALLOW_VISIBLE_WINDOW) {
diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
index 2a0252ab06fd..506477f67bfc 100644
--- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
+++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
@@ -38,7 +38,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.CameraCompatTaskInfo;
-import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.view.DisplayInfo;
import android.view.Surface;
@@ -46,7 +45,6 @@ import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.protolog.WmProtoLogGroups;
-import com.android.window.flags.Flags;
/**
* Policy for camera compatibility freeform treatment.
@@ -124,26 +122,6 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
return appBoundsChanged || displayRotationChanged;
}
- /**
- * Whether activity is eligible for camera compatibility free-form treatment.
- *
- * <p>The treatment is applied to a fixed-orientation camera activity in free-form windowing
- * mode. The treatment letterboxes or pillarboxes the activity to the expected orientation and
- * provides changes to the camera and display orientation signals to match those expected on a
- * portrait device in that orientation (for example, on a standard phone).
- *
- * <p>The treatment is enabled when the following conditions are met:
- * <ul>
- * <li>Property gating the camera compatibility free-form treatment is enabled.
- * <li>Activity isn't opted out by the device manufacturer with override.
- * </ul>
- */
- @VisibleForTesting
- boolean isCameraCompatForFreeformEnabledForActivity(@NonNull ActivityRecord activity) {
- return Flags.enableCameraCompatForDesktopWindowing() && !activity.info.isChangeEnabled(
- ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT);
- }
-
@Override
public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
@NonNull String cameraId) {
@@ -159,16 +137,10 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
}
cameraActivity.recomputeConfiguration();
- updateCameraCompatMode(cameraActivity);
cameraActivity.getTask().dispatchTaskInfoChangedIfNeeded(/* force= */ true);
cameraActivity.ensureActivityConfiguration(/* ignoreVisibility= */ false);
}
- private void updateCameraCompatMode(@NonNull ActivityRecord cameraActivity) {
- cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
- .setFreeformCameraCompatMode(getCameraCompatMode(cameraActivity));
- }
-
@Override
public boolean onCameraClosed(@NonNull String cameraId) {
// Top activity in the same task as the camera activity, or `null` if the task is
@@ -277,7 +249,8 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
boolean isTreatmentEnabledForActivity(@NonNull ActivityRecord activity,
boolean checkOrientation) {
int orientation = activity.getRequestedConfigurationOrientation();
- return isCameraCompatForFreeformEnabledForActivity(activity)
+ return activity.mAppCompatController.getAppCompatCameraOverrides()
+ .shouldApplyFreeformTreatmentForCameraCompat()
&& mCameraStateMonitor.isCameraRunningForActivity(activity)
&& (!checkOrientation || orientation != ORIENTATION_UNDEFINED)
&& activity.inFreeformWindowingMode()
diff --git a/services/core/java/com/android/server/wm/MirrorActiveUids.java b/services/core/java/com/android/server/wm/MirrorActiveUids.java
index b9aa9599babe..b7bf16257f24 100644
--- a/services/core/java/com/android/server/wm/MirrorActiveUids.java
+++ b/services/core/java/com/android/server/wm/MirrorActiveUids.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import android.app.ActivityManager.ProcessState;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import java.io.PrintWriter;
@@ -34,6 +35,8 @@ class MirrorActiveUids {
/** Uid -> number of non-app visible windows belong to the uid. */
private final SparseIntArray mNumNonAppVisibleWindowMap = new SparseIntArray();
+ /** Type -> Uid -> number of non-app visible windows for type/uid. */
+ private final SparseArray<SparseIntArray> mNumNonAppVisibleWindowMapByType = new SparseArray();
synchronized void onUidActive(int uid, int procState) {
mUidStates.put(uid, procState);
@@ -55,17 +58,31 @@ class MirrorActiveUids {
}
/** Called when the surface of non-application (exclude toast) window is shown or hidden. */
- synchronized void onNonAppSurfaceVisibilityChanged(int uid, boolean visible) {
- final int index = mNumNonAppVisibleWindowMap.indexOfKey(uid);
+ synchronized void onNonAppSurfaceVisibilityChanged(int uid, int type, boolean visible) {
+ updateCount(uid, visible, mNumNonAppVisibleWindowMap);
+ updateCount(uid, visible, getNumNonAppVisibleWindowMapByType(type));
+ }
+
+ private SparseIntArray getNumNonAppVisibleWindowMapByType(int type) {
+ SparseIntArray result = mNumNonAppVisibleWindowMapByType.get(type);
+ if (result == null) {
+ result = new SparseIntArray();
+ mNumNonAppVisibleWindowMapByType.append(type, result);
+ }
+ return result;
+ }
+
+ private void updateCount(int uid, boolean visible, SparseIntArray numNonAppVisibleWindowMap) {
+ final int index = numNonAppVisibleWindowMap.indexOfKey(uid);
if (index >= 0) {
- final int num = mNumNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1);
+ final int num = numNonAppVisibleWindowMap.valueAt(index) + (visible ? 1 : -1);
if (num > 0) {
- mNumNonAppVisibleWindowMap.setValueAt(index, num);
+ numNonAppVisibleWindowMap.setValueAt(index, num);
} else {
- mNumNonAppVisibleWindowMap.removeAt(index);
+ numNonAppVisibleWindowMap.removeAt(index);
}
} else if (visible) {
- mNumNonAppVisibleWindowMap.append(uid, 1);
+ numNonAppVisibleWindowMap.append(uid, 1);
}
}
@@ -78,6 +95,24 @@ class MirrorActiveUids {
return mNumNonAppVisibleWindowMap.get(uid) > 0;
}
+ /**
+ * Returns details about the windows that contribute to the result of
+ * {@link #hasNonAppVisibleWindow(int)}.
+ *
+ * @return a map of window type to count
+ */
+ synchronized SparseIntArray getNonAppVisibleWindowDetails(int uid) {
+ SparseIntArray result = new SparseIntArray();
+ for (int i = 0; i < mNumNonAppVisibleWindowMapByType.size(); i++) {
+ SparseIntArray numNonAppVisibleWindowMap = mNumNonAppVisibleWindowMapByType.valueAt(i);
+ int count = numNonAppVisibleWindowMap.get(uid);
+ if (count > 0) {
+ result.append(mNumNonAppVisibleWindowMapByType.keyAt(i), count);
+ }
+ }
+ return result;
+ }
+
synchronized void dump(PrintWriter pw, String prefix) {
pw.print(prefix + "NumNonAppVisibleWindowUidMap:[");
for (int i = mNumNonAppVisibleWindowMap.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 81a04af17703..f0e12fec3107 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -2025,22 +2025,9 @@ class RecentTasks {
// Fill in some deprecated values.
rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
rti.persistentId = rti.taskId;
- rti.lastSnapshotData.set(tr.mLastTaskSnapshotData);
if (!getTasksAllowed) {
Task.trimIneffectiveInfo(tr, rti);
}
-
- // Fill in organized child task info for the task created by organizer.
- if (tr.mCreatedByOrganizer) {
- for (int i = tr.getChildCount() - 1; i >= 0; i--) {
- final Task childTask = tr.getChildAt(i).asTask();
- if (childTask != null && childTask.isOrganized()) {
- final ActivityManager.RecentTaskInfo cti = new ActivityManager.RecentTaskInfo();
- childTask.fillTaskInfo(cti, true /* stripExtras */, tda);
- rti.childrenTaskInfos.add(cti);
- }
- }
- }
return rti;
}
diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
index e4c34ed52359..5ce8a32aa141 100644
--- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java
+++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
@@ -234,6 +234,12 @@ class RefreshRatePolicy {
return w.mFrameRateVote.reset();
}
+ // If insets animation is running, do not convey the preferred app refresh rate to let VRI
+ // to control the refresh rate.
+ if (w.isInsetsAnimationRunning()) {
+ return w.mFrameRateVote.reset();
+ }
+
// If the app set a preferredDisplayModeId, the preferred refresh rate is the refresh rate
// of that mode id.
if (refreshRateSwitchingType != SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY) {
@@ -272,7 +278,7 @@ class RefreshRatePolicy {
float getPreferredMinRefreshRate(WindowState w) {
// If app is animating, it's not able to control refresh rate because we want the animation
// to run in default refresh rate.
- if (w.isAnimationRunningSelfOrParent()) {
+ if (w.isAnimationRunningSelfOrParent() || w.isInsetsAnimationRunning()) {
return 0;
}
@@ -295,7 +301,7 @@ class RefreshRatePolicy {
float getPreferredMaxRefreshRate(WindowState w) {
// If app is animating, it's not able to control refresh rate because we want the animation
// to run in default refresh rate.
- if (w.isAnimationRunningSelfOrParent()) {
+ if (w.isAnimationRunningSelfOrParent() || w.isInsetsAnimationRunning()) {
return 0;
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 0f66b93ca273..07de489d9ff4 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -1012,4 +1012,15 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
}
}
+
+ @Override
+ public void notifyInsetsAnimationRunningStateChanged(IWindow window, boolean running) {
+ synchronized (mService.mGlobalLock) {
+ final WindowState win = mService.windowForClientLocked(this, window,
+ false /* throwOnError */);
+ if (win != null) {
+ win.notifyInsetsAnimationRunningStateChanged(running);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index dbc3b76c22a1..87e472ab7aa6 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -128,7 +128,6 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
-import android.app.ActivityManager.RecentTaskInfo.PersistedTaskSnapshotData;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
@@ -256,9 +255,6 @@ class Task extends TaskFragment {
private static final String ATTR_MIN_HEIGHT = "min_height";
private static final String ATTR_PERSIST_TASK_VERSION = "persist_task_version";
private static final String ATTR_WINDOW_LAYOUT_AFFINITY = "window_layout_affinity";
- private static final String ATTR_LAST_SNAPSHOT_TASK_SIZE = "last_snapshot_task_size";
- private static final String ATTR_LAST_SNAPSHOT_CONTENT_INSETS = "last_snapshot_content_insets";
- private static final String ATTR_LAST_SNAPSHOT_BUFFER_SIZE = "last_snapshot_buffer_size";
// How long to wait for all background Activities to redraw following a call to
// convertToTranslucent().
@@ -472,10 +468,6 @@ class Task extends TaskFragment {
// NOTE: This value needs to be persisted with each task
private TaskDescription mTaskDescription;
- // Information about the last snapshot that should be persisted with the task to allow SystemUI
- // to layout without loading all the task snapshots
- final PersistedTaskSnapshotData mLastTaskSnapshotData;
-
/** @see #setCanAffectSystemUiFlags */
private boolean mCanAffectSystemUiFlags = true;
@@ -635,14 +627,13 @@ class Task extends TaskFragment {
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
boolean _autoRemoveRecents, int _userId, int _effectiveUid,
String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity,
- TaskDescription _lastTaskDescription, PersistedTaskSnapshotData _lastSnapshotData,
- int taskAffiliation, int prevTaskId, int nextTaskId, int callingUid,
- String callingPackage, @Nullable String callingFeatureId, int resizeMode,
- boolean supportsPictureInPicture, boolean _realActivitySuspended,
- boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info,
- IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
- boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
- boolean _removeWithTaskOrganizer) {
+ TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
+ int nextTaskId, int callingUid, String callingPackage,
+ @Nullable String callingFeatureId, int resizeMode, boolean supportsPictureInPicture,
+ boolean _realActivitySuspended, boolean userSetupComplete, int minWidth, int minHeight,
+ ActivityInfo info, IVoiceInteractionSession _voiceSession,
+ IVoiceInteractor _voiceInteractor, boolean _createdByOrganizer, IBinder _launchCookie,
+ boolean _deferTaskAppear, boolean _removeWithTaskOrganizer) {
super(atmService, null /* fragmentToken */, _createdByOrganizer, false /* isEmbedded */);
mTaskId = _taskId;
@@ -652,9 +643,6 @@ class Task extends TaskFragment {
mTaskDescription = _lastTaskDescription != null
? _lastTaskDescription
: new TaskDescription();
- mLastTaskSnapshotData = _lastSnapshotData != null
- ? _lastSnapshotData
- : new PersistedTaskSnapshotData();
affinityIntent = _affinityIntent;
affinity = _affinity;
rootAffinity = _rootAffinity;
@@ -1212,20 +1200,23 @@ class Task extends TaskFragment {
@Override
void onResize() {
super.onResize();
- updateTaskLayerForFreeform();
+ onTaskBoundsChangedForFreeform();
}
@Override
void onMovedByResize() {
super.onMovedByResize();
- updateTaskLayerForFreeform();
+ onTaskBoundsChangedForFreeform();
}
- private void updateTaskLayerForFreeform() {
- if (!com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode()) {
+ private void onTaskBoundsChangedForFreeform() {
+ if (!isVisibleRequested() || !inFreeformWindowingMode()) {
return;
}
- if (!isVisibleRequested() || !inFreeformWindowingMode()) {
+
+ mAtmService.notifyTaskPersisterLocked(this, false /* flush */);
+
+ if (!com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode()) {
return;
}
mRootWindowContainer.invalidateTaskLayersAndUpdateOomAdjIfNeeded();
@@ -3111,7 +3102,6 @@ class Task extends TaskFragment {
}
void onSnapshotChanged(TaskSnapshot snapshot) {
- mLastTaskSnapshotData.set(snapshot);
mAtmService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(
mTaskId, snapshot);
}
@@ -3423,8 +3413,8 @@ class Task extends TaskFragment {
? top.getLastParentBeforePip().mTaskId : INVALID_TASK_ID;
info.shouldDockBigOverlays = top != null && top.shouldDockBigOverlays;
info.mTopActivityLocusId = top != null ? top.getLocusId() : null;
- info.isTopActivityLimitSystemEducationDialogs = top != null
- ? top.mShouldLimitSystemEducationDialogs : false;
+ info.topActivityRequestOpenInBrowserEducationTimestamp = top != null
+ ? top.mRequestOpenInBrowserEducationTimestamp : 0;
final Task parentTask = getParent() != null ? getParent().asTask() : null;
info.parentTaskId = parentTask != null && parentTask.mCreatedByOrganizer
? parentTask.mTaskId
@@ -3523,6 +3513,7 @@ class Task extends TaskFragment {
info.capturedLink = null;
info.capturedLinkTimestamp = 0;
+ info.topActivityRequestOpenInBrowserEducationTimestamp = 0;
}
@Nullable PictureInPictureParams getPictureInPictureParams() {
@@ -3989,19 +3980,6 @@ class Task extends TaskFragment {
out.attributeInt(null, ATTR_MIN_HEIGHT, mMinHeight);
out.attributeInt(null, ATTR_PERSIST_TASK_VERSION, PERSIST_TASK_VERSION);
- if (mLastTaskSnapshotData.taskSize != null) {
- out.attribute(null, ATTR_LAST_SNAPSHOT_TASK_SIZE,
- mLastTaskSnapshotData.taskSize.flattenToString());
- }
- if (mLastTaskSnapshotData.contentInsets != null) {
- out.attribute(null, ATTR_LAST_SNAPSHOT_CONTENT_INSETS,
- mLastTaskSnapshotData.contentInsets.flattenToString());
- }
- if (mLastTaskSnapshotData.bufferSize != null) {
- out.attribute(null, ATTR_LAST_SNAPSHOT_BUFFER_SIZE,
- mLastTaskSnapshotData.bufferSize.flattenToString());
- }
-
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
affinityIntent.saveToXml(out);
@@ -4068,7 +4046,6 @@ class Task extends TaskFragment {
int taskId = INVALID_TASK_ID;
final int outerDepth = in.getDepth();
TaskDescription taskDescription = new TaskDescription();
- PersistedTaskSnapshotData lastSnapshotData = new PersistedTaskSnapshotData();
int taskAffiliation = INVALID_TASK_ID;
int prevTaskId = INVALID_TASK_ID;
int nextTaskId = INVALID_TASK_ID;
@@ -4175,15 +4152,6 @@ class Task extends TaskFragment {
case ATTR_PERSIST_TASK_VERSION:
persistTaskVersion = Integer.parseInt(attrValue);
break;
- case ATTR_LAST_SNAPSHOT_TASK_SIZE:
- lastSnapshotData.taskSize = Point.unflattenFromString(attrValue);
- break;
- case ATTR_LAST_SNAPSHOT_CONTENT_INSETS:
- lastSnapshotData.contentInsets = Rect.unflattenFromString(attrValue);
- break;
- case ATTR_LAST_SNAPSHOT_BUFFER_SIZE:
- lastSnapshotData.bufferSize = Point.unflattenFromString(attrValue);
- break;
default:
if (!attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
Slog.w(TAG, "Task: Unknown attribute=" + attrName);
@@ -4277,7 +4245,6 @@ class Task extends TaskFragment {
.setLastTimeMoved(lastTimeOnTop)
.setNeverRelinquishIdentity(neverRelinquishIdentity)
.setLastTaskDescription(taskDescription)
- .setLastSnapshotData(lastSnapshotData)
.setTaskAffiliation(taskAffiliation)
.setPrevAffiliateTaskId(prevTaskId)
.setNextAffiliateTaskId(nextTaskId)
@@ -6443,7 +6410,6 @@ class Task extends TaskFragment {
private long mLastTimeMoved;
private boolean mNeverRelinquishIdentity;
private TaskDescription mLastTaskDescription;
- private PersistedTaskSnapshotData mLastSnapshotData;
private int mTaskAffiliation;
private int mPrevAffiliateTaskId = INVALID_TASK_ID;
private int mNextAffiliateTaskId = INVALID_TASK_ID;
@@ -6671,11 +6637,6 @@ class Task extends TaskFragment {
return this;
}
- private Builder setLastSnapshotData(PersistedTaskSnapshotData lastSnapshotData) {
- mLastSnapshotData = lastSnapshotData;
- return this;
- }
-
private Builder setOrigActivity(ComponentName origActivity) {
mOrigActivity = origActivity;
return this;
@@ -6824,7 +6785,7 @@ class Task extends TaskFragment {
return new Task(mAtmService, mTaskId, mIntent, mAffinityIntent, mAffinity,
mRootAffinity, mRealActivity, mOrigActivity, mRootWasReset, mAutoRemoveRecents,
mUserId, mEffectiveUid, mLastDescription, mLastTimeMoved,
- mNeverRelinquishIdentity, mLastTaskDescription, mLastSnapshotData,
+ mNeverRelinquishIdentity, mLastTaskDescription,
mTaskAffiliation, mPrevAffiliateTaskId, mNextAffiliateTaskId, mCallingUid,
mCallingPackage, mCallingFeatureId, mResizeMode, mSupportsPictureInPicture,
mRealActivitySuspended, mUserSetupComplete, mMinWidth, mMinHeight,
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 091896590b6b..c42aa37d847b 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -788,9 +788,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
deferResume = false;
// Already calls ensureActivityConfig
mService.mRootWindowContainer.ensureActivitiesVisible();
- if (!mService.mRootWindowContainer.resumeFocusedTasksTopActivities()) {
- mService.mTaskSupervisor.updateTopResumedActivityIfNeeded("endWCT-effects");
- }
+ mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
} else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
for (int i = haveConfigChanges.size() - 1; i >= 0; --i) {
haveConfigChanges.valueAt(i).forAllActivities(r -> {
@@ -816,10 +814,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
if (deferResume) {
mService.mTaskSupervisor.endDeferResume();
- // Transient launching the Recents via HIERARCHY_OP_TYPE_PENDING_INTENT directly
- // resume the Recents activity with no TRANSACT_EFFECTS_LIFECYCLE. Explicitly
- // checks if the top resumed activity should be updated after defer-resume ended.
- mService.mTaskSupervisor.updateTopResumedActivityIfNeeded("endWCT");
}
mService.continueWindowLayout();
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 81af78e5ce25..82947377d01e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -182,7 +182,6 @@ import static com.android.server.wm.WindowStateProto.UNRESTRICTED_KEEP_CLEAR_ARE
import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY;
import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES;
-import static com.android.window.flags.Flags.secureWindowState;
import static com.android.window.flags.Flags.surfaceTrustedOverlay;
import android.annotation.CallSuper;
@@ -213,6 +212,7 @@ 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;
@@ -793,6 +793,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
private final List<DrawHandler> mDrawHandlers = new ArrayList<>();
+ /**
+ * Indicates whether inset animations are currently running within the Window.
+ * This value is used by (@link com.android.server.wm.RefreshRatePolicy.java)
+ * to omit setting a frame rate on the WindowState. Insets Animation is unique in that
+ * sense that an app might drive an insets animation for a Window owned by a different
+ * app (such as IME). In that case, we need the app that drives the insets animation
+ * to be able to vote for high refresh rate from VRI.
+ */
+ private boolean mInsetsAnimationRunning;
+
private final Consumer<SurfaceControl.Transaction> mSeamlessRotationFinishedConsumer = t -> {
finishSeamlessRotation(t);
updateSurfacePosition(t);
@@ -1187,9 +1197,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (surfaceTrustedOverlay() && isWindowTrustedOverlay()) {
getPendingTransaction().setTrustedOverlay(mSurfaceControl, true);
}
- if (secureWindowState()) {
- getPendingTransaction().setSecure(mSurfaceControl, isSecureLocked());
- }
+ getPendingTransaction().setSecure(mSurfaceControl, isSecureLocked());
// All apps should be considered as occluding when computing TrustedPresentation Thresholds.
final boolean canOccludePresentation = !mSession.mCanAddInternalSystemWindow;
getPendingTransaction().setCanOccludePresentation(mSurfaceControl, canOccludePresentation);
@@ -3428,7 +3436,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
&& mAttrs.type != TYPE_PRIVATE_PRESENTATION
&& !(mAttrs.type == TYPE_PRESENTATION && isOnVirtualDisplay())
) {
- mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, shown);
+ mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid,
+ mAttrs.type, shown);
}
}
@@ -6174,21 +6183,28 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void setSecureLocked(boolean isSecure) {
ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isSecure=%b: %s", isSecure, getName());
- if (secureWindowState()) {
- if (mSurfaceControl == null) {
- return;
- }
- getPendingTransaction().setSecure(mSurfaceControl, isSecure);
- } else {
- if (mWinAnimator.mSurfaceControl == null) {
- return;
- }
- getPendingTransaction().setSecure(mWinAnimator.mSurfaceControl,
- isSecure);
+ if (mSurfaceControl == null) {
+ return;
}
+ getPendingTransaction().setSecure(mSurfaceControl, isSecure);
if (mDisplayContent != null) {
mDisplayContent.refreshImeSecureFlag(getSyncTransaction());
}
mWmService.scheduleAnimationLocked();
}
+
+ void notifyInsetsAnimationRunningStateChanged(boolean running) {
+ if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+ Trace.instant(TRACE_TAG_WINDOW_MANAGER,
+ TextUtils.formatSimple("%s: notifyInsetsAnimationRunningStateChanged(%s)",
+ getName(),
+ Boolean.toString(running)));
+ }
+ mInsetsAnimationRunning = running;
+ mWmService.scheduleAnimationLocked();
+ }
+
+ boolean isInsetsAnimationRunning() {
+ return mInsetsAnimationRunning;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a934eea690f7..0154d95d888d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -49,7 +49,6 @@ import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
import static com.android.server.wm.WindowSurfaceControllerProto.SHOWN;
-import static com.android.window.flags.Flags.secureWindowState;
import static com.android.window.flags.Flags.setScPropertiesInClient;
import android.content.Context;
@@ -310,12 +309,6 @@ class WindowStateAnimator {
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
- if (!secureWindowState()) {
- if (w.isSecureLocked()) {
- flags |= SurfaceControl.SECURE;
- }
- }
-
if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
flags |= SurfaceControl.SKIP_SCREENSHOT;
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index e38337540ad9..dece612c9424 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -2330,6 +2330,12 @@ static void nativeToggleCapsLock(JNIEnv* env, jobject nativeImplObj, jint device
im->getInputManager()->getReader().toggleCapsLockState(deviceId);
}
+static void resetLockedModifierState(JNIEnv* env, jobject nativeImplObj) {
+ NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+
+ im->getInputManager()->getReader().resetLockedModifierState();
+}
+
static void nativeDisplayRemoved(JNIEnv* env, jobject nativeImplObj, jint displayId) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
@@ -3134,6 +3140,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
{"verifyInputEvent", "(Landroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
(void*)nativeVerifyInputEvent},
{"toggleCapsLock", "(I)V", (void*)nativeToggleCapsLock},
+ {"resetLockedModifierState", "()V", (void*)resetLockedModifierState},
{"displayRemoved", "(I)V", (void*)nativeDisplayRemoved},
{"setFocusedApplication", "(ILandroid/view/InputApplicationHandle;)V",
(void*)nativeSetFocusedApplication},
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6292cbfad00b..dde213de1d40 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -19245,21 +19245,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- private boolean isAnyResetPasswordTokenActiveForUser(int userId) {
+ private boolean isAnyResetPasswordTokenActiveForUserLocked(int userId) {
return mDevicePolicyEngine
.getLocalPoliciesSetByAdmins(PolicyDefinition.RESET_PASSWORD_TOKEN, userId)
- .values()
+ .entrySet()
.stream()
- .anyMatch((p) -> isResetPasswordTokenActiveForUserLocked(p.getValue(), userId));
+ .anyMatch((e) -> {
+ EnforcingAdmin admin = e.getKey();
+ PolicyValue<Long> policyValue = e.getValue();
+ return isResetPasswordTokenActiveForUserLocked(policyValue.getValue(), userId)
+ && isEncryptionAware(admin.getPackageName(), userId);
+ });
}
private boolean isResetPasswordTokenActiveForUserLocked(
long passwordTokenHandle, int userHandle) {
- if (passwordTokenHandle != 0) {
- return mInjector.binderWithCleanCallingIdentity(() ->
+ return passwordTokenHandle != 0 && mInjector.binderWithCleanCallingIdentity(() ->
mLockPatternUtils.isEscrowTokenActive(passwordTokenHandle, userHandle));
- }
- return false;
}
@Override
@@ -21108,10 +21110,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()),
String.format(NOT_SYSTEM_CALLER_MSG,
"call canProfileOwnerResetPasswordWhenLocked"));
- if (Flags.resetPasswordWithTokenCoexistence()) {
- return isAnyResetPasswordTokenActiveForUser(userId);
- }
synchronized (getLockObject()) {
+ if (Flags.resetPasswordWithTokenCoexistence()) {
+ return isAnyResetPasswordTokenActiveForUserLocked(userId);
+ }
final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId);
DevicePolicyData policy = getUserData(userId);
if (poAdmin == null
@@ -21120,26 +21122,29 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy.mPasswordTokenHandle, userId)) {
return false;
}
- final ApplicationInfo poAppInfo;
- try {
- poAppInfo = mIPackageManager.getApplicationInfo(
- poAdmin.info.getPackageName(), 0 /* flags */, userId);
- } catch (RemoteException e) {
- Slogf.e(LOG_TAG, "Failed to query PO app info", e);
- return false;
- }
- if (poAppInfo == null) {
- Slogf.wtf(LOG_TAG, "Cannot find AppInfo for profile owner");
- return false;
- }
- if (!poAppInfo.isEncryptionAware()) {
- return false;
- }
- Slogf.d(LOG_TAG, "PO should be able to reset password from direct boot");
- return true;
+ return isEncryptionAware(poAdmin.info.getPackageName(), userId);
}
}
+ private boolean isEncryptionAware(String packageName, int userId) {
+ final ApplicationInfo poAppInfo;
+ try {
+ poAppInfo = mIPackageManager.getApplicationInfo(packageName, 0 /* flags */, userId);
+ } catch (RemoteException e) {
+ Slogf.e(LOG_TAG, "Failed to query PO / role holder's app info", e);
+ return false;
+ }
+ if (poAppInfo == null) {
+ Slogf.wtf(LOG_TAG, "Cannot find AppInfo for PO / role holder");
+ return false;
+ }
+ if (!poAppInfo.isEncryptionAware()) {
+ return false;
+ }
+ Slogf.d(LOG_TAG, "PO / role holder should be able to reset password from direct boot");
+ return true;
+ }
+
@Override
public String getEnrollmentSpecificId(String callerPackage) {
if (!mHasFeature) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index da478f38498b..82d49fcac305 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -27,6 +27,7 @@ import static android.system.OsConstants.O_CLOEXEC;
import static android.system.OsConstants.O_RDONLY;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
import static com.android.server.utils.TimingsTraceAndSlog.SYSTEM_SERVER_TIMING_TAG;
import static com.android.tradeinmode.flags.Flags.enableTradeInMode;
@@ -251,7 +252,8 @@ import com.android.server.security.KeyAttestationApplicationIdProviderService;
import com.android.server.security.KeyChainSystemService;
import com.android.server.security.advancedprotection.AdvancedProtectionService;
import com.android.server.security.authenticationpolicy.AuthenticationPolicyService;
-import com.android.server.security.forensic.ForensicService;
+import com.android.server.security.authenticationpolicy.SecureLockDeviceService;
+import com.android.server.security.intrusiondetection.IntrusionDetectionService;
import com.android.server.security.rkp.RemoteProvisioningService;
import com.android.server.selinux.SelinuxAuditLogsService;
import com.android.server.sensorprivacy.SensorPrivacyService;
@@ -1653,7 +1655,12 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
t.traceBegin("StartInputManagerService");
- inputManager = new InputManagerService(context);
+ if (inputManagerLifecycleSupport()) {
+ inputManager = mSystemServiceManager.startService(
+ InputManagerService.Lifecycle.class).getService();
+ } else {
+ inputManager = new InputManagerService(context);
+ }
t.traceEnd();
t.traceBegin("DeviceStateManagerService");
@@ -1674,8 +1681,10 @@ public final class SystemServer implements Dumpable {
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
| DUMP_FLAG_PROTO);
- ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
- /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
+ if (!inputManagerLifecycleSupport()) {
+ ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
+ /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
+ }
t.traceEnd();
t.traceBegin("SetWindowManagerService");
@@ -1763,8 +1772,8 @@ public final class SystemServer implements Dumpable {
if (!isWatch && !isTv && !isAutomotive
&& android.security.Flags.aflApi()) {
- t.traceBegin("StartForensicService");
- mSystemServiceManager.startService(ForensicService.class);
+ t.traceBegin("StartIntrusionDetectionService");
+ mSystemServiceManager.startService(IntrusionDetectionService.class);
t.traceEnd();
}
@@ -2659,6 +2668,12 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(AuthService.class);
t.traceEnd();
+ if (android.security.Flags.secureLockdown()) {
+ t.traceBegin("StartSecureLockDeviceService.Lifecycle");
+ mSystemServiceManager.startService(SecureLockDeviceService.Lifecycle.class);
+ t.traceEnd();
+ }
+
if (android.adaptiveauth.Flags.enableAdaptiveAuth()) {
t.traceBegin("StartAuthenticationPolicyService");
mSystemServiceManager.startService(AuthenticationPolicyService.class);
@@ -3062,7 +3077,10 @@ public final class SystemServer implements Dumpable {
if (com.android.ranging.flags.Flags.rangingStackEnabled()) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)
|| context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_RTT)) {
+ PackageManager.FEATURE_WIFI_RTT)
+ || (com.android.ranging.flags.Flags.rangingCsEnabled()
+ && context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING))) {
t.traceBegin("RangingService");
// TODO: b/375264320 - Remove after RELEASE_RANGING_STACK is ramped to next.
try {
@@ -3340,16 +3358,18 @@ public final class SystemServer implements Dumpable {
reportWtf("Notifying NetworkTimeService running", e);
}
t.traceEnd();
- t.traceBegin("MakeInputManagerServiceReady");
- try {
- // TODO(BT) Pass parameter to input manager
- if (inputManagerF != null) {
- inputManagerF.systemRunning();
+ if (!inputManagerLifecycleSupport()) {
+ t.traceBegin("MakeInputManagerServiceReady");
+ try {
+ // TODO(BT) Pass parameter to input manager
+ if (inputManagerF != null) {
+ inputManagerF.systemRunning();
+ }
+ } catch (Throwable e) {
+ reportWtf("Notifying InputManagerService running", e);
}
- } catch (Throwable e) {
- reportWtf("Notifying InputManagerService running", e);
+ t.traceEnd();
}
- t.traceEnd();
t.traceBegin("MakeTelephonyRegistryReady");
try {
if (telephonyRegistryF != null) {
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
index a547d0f94ea3..4e9fff230bac 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import static org.testng.Assert.expectThrows;
@@ -96,6 +97,7 @@ public class BackupManagerServiceRoboTest {
@UserIdInt private int mUserTwoId;
@Mock private UserBackupManagerService mUserSystemService;
@Mock private UserBackupManagerService mUserOneService;
+ @Mock private BackupAgentConnectionManager mUserOneBackupAgentConnectionManager;
@Mock private UserBackupManagerService mUserTwoService;
/** Setup */
@@ -116,6 +118,9 @@ public class BackupManagerServiceRoboTest {
mShadowContext.grantPermissions(BACKUP);
mShadowContext.grantPermissions(INTERACT_ACROSS_USERS_FULL);
+ when(mUserOneService.getBackupAgentConnectionManager()).thenReturn(
+ mUserOneBackupAgentConnectionManager);
+
ShadowBinder.setCallingUid(Process.SYSTEM_UID);
}
@@ -226,7 +231,7 @@ public class BackupManagerServiceRoboTest {
backupManagerService.agentConnected(mUserOneId, TEST_PACKAGE, agentBinder);
- verify(mUserOneService).agentConnected(TEST_PACKAGE, agentBinder);
+ verify(mUserOneBackupAgentConnectionManager).agentConnected(TEST_PACKAGE, agentBinder);
}
/** Test that the backup service does not route methods for non-registered users. */
@@ -239,7 +244,8 @@ public class BackupManagerServiceRoboTest {
backupManagerService.agentConnected(mUserTwoId, TEST_PACKAGE, agentBinder);
- verify(mUserOneService, never()).agentConnected(TEST_PACKAGE, agentBinder);
+ verify(mUserOneBackupAgentConnectionManager, never()).agentConnected(TEST_PACKAGE,
+ agentBinder);
}
/** Test that the backup service routes methods correctly to the user that requests it. */
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 7349c14ef62b..aeb1ba93f049 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
@@ -107,6 +107,7 @@ import com.android.internal.backup.IBackupTransport;
import com.android.internal.infra.AndroidFuture;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentConnectionManager;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.KeyValueBackupJob;
@@ -167,7 +168,6 @@ import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.stream.Stream;
-// TODO: Test agents timing out
@RunWith(RobolectricTestRunner.class)
@Config(
shadows = {
@@ -195,6 +195,7 @@ public class KeyValueBackupTaskTest {
@Mock private IBackupManagerMonitor mMonitor;
@Mock private OnTaskFinishedListener mListener;
@Mock private PackageManagerInternal mPackageManagerInternal;
+ @Mock private BackupAgentConnectionManager mBackupAgentConnectionManager;
private UserBackupManagerService mBackupManagerService;
private TransportData mTransport;
@@ -257,6 +258,8 @@ public class KeyValueBackupTaskTest {
when(mBackupManagerService.getBaseStateDir()).thenReturn(mBaseStateDir);
when(mBackupManagerService.getDataDir()).thenReturn(mDataDir);
when(mBackupManagerService.getBackupManagerBinder()).thenReturn(mBackupManager);
+ when(mBackupManagerService.getBackupAgentConnectionManager()).thenReturn(
+ mBackupAgentConnectionManager);
mBackupHandler = mBackupManagerService.getBackupHandler();
mShadowBackupLooper = shadowOf(mBackupHandler.getLooper());
@@ -749,7 +752,8 @@ public class KeyValueBackupTaskTest {
/**
* Agent unavailable means {@link
- * UserBackupManagerService#bindToAgentSynchronous(ApplicationInfo, int)} returns {@code null}.
+ * BackupAgentConnectionManager#bindToAgentSynchronous(ApplicationInfo, int, int)} returns
+ * {@code null}.
*
* @see #setUpAgent(PackageData)
*/
@@ -805,7 +809,7 @@ public class KeyValueBackupTaskTest {
TransportMock transportMock = setUpInitializedTransport(mTransport);
setUpAgent(PACKAGE_1);
doThrow(SecurityException.class)
- .when(mBackupManagerService)
+ .when(mBackupAgentConnectionManager)
.bindToAgentSynchronous(argThat(applicationInfo(PACKAGE_1)), anyInt(), anyInt());
KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
@@ -823,7 +827,7 @@ public class KeyValueBackupTaskTest {
TransportMock transportMock = setUpInitializedTransport(mTransport);
setUpAgent(PACKAGE_1);
doThrow(SecurityException.class)
- .when(mBackupManagerService)
+ .when(mBackupAgentConnectionManager)
.bindToAgentSynchronous(argThat(applicationInfo(PACKAGE_1)), anyInt(), anyInt());
KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1);
@@ -861,7 +865,7 @@ public class KeyValueBackupTaskTest {
runTask(task);
verify(mBackupManagerService).setWorkSource(null);
- verify(mBackupManagerService).unbindAgent(argThat(applicationInfo(PACKAGE_1)));
+ verify(mBackupAgentConnectionManager).unbindAgent(argThat(applicationInfo(PACKAGE_1)));
}
@Test
@@ -1097,7 +1101,7 @@ public class KeyValueBackupTaskTest {
runTask(task);
verify(agentMock.agentBinder).fail(any());
- verify(mBackupManagerService).unbindAgent(argThat(applicationInfo(PACKAGE_1)));
+ verify(mBackupAgentConnectionManager).unbindAgent(argThat(applicationInfo(PACKAGE_1)));
}
@Test
@@ -1418,7 +1422,8 @@ public class KeyValueBackupTaskTest {
.isEqualTo("newState".getBytes());
assertCleansUpFiles(mTransport, PM_PACKAGE);
// We don't unbind PM
- verify(mBackupManagerService, never()).unbindAgent(argThat(applicationInfo(PM_PACKAGE)));
+ verify(mBackupAgentConnectionManager, never()).unbindAgent(
+ argThat(applicationInfo(PM_PACKAGE)));
}
@Test
@@ -1439,7 +1444,8 @@ public class KeyValueBackupTaskTest {
runTask(task);
- verify(mBackupManagerService, never()).unbindAgent(argThat(applicationInfo(PM_PACKAGE)));
+ verify(mBackupAgentConnectionManager, never()).unbindAgent(
+ argThat(applicationInfo(PM_PACKAGE)));
}
@Test
@@ -1642,9 +1648,10 @@ public class KeyValueBackupTaskTest {
runTask(task);
- InOrder inOrder = inOrder(agentMock.agent, mBackupManagerService);
+ InOrder inOrder = inOrder(agentMock.agent, mBackupAgentConnectionManager);
inOrder.verify(agentMock.agent).onQuotaExceeded(anyLong(), eq(1234L));
- inOrder.verify(mBackupManagerService).unbindAgent(argThat(applicationInfo(PACKAGE_1)));
+ inOrder.verify(mBackupAgentConnectionManager).unbindAgent(
+ argThat(applicationInfo(PACKAGE_1)));
}
@Test
@@ -2634,12 +2641,12 @@ public class KeyValueBackupTaskTest {
doNothing().when(backupAgentBinder).fail(any());
if (packageData.available) {
doReturn(backupAgentBinder)
- .when(mBackupManagerService)
+ .when(mBackupAgentConnectionManager)
.bindToAgentSynchronous(argThat(applicationInfo(packageData)), anyInt(),
anyInt());
} else {
doReturn(null)
- .when(mBackupManagerService)
+ .when(mBackupAgentConnectionManager)
.bindToAgentSynchronous(argThat(applicationInfo(packageData)), anyInt(),
anyInt());
}
@@ -2976,7 +2983,7 @@ public class KeyValueBackupTaskTest {
private void assertCleansUpFilesAndAgent(TransportData transport, PackageData packageData) {
assertCleansUpFiles(transport, packageData);
- verify(mBackupManagerService).unbindAgent(argThat(applicationInfo(packageData)));
+ verify(mBackupAgentConnectionManager).unbindAgent(argThat(applicationInfo(packageData)));
}
private void assertCleansUpFiles(TransportData transport, PackageData packageData) {
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index 5bb6b19cd63e..d08715586580 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -194,7 +194,13 @@ public class InputMethodServiceTest {
() -> assertThat(mActivity.hideImeWithWindowInsetsController()).isTrue(),
true /* expected */,
false /* inputViewStarted */);
- assertThat(mInputMethodService.isInputViewShown()).isFalse();
+ if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+ // The IME visibility is only sent at the end of the animation. Therefore, we have to
+ // wait until the visibility was sent to the server and the IME window hidden.
+ eventually(() -> assertThat(mInputMethodService.isInputViewShown()).isFalse());
+ } else {
+ assertThat(mInputMethodService.isInputViewShown()).isFalse();
+ }
}
/**
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
index 5a59c57ddf28..14dce103fc90 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
@@ -21,8 +21,6 @@ import android.content.pm.PackageInstaller.SessionParams
import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DEFAULT
import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DENIED
import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED
-import android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED
-import android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_OPEN
import android.content.pm.PackageManager
import android.content.pm.verify.domain.DomainSet
import android.os.Parcel
@@ -32,14 +30,8 @@ import android.util.AtomicFile
import android.util.Slog
import android.util.Xml
import com.android.internal.os.BackgroundThread
-import com.android.server.pm.verify.pkg.VerifierController
import com.android.server.testutils.whenever
import com.google.common.truth.Truth.assertThat
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileNotFoundException
-import java.io.FileOutputStream
-import java.io.IOException
import libcore.io.IoUtils
import org.junit.Before
import org.junit.Rule
@@ -53,6 +45,11 @@ import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.io.IOException
@Presubmit
class PackageInstallerSessionTest {
@@ -199,9 +196,6 @@ class PackageInstallerSessionTest {
/* stagedSessionErrorCode */ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
/* stagedSessionErrorMessage */ "some error",
/* preVerifiedDomains */ DomainSet(setOf("com.foo", "com.bar")),
- /* VerifierController */ mock(VerifierController::class.java),
- /* initialVerificationPolicy */ VERIFICATION_POLICY_BLOCK_FAIL_OPEN,
- /* currentVerificationPolicy */ VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
/* installDependencyHelper */ null
)
}
@@ -257,7 +251,6 @@ class PackageInstallerSessionTest {
mTmpDir,
mock(PackageSessionProvider::class.java),
mock(SilentUpdatePolicy::class.java),
- mock(VerifierController::class.java),
mock(InstallDependencyHelper::class.java)
)
ret.add(session)
@@ -295,7 +288,6 @@ class PackageInstallerSessionTest {
assertThat(expected.installerPackageName).isEqualTo(actual.installerPackageName)
assertThat(expected.isMultiPackage).isEqualTo(actual.isMultiPackage)
assertThat(expected.isStaged).isEqualTo(actual.isStaged)
- assertThat(expected.forceVerification).isEqualTo(actual.forceVerification)
}
private fun assertEquals(
@@ -346,8 +338,6 @@ class PackageInstallerSessionTest {
assertThat(expected.childSessionIds).asList()
.containsExactlyElementsIn(actual.childSessionIds.toList())
assertThat(expected.preVerifiedDomains).isEqualTo(actual.preVerifiedDomains)
- assertThat(expected.initialVerificationPolicy).isEqualTo(actual.initialVerificationPolicy)
- assertThat(expected.currentVerificationPolicy).isEqualTo(actual.currentVerificationPolicy)
}
private fun assertInstallSourcesEquivalent(expected: InstallSource, actual: InstallSource) {
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
index 5da202f109d4..f5c0de034483 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
@@ -20,6 +20,7 @@ import static android.content.UriRelativeFilter.QUERY;
import static android.content.UriRelativeFilter.FRAGMENT;
import static android.content.UriRelativeFilterGroup.ACTION_ALLOW;
import static android.content.UriRelativeFilterGroup.ACTION_BLOCK;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS;
import static android.os.PatternMatcher.PATTERN_ADVANCED_GLOB;
import static android.os.PatternMatcher.PATTERN_LITERAL;
import static android.os.PatternMatcher.PATTERN_PREFIX;
@@ -111,6 +112,8 @@ import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageUserStateInternal;
+import com.google.android.collect.Sets;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -212,6 +215,30 @@ public class PackageParserTest {
}
@Test
+ public void testParse_withCache_hiddenApiAllowlist() throws Exception {
+ CachePackageNameParser pp = new CachePackageNameParser(null);
+
+ pp.setCacheDir(mTmpDir);
+ // The first parse will write this package to the cache.
+ pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
+
+ // Now attempt to parse the package again, should return the
+ // cached result.
+ ParsedPackage pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
+ true /* useCaches */);
+ assertEquals("cache_android", pkg.getPackageName());
+
+ // Create application info
+ pkg.hideAsFinal();
+ ApplicationInfo aInfo = PackageInfoUtils.generateApplicationInfo(pkg, 0,
+ PackageUserStateInternal.DEFAULT, 0, mockPkgSetting(pkg));
+
+ // verify ext flag for hidden APIs allowlist
+ assertEquals(PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS,
+ aInfo.privateFlagsExt & PRIVATE_FLAG_EXT_ALLOWLISTED_FOR_HIDDEN_APIS);
+ }
+
+ @Test
public void test_serializePackage() throws Exception {
try (PackageParser2 pp = PackageParserUtils.forParsingFileWithDefaults()) {
AndroidPackage pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
@@ -856,35 +883,37 @@ public class PackageParserTest {
*/
public static class CachePackageNameParser extends PackageParser2 {
- CachePackageNameParser(@Nullable File cacheDir) {
- super(null, null, null, new Callback() {
- @Override
- public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
- return true;
- }
+ private static final Callback CALLBACK = new Callback() {
+ @Override
+ public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
+ return true;
+ }
- @Override
- public boolean hasFeature(String feature) {
- return false;
- }
+ @Override
+ public boolean hasFeature(String feature) {
+ return false;
+ }
- @Override
- public Set<String> getHiddenApiWhitelistedApps() {
- return new ArraySet<>();
- }
+ @Override
+ public Set<String> getHiddenApiWhitelistedApps() {
+ return Sets.newArraySet("cache_android");
+ }
- @Override
- public Set<String> getInstallConstraintsAllowlist() {
- return new ArraySet<>();
- }
- });
+ @Override
+ public Set<String> getInstallConstraintsAllowlist() {
+ return new ArraySet<>();
+ }
+ };
+
+ CachePackageNameParser(@Nullable File cacheDir) {
+ super(null, null, null, CALLBACK);
if (cacheDir != null) {
setCacheDir(cacheDir);
}
}
void setCacheDir(@NonNull File cacheDir) {
- this.mCacher = new PackageCacher(cacheDir) {
+ this.mCacher = new PackageCacher(cacheDir, CALLBACK) {
@Override
public ParsedPackage fromCacheEntry(byte[] cacheEntry) {
ParsedPackage parsed = super.fromCacheEntry(cacheEntry);
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java
deleted file mode 100644
index 787fb5a4e524..000000000000
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerificationStatusTrackerTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.verify.pkg;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerificationStatusTrackerTest {
- private static final String TEST_PACKAGE_NAME = "com.foo";
- private static final long TEST_REQUEST_START_TIME = 100L;
- private static final long TEST_TIMEOUT_DURATION_MILLIS = TimeUnit.MINUTES.toMillis(1);
- private static final long TEST_TIMEOUT_EXTENDED_MILLIS = TimeUnit.MINUTES.toMillis(2);
- private static final long TEST_MAX_TIMEOUT_DURATION_MILLIS =
- TimeUnit.MINUTES.toMillis(10);
-
- @Mock
- VerifierController.Injector mInjector;
- private VerificationStatusTracker mTracker;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- when(mInjector.getVerificationRequestTimeoutMillis()).thenReturn(
- TEST_TIMEOUT_DURATION_MILLIS);
- when(mInjector.getMaxVerificationExtendedTimeoutMillis()).thenReturn(
- TEST_MAX_TIMEOUT_DURATION_MILLIS);
- // Mock time forward as the code continues to check for the current time
- when(mInjector.getCurrentTimeMillis())
- .thenReturn(TEST_REQUEST_START_TIME)
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 1)
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS)
- .thenReturn(TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS - 100)
- .thenReturn(TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS);
- mTracker = new VerificationStatusTracker(TEST_TIMEOUT_DURATION_MILLIS,
- TEST_MAX_TIMEOUT_DURATION_MILLIS, mInjector);
- }
-
- @Test
- public void testTimeout() {
- assertThat(mTracker.getTimeoutTime()).isEqualTo(
- TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS);
- // It takes two calls to set the timeout, because the timeout time hasn't been reached for
- // the first calls
- assertThat(mTracker.isTimeout()).isFalse();
- assertThat(mTracker.isTimeout()).isTrue();
- }
-
- @Test
- public void testTimeoutExtended() {
- assertThat(mTracker.getTimeoutTime()).isEqualTo(
- TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS);
- assertThat(mTracker.extendTimeRemaining(TEST_TIMEOUT_EXTENDED_MILLIS))
- .isEqualTo(TEST_TIMEOUT_EXTENDED_MILLIS);
- assertThat(mTracker.getTimeoutTime()).isEqualTo(
- TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS
- + TEST_TIMEOUT_EXTENDED_MILLIS);
-
- // It would take 3 calls to set the timeout, because the timeout time hasn't been reached
- // for the first 2 time checks, but querying the remaining time also does a time check.
- assertThat(mTracker.isTimeout()).isFalse();
- assertThat(mTracker.getRemainingTime()).isGreaterThan(0);
- assertThat(mTracker.isTimeout()).isTrue();
- assertThat(mTracker.getRemainingTime()).isEqualTo(0);
- }
-
- @Test
- public void testTimeoutExtendedExceedsMax() {
- assertThat(mTracker.getTimeoutTime()).isEqualTo(
- TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS);
- assertThat(mTracker.extendTimeRemaining(TEST_MAX_TIMEOUT_DURATION_MILLIS))
- .isEqualTo(TEST_MAX_TIMEOUT_DURATION_MILLIS - TEST_TIMEOUT_DURATION_MILLIS);
- assertThat(mTracker.getTimeoutTime()).isEqualTo(
- TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS);
- // It takes 4 calls to set the timeout, because the timeout time hasn't been reached for
- // the first 3 calls
- assertThat(mTracker.isTimeout()).isFalse();
- assertThat(mTracker.isTimeout()).isFalse();
- assertThat(mTracker.isTimeout()).isFalse();
- assertThat(mTracker.isTimeout()).isTrue();
- assertThat(mTracker.getRemainingTime()).isEqualTo(0);
- }
-}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java
deleted file mode 100644
index 3046d4beb7a3..000000000000
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/verify/pkg/VerifierControllerTest.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.pm.verify.pkg;
-
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-import static android.content.pm.PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_OPEN;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.expectThrows;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.SigningInfo;
-import android.content.pm.VersionedPackage;
-import android.content.pm.verify.pkg.IVerifierService;
-import android.content.pm.verify.pkg.VerificationSession;
-import android.content.pm.verify.pkg.VerificationStatus;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.platform.test.annotations.Presubmit;
-import android.util.Pair;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.internal.infra.AndroidFuture;
-import com.android.internal.infra.ServiceConnector;
-import com.android.server.pm.Computer;
-import com.android.server.pm.PackageInstallerSession;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class VerifierControllerTest {
- private static final int TEST_ID = 100;
- private static final String TEST_PACKAGE_NAME = "com.foo";
- private static final ComponentName TEST_VERIFIER_COMPONENT_NAME =
- new ComponentName("com.verifier", "com.verifier.Service");
- private static final Uri TEST_PACKAGE_URI = Uri.parse("test://test");
- private static final SigningInfo TEST_SIGNING_INFO = new SigningInfo();
- private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO1 =
- new SharedLibraryInfo("sharedLibPath1", TEST_PACKAGE_NAME,
- Collections.singletonList("path1"), "sharedLib1", 101,
- SharedLibraryInfo.TYPE_DYNAMIC, new VersionedPackage(TEST_PACKAGE_NAME, 1),
- null, null, false);
- private static final SharedLibraryInfo TEST_SHARED_LIBRARY_INFO2 =
- new SharedLibraryInfo("sharedLibPath2", TEST_PACKAGE_NAME,
- Collections.singletonList("path2"), "sharedLib2", 102,
- SharedLibraryInfo.TYPE_DYNAMIC,
- new VersionedPackage(TEST_PACKAGE_NAME, 2), null, null, false);
- private static final String TEST_KEY = "test key";
- private static final String TEST_VALUE = "test value";
- private static final String TEST_FAILURE_MESSAGE = "verification failed!";
- private static final long TEST_REQUEST_START_TIME = 0L;
- private static final long TEST_TIMEOUT_DURATION_MILLIS = TimeUnit.MINUTES.toMillis(1);
- private static final long TEST_MAX_TIMEOUT_DURATION_MILLIS =
- TimeUnit.MINUTES.toMillis(10);
- private static final long TEST_VERIFIER_CONNECTION_TIMEOUT_DURATION_MILLIS =
- TimeUnit.SECONDS.toMillis(10);
- private static final int TEST_POLICY = VERIFICATION_POLICY_BLOCK_FAIL_CLOSED;
-
- private final ArrayList<SharedLibraryInfo> mTestDeclaredLibraries = new ArrayList<>();
- private final PersistableBundle mTestExtensionParams = new PersistableBundle();
- @Mock
- Context mContext;
- @Mock
- Handler mHandler;
- @Mock
- VerifierController.Injector mInjector;
- @Mock
- ServiceConnector<IVerifierService> mMockServiceConnector;
- @Mock
- IVerifierService mMockService;
- @Mock
- Computer mSnapshot;
- Supplier<Computer> mSnapshotSupplier = () -> mSnapshot;
- @Mock
- PackageInstallerSession.VerifierCallback mSessionCallback;
-
- private VerifierController mVerifierController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- // Mock that the UID of this test becomes the UID of the verifier
- when(mSnapshot.getPackageUidInternal(anyString(), anyLong(), anyInt(), anyInt()))
- .thenReturn(InstrumentationRegistry.getInstrumentation().getContext()
- .getApplicationInfo().uid);
- when(mInjector.getVerifierPackageName(any(Computer.class), anyInt())).thenReturn(
- TEST_VERIFIER_COMPONENT_NAME.getPackageName());
- when(mInjector.getRemoteService(
- any(Computer.class), any(Context.class), anyInt(), any(Handler.class)
- )).thenReturn(new Pair<>(mMockServiceConnector, TEST_VERIFIER_COMPONENT_NAME));
- when(mInjector.getVerificationRequestTimeoutMillis()).thenReturn(
- TEST_TIMEOUT_DURATION_MILLIS);
- when(mInjector.getMaxVerificationExtendedTimeoutMillis()).thenReturn(
- TEST_MAX_TIMEOUT_DURATION_MILLIS);
- when(mInjector.getVerifierConnectionTimeoutMillis()).thenReturn(
- TEST_VERIFIER_CONNECTION_TIMEOUT_DURATION_MILLIS
- );
- // Mock time forward as the code continues to check for the current time
- when(mInjector.getCurrentTimeMillis())
- .thenReturn(TEST_REQUEST_START_TIME)
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS + 1);
- when(mMockServiceConnector.post(any(ServiceConnector.VoidJob.class)))
- .thenAnswer(
- i -> {
- ((ServiceConnector.VoidJob) i.getArguments()[0]).run(mMockService);
- return new AndroidFuture<>();
- });
- when(mMockServiceConnector.run(any(ServiceConnector.VoidJob.class)))
- .thenAnswer(
- i -> {
- ((ServiceConnector.VoidJob) i.getArguments()[0]).run(mMockService);
- return true;
- });
-
- mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO1);
- mTestDeclaredLibraries.add(TEST_SHARED_LIBRARY_INFO2);
- mTestExtensionParams.putString(TEST_KEY, TEST_VALUE);
-
- mVerifierController = new VerifierController(mContext, mHandler, mInjector);
- }
-
- @Test
- public void testVerifierNotInstalled() {
- when(mInjector.getVerifierPackageName(any(Computer.class), anyInt())).thenReturn(null);
- when(mInjector.getRemoteService(
- any(Computer.class), any(Context.class), anyInt(), any(Handler.class)
- )).thenReturn(null);
- assertThat(mVerifierController.getVerifierPackageName(mSnapshotSupplier, 0)).isNull();
- assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
- .isFalse();
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isFalse();
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ true)).isFalse();
- verifyZeroInteractions(mSessionCallback);
- }
-
- @Test
- public void testRebindService() {
- assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
- .isTrue();
- }
-
- @Test
- public void testVerifierAvailableButNotConnected() {
- assertThat(mVerifierController.getVerifierPackageName(mSnapshotSupplier, 0)).isNotNull();
- when(mInjector.getRemoteService(
- any(Computer.class), any(Context.class), anyInt(), any(Handler.class)
- )).thenReturn(null);
- assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
- .isFalse();
- // Test that nothing crashes if the verifier is available even though there's no bound
- mVerifierController.notifyPackageNameAvailable(TEST_PACKAGE_NAME);
- mVerifierController.notifyVerificationCancelled(TEST_PACKAGE_NAME);
- mVerifierController.notifyVerificationTimeout(-1);
- // Since there was no bound, no call is made to the verifier
- verifyZeroInteractions(mMockService);
- }
-
- @Test
- public void testUnbindService() throws Exception {
- ArgumentCaptor<ServiceConnector.ServiceLifecycleCallbacks> captor = ArgumentCaptor.forClass(
- ServiceConnector.ServiceLifecycleCallbacks.class);
- assertThat(mVerifierController.bindToVerifierServiceIfNeeded(mSnapshotSupplier, 0))
- .isTrue();
- verify(mMockServiceConnector).setServiceLifecycleCallbacks(captor.capture());
- ServiceConnector.ServiceLifecycleCallbacks<IVerifierService> callbacks = captor.getValue();
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mMockService, times(1)).onVerificationRequired(any(VerificationSession.class));
- callbacks.onBinderDied();
- // Test that nothing crashes if the service connection is lost
- assertThat(mVerifierController.getVerifierPackageName(mSnapshotSupplier, 0)).isNotNull();
- mVerifierController.notifyPackageNameAvailable(TEST_PACKAGE_NAME);
- mVerifierController.notifyVerificationCancelled(TEST_PACKAGE_NAME);
- mVerifierController.notifyVerificationTimeout(TEST_ID);
- verifyNoMoreInteractions(mMockService);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ true)).isTrue();
- mVerifierController.notifyVerificationTimeout(TEST_ID);
- verify(mMockService, times(1)).onVerificationTimeout(eq(TEST_ID));
- }
-
- @Test
- public void testNotifyPackageNameAvailable() throws Exception {
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- mVerifierController.notifyPackageNameAvailable(TEST_PACKAGE_NAME);
- verify(mMockService).onPackageNameAvailable(eq(TEST_PACKAGE_NAME));
- }
-
- @Test
- public void testNotifyVerificationCancelled() throws Exception {
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- mVerifierController.notifyVerificationCancelled(TEST_PACKAGE_NAME);
- verify(mMockService).onVerificationCancelled(eq(TEST_PACKAGE_NAME));
- }
-
- @Test
- public void testStartVerificationSession() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- assertThat(session.getId()).isEqualTo(TEST_ID);
- assertThat(session.getInstallSessionId()).isEqualTo(TEST_ID);
- assertThat(session.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(session.getStagedPackageUri()).isEqualTo(TEST_PACKAGE_URI);
- assertThat(session.getSigningInfo().getSigningDetails())
- .isEqualTo(TEST_SIGNING_INFO.getSigningDetails());
- List<SharedLibraryInfo> declaredLibraries = session.getDeclaredLibraries();
- // SharedLibraryInfo doesn't have a "equals" method, so we have to check it indirectly
- assertThat(declaredLibraries.getFirst().toString())
- .isEqualTo(TEST_SHARED_LIBRARY_INFO1.toString());
- assertThat(declaredLibraries.get(1).toString())
- .isEqualTo(TEST_SHARED_LIBRARY_INFO2.toString());
- // We can't directly test with PersistableBundle.equals() because the parceled bundle's
- // structure is different, but all the key/value pairs should be preserved as before.
- assertThat(session.getExtensionParams().getString(TEST_KEY))
- .isEqualTo(mTestExtensionParams.getString(TEST_KEY));
- }
-
- @Test
- public void testNotifyVerificationRetry() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ true)).isTrue();
- verify(mMockService).onVerificationRetry(captor.capture());
- VerificationSession session = captor.getValue();
- assertThat(session.getId()).isEqualTo(TEST_ID);
- assertThat(session.getInstallSessionId()).isEqualTo(TEST_ID);
- assertThat(session.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
- assertThat(session.getStagedPackageUri()).isEqualTo(TEST_PACKAGE_URI);
- assertThat(session.getSigningInfo().getSigningDetails())
- .isEqualTo(TEST_SIGNING_INFO.getSigningDetails());
- List<SharedLibraryInfo> declaredLibraries = session.getDeclaredLibraries();
- // SharedLibraryInfo doesn't have a "equals" method, so we have to check it indirectly
- assertThat(declaredLibraries.getFirst().toString())
- .isEqualTo(TEST_SHARED_LIBRARY_INFO1.toString());
- assertThat(declaredLibraries.get(1).toString())
- .isEqualTo(TEST_SHARED_LIBRARY_INFO2.toString());
- // We can't directly test with PersistableBundle.equals() because the parceled bundle's
- // structure is different, but all the key/value pairs should be preserved as before.
- assertThat(session.getExtensionParams().getString(TEST_KEY))
- .isEqualTo(mTestExtensionParams.getString(TEST_KEY));
- }
-
- @Test
- public void testNotifyVerificationTimeout() throws Exception {
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ true)).isTrue();
- mVerifierController.notifyVerificationTimeout(TEST_ID);
- verify(mMockService).onVerificationTimeout(eq(TEST_ID));
- }
-
- @Test
- public void testRequestTimeout() {
- // Let the mock handler set request to TIMEOUT, immediately after the request is sent.
- // We can't mock postDelayed because it's final, but we can mock the method it calls.
- when(mHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
- i -> {
- ((Message) i.getArguments()[0]).getCallback().run();
- return true;
- });
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
- verify(mSessionCallback, times(1)).onTimeout();
- verify(mInjector, times(2)).getCurrentTimeMillis();
- verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
- }
-
- @Test
- public void testRequestTimeoutWithRetryPass() throws Exception {
- // Only let the first request timeout and let the second one pass
- when(mHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
- i -> {
- ((Message) i.getArguments()[0]).getCallback().run();
- return true;
- })
- .thenAnswer(i -> true);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
- verify(mSessionCallback, times(1)).onTimeout();
- verify(mInjector, times(2)).getCurrentTimeMillis();
- verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
- // Then retry
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ true)).isTrue();
- verify(mMockService).onVerificationRetry(captor.capture());
- VerificationSession session = captor.getValue();
- VerificationStatus status = new VerificationStatus.Builder().setVerified(true).build();
- session.reportVerificationComplete(status);
- verify(mSessionCallback, times(1)).onVerificationCompleteReceived(
- eq(status), eq(null));
- verify(mInjector, times(2)).stopTimeoutCountdown(eq(mHandler), any());
- }
-
- @Test
- public void testRequestIncomplete() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- session.reportVerificationIncomplete(VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN);
- verify(mSessionCallback, times(1)).onVerificationIncompleteReceived(
- eq(VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN));
- verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
- }
-
- @Test
- public void testRequestCompleteWithSuccessWithExtensionResponse() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- VerificationStatus status = new VerificationStatus.Builder().setVerified(true).build();
- PersistableBundle bundle = new PersistableBundle();
- session.reportVerificationComplete(status, bundle);
- verify(mSessionCallback, times(1)).onVerificationCompleteReceived(
- eq(status), eq(bundle));
- verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
- }
-
- @Test
- public void testRequestCompleteWithFailure() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- VerificationStatus status = new VerificationStatus.Builder()
- .setVerified(false)
- .setFailureMessage(TEST_FAILURE_MESSAGE)
- .build();
- session.reportVerificationComplete(status);
- verify(mSessionCallback, times(1)).onVerificationCompleteReceived(
- eq(status), eq(null));
- verify(mInjector, times(1)).stopTimeoutCountdown(eq(mHandler), any());
- }
-
- @Test
- public void testRepeatedRequestCompleteShouldThrow() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- assertThat(mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false)).isTrue();
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- VerificationStatus status = new VerificationStatus.Builder().setVerified(true).build();
- session.reportVerificationComplete(status);
- // getters should throw after the report
- expectThrows(IllegalStateException.class, () -> session.getTimeoutTime());
- // Report again should fail with exception
- expectThrows(IllegalStateException.class, () -> session.reportVerificationComplete(status));
- }
-
- @Test
- public void testExtendTimeRemaining() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false);
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- final long initialTimeoutTime = TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS;
- assertThat(session.getTimeoutTime()).isEqualTo(initialTimeoutTime);
- final long extendTimeMillis = TEST_TIMEOUT_DURATION_MILLIS;
- assertThat(session.extendTimeRemaining(extendTimeMillis)).isEqualTo(extendTimeMillis);
- assertThat(session.getTimeoutTime()).isEqualTo(initialTimeoutTime + extendTimeMillis);
- }
-
- @Test
- public void testExtendTimeExceedsMax() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false);
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- final long initialTimeoutTime = TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS;
- final long maxTimeoutTime = TEST_REQUEST_START_TIME + TEST_MAX_TIMEOUT_DURATION_MILLIS;
- assertThat(session.getTimeoutTime()).isEqualTo(initialTimeoutTime);
- final long extendTimeMillis = TEST_MAX_TIMEOUT_DURATION_MILLIS;
- assertThat(session.extendTimeRemaining(extendTimeMillis)).isEqualTo(
- TEST_MAX_TIMEOUT_DURATION_MILLIS - TEST_TIMEOUT_DURATION_MILLIS);
- assertThat(session.getTimeoutTime()).isEqualTo(maxTimeoutTime);
- }
-
- @Test
- public void testTimeoutChecksMultipleTimes() {
- // Mock message handling
- when(mHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
- i -> {
- ((Message) i.getArguments()[0]).getCallback().run();
- return true;
- });
- // Mock time forward as the code continues to check for the current time
- when(mInjector.getCurrentTimeMillis())
- // First called when the tracker is created
- .thenReturn(TEST_REQUEST_START_TIME)
- // Then mock the first timeout check when the timeout time isn't reached yet
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 1000)
- // Then mock the same time used to check the remaining time
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 1000)
- // Then mock the second timeout check when the timeout time isn't reached yet
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 100)
- // Then mock the same time used to check the remaining time
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS - 100)
- // Then mock the third timeout check when the timeout time has been reached
- .thenReturn(TEST_REQUEST_START_TIME + TEST_TIMEOUT_DURATION_MILLIS + 1);
- mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false);
- verify(mHandler, times(3)).sendMessageAtTime(any(Message.class), anyLong());
- verify(mInjector, times(6)).getCurrentTimeMillis();
- verify(mSessionCallback, times(1)).onTimeout();
- }
-
- @Test
- public void testPolicyOverride() throws Exception {
- ArgumentCaptor<VerificationSession> captor =
- ArgumentCaptor.forClass(VerificationSession.class);
- mVerifierController.startVerificationSession(
- mSnapshotSupplier, 0, TEST_ID, TEST_PACKAGE_NAME, TEST_PACKAGE_URI,
- TEST_SIGNING_INFO, mTestDeclaredLibraries, TEST_POLICY, mTestExtensionParams,
- mSessionCallback, /* retry= */ false);
- verify(mMockService).onVerificationRequired(captor.capture());
- VerificationSession session = captor.getValue();
- final int policy = VERIFICATION_POLICY_BLOCK_FAIL_OPEN;
- when(mSessionCallback.setVerificationPolicy(eq(policy))).thenReturn(true);
- assertThat(session.setVerificationPolicy(policy)).isTrue();
- assertThat(session.getVerificationPolicy()).isEqualTo(policy);
- verify(mSessionCallback, times(1)).setVerificationPolicy(eq(policy));
- }
-}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 312df4391e2d..0e9dfedac0c9 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -1118,7 +1118,8 @@ public class AutomaticBrightnessControllerTest {
@Test
public void testAutoBrightnessInDoze_useNormalBrightnessForDozeFalse_scaleScreenOn()
throws Exception {
- when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+ true);
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
@@ -1154,7 +1155,8 @@ public class AutomaticBrightnessControllerTest {
@Test
public void testAutoBrightnessInDoze_useNormalBrightnessForDozeTrue_notScaleScreenOn()
throws Exception {
- when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+ true);
ArgumentCaptor<SensorEventListener> listenerCaptor =
ArgumentCaptor.forClass(SensorEventListener.class);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index c9963391470e..91f1aaf603e6 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -2119,7 +2119,8 @@ public final class DisplayPowerControllerTest {
@Test
public void testManualBrightness_stateOnPolicyDozeUseNormalBrightnessForDozeFalse_brightnessDoze() {
when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
- when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled(
+ mContext)).thenReturn(true);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -2154,7 +2155,8 @@ public final class DisplayPowerControllerTest {
@Test
public void testManualBrightness_stateOnPolicyDozeUseNormalBrightnessForDozeTrue_brightnessNormal() {
when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
- when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled(
+ mContext)).thenReturn(true);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
@@ -2188,7 +2190,8 @@ public final class DisplayPowerControllerTest {
@Test
public void testManualBrightness_stateDozePolicyOnUseNormalBrightnessForDozeTrue_brightnessDoze() {
when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
- when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isNormalBrightnessForDozeParameterEnabled(
+ mContext)).thenReturn(true);
mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
index a6476910a5de..2ebb6c2a3ce4 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
@@ -207,7 +207,8 @@ public final class DisplayBrightnessStrategySelectorTest {
@Test
public void selectStrategyWhenValid_useNormalBrightnessForDozeTrue_doNotSelectsDozeStrategy() {
- when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+ true);
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
displayPowerRequest.policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index 65f8ea7bfdfc..4be96c2a2eb3 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.Resources;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.DisplayManagerInternal;
import android.os.PowerManager;
@@ -76,6 +77,9 @@ public class AutomaticBrightnessStrategyTest {
@Mock
private DisplayManagerFlags mDisplayManagerFlags;
+ @Mock
+ private Resources mMockResources;
+
private BrightnessConfiguration mBrightnessConfiguration;
private float mDefaultScreenAutoBrightnessAdjustment;
private Context mContext;
@@ -378,7 +382,8 @@ public class AutomaticBrightnessStrategyTest {
reset(mAutomaticBrightnessController);
when(mAutomaticBrightnessController.isInIdleMode()).thenReturn(false);
- when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled()).thenReturn(true);
+ when(mDisplayManagerFlags.isNormalBrightnessForDozeParameterEnabled(mContext)).thenReturn(
+ true);
policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
// Validate interaction when automaticBrightnessController is in non-idle mode, display
diff --git a/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt
new file mode 100644
index 000000000000..01061f16c279
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginManagerTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import com.android.server.display.feature.DisplayManagerFlags
+import com.android.server.display.plugin.PluginManager.PluginChangeListener
+
+import org.junit.Test
+
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+private val TEST_PLUGIN_TYPE = PluginType(Int::class.java, "test_type")
+
+@SmallTest
+class PluginManagerTest {
+
+ private val mockContext = mock<Context>()
+ private val mockFlags = mock<DisplayManagerFlags>()
+ private val mockListener = mock<PluginChangeListener<Int>>()
+ private val testInjector = TestInjector()
+
+ @Test
+ fun testBootCompleted_enabledPluginManager() {
+ val pluginManager = createPluginManager()
+
+ pluginManager.onBootCompleted()
+
+ verify(testInjector.mockPlugin1).onBootCompleted()
+ verify(testInjector.mockPlugin2).onBootCompleted()
+ }
+
+ @Test
+ fun testBootCompleted_disabledPluginManager() {
+ val pluginManager = createPluginManager(false)
+
+ pluginManager.onBootCompleted()
+
+ verify(testInjector.mockPlugin1, never()).onBootCompleted()
+ verify(testInjector.mockPlugin2, never()).onBootCompleted()
+ }
+
+ @Test
+ fun testSubscribe() {
+ val pluginManager = createPluginManager()
+
+ pluginManager.subscribe(TEST_PLUGIN_TYPE, mockListener)
+
+ verify(testInjector.mockStorage).addListener(TEST_PLUGIN_TYPE, mockListener)
+ }
+
+ @Test
+ fun testUnsubscribe() {
+ val pluginManager = createPluginManager()
+
+ pluginManager.unsubscribe(TEST_PLUGIN_TYPE, mockListener)
+
+ verify(testInjector.mockStorage).removeListener(TEST_PLUGIN_TYPE, mockListener)
+ }
+
+ private fun createPluginManager(enabled: Boolean = true): PluginManager {
+ whenever(mockFlags.isPluginManagerEnabled).thenReturn(enabled)
+ return PluginManager(mockContext, mockFlags, testInjector)
+ }
+
+ private class TestInjector : PluginManager.Injector() {
+ val mockStorage = mock<PluginStorage>()
+ val mockPlugin1 = mock<Plugin>()
+ val mockPlugin2 = mock<Plugin>()
+
+ override fun getPluginStorage(): PluginStorage {
+ return mockStorage
+ }
+
+ override fun loadPlugins(context: Context?, storage: PluginStorage?): List<Plugin> {
+ return listOf(mockPlugin1, mockPlugin2)
+ }
+ }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt
new file mode 100644
index 000000000000..218e34134e93
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/plugin/PluginStorageTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.plugin
+
+import androidx.test.filters.SmallTest
+import com.android.server.display.plugin.PluginManager.PluginChangeListener
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+private val TEST_PLUGIN_TYPE1 = PluginType(String::class.java, "test_type1")
+private val TEST_PLUGIN_TYPE2 = PluginType(String::class.java, "test_type2")
+
+@SmallTest
+class PluginStorageTest {
+
+ val storage = PluginStorage()
+
+ @Test
+ fun testUpdateValue() {
+ val type1Value = "value1"
+ val testChangeListener = TestPluginChangeListener<String>()
+ storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+ storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+ assertThat(testChangeListener.receivedValue).isEqualTo(type1Value)
+ }
+
+ @Test
+ fun testAddListener() {
+ val type1Value = "value1"
+ val testChangeListener = TestPluginChangeListener<String>()
+ storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+ storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+ assertThat(testChangeListener.receivedValue).isEqualTo(type1Value)
+ }
+
+ @Test
+ fun testRemoveListener() {
+ val type1Value = "value1"
+ val testChangeListener = TestPluginChangeListener<String>()
+ storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+ storage.removeListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+ storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+ assertThat(testChangeListener.receivedValue).isNull()
+ }
+
+ @Test
+ fun testAddListener_multipleValues() {
+ val type1Value = "value1"
+ val type2Value = "value2"
+ val testChangeListener = TestPluginChangeListener<String>()
+ storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+ storage.updateValue(TEST_PLUGIN_TYPE2, type2Value)
+
+ storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener)
+
+ assertThat(testChangeListener.receivedValue).isEqualTo(type1Value)
+ }
+
+ @Test
+ fun testUpdateValue_multipleListeners() {
+ val type1Value = "value1"
+ val testChangeListener1 = TestPluginChangeListener<String>()
+ val testChangeListener2 = TestPluginChangeListener<String>()
+ storage.addListener(TEST_PLUGIN_TYPE1, testChangeListener1)
+ storage.addListener(TEST_PLUGIN_TYPE2, testChangeListener2)
+
+ storage.updateValue(TEST_PLUGIN_TYPE1, type1Value)
+
+ assertThat(testChangeListener1.receivedValue).isEqualTo(type1Value)
+ assertThat(testChangeListener2.receivedValue).isNull()
+ }
+
+ private class TestPluginChangeListener<T> : PluginChangeListener<T> {
+ var receivedValue: T? = null
+
+ override fun onChanged(value: T?) {
+ receivedValue = value
+ }
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 5a872ea04bcc..ace6aae1a8fc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -283,9 +283,9 @@ public class ActivityManagerServiceTest {
// Required for updating DeviceConfig.
InstrumentationRegistry.getInstrumentation()
.getUiAutomation()
- .adoptShellPermissionIdentity(
- Manifest.permission.READ_DEVICE_CONFIG,
- Manifest.permission.WRITE_DEVICE_CONFIG);
+ .adoptShellPermissionIdentity(Manifest.permission.READ_DEVICE_CONFIG,
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
sProcessListSettingsListener = mAms.mProcessList.getProcessListSettingsListener();
assertThat(sProcessListSettingsListener).isNotNull();
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
new file mode 100644
index 000000000000..19e43b6fa851
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAgentConnectionManagerTest.java
@@ -0,0 +1,381 @@
+/*
+ * 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.backup;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+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.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ApplicationThreadConstants;
+import android.app.IActivityManager;
+import android.app.IBackupAgent;
+import android.app.backup.BackupAnnotations.BackupDestination;
+import android.app.backup.BackupAnnotations.OperationType;
+import android.compat.testing.PlatformCompatChangeRule;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.LocalServices;
+import com.android.server.backup.internal.LifecycleOperationStorage;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.util.Set;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupAgentConnectionManagerTest {
+ private static final String TEST_PACKAGE = "com.test.package";
+
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ @Mock
+ IActivityManager mActivityManager;
+ @Mock
+ ActivityManagerInternal mActivityManagerInternal;
+ @Mock
+ LifecycleOperationStorage mOperationStorage;
+ @Mock
+ UserBackupManagerService mUserBackupManagerService;
+ @Mock
+ IBackupAgent.Stub mBackupAgentStub;
+ @Mock
+ PackageManager mPackageManager;
+
+ private BackupAgentConnectionManager mConnectionManager;
+ private MockitoSession mSession;
+ private ApplicationInfo mTestApplicationInfo;
+ private IBackupAgent mBackupAgentResult;
+ private Thread mTestThread;
+
+ @Before
+ public void setUp() throws Exception {
+ mSession = mockitoSession().initMocks(this).mockStatic(ActivityManager.class).mockStatic(
+ LocalServices.class).strictness(Strictness.LENIENT).startMocking();
+ MockitoAnnotations.initMocks(this);
+
+ doReturn(mActivityManager).when(ActivityManager::getService);
+ doReturn(mActivityManagerInternal).when(
+ () -> LocalServices.getService(ActivityManagerInternal.class));
+ // Real package manager throws if a property is not defined.
+ when(mPackageManager.getPropertyAsUser(any(), any(), any(), anyInt())).thenThrow(
+ new PackageManager.NameNotFoundException());
+
+ mConnectionManager = spy(
+ new BackupAgentConnectionManager(mOperationStorage, mPackageManager,
+ mUserBackupManagerService, UserHandle.USER_SYSTEM));
+
+ mTestApplicationInfo = new ApplicationInfo();
+ mTestApplicationInfo.packageName = TEST_PACKAGE;
+
+ mBackupAgentResult = null;
+ mTestThread = null;
+ }
+
+ @After
+ public void tearDown() {
+ if (mSession != null) {
+ mSession.finishMocking();
+ }
+ }
+
+ @Test
+ public void bindToAgentSynchronous_amReturnsFailure_returnsNullAndClearsPendingBackups()
+ throws Exception {
+ when(mActivityManager.bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(),
+ anyInt(), anyBoolean())).thenReturn(false);
+
+ IBackupAgent result = mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ assertThat(result).isNull();
+ verify(mActivityManagerInternal).clearPendingBackup(UserHandle.USER_SYSTEM);
+ }
+
+ @Test
+ public void bindToAgentSynchronous_agentDisconnectedCalled_returnsNullAndClearsPendingBackups()
+ throws Exception {
+ when(mActivityManager.bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(),
+ anyInt(), anyBoolean())).thenReturn(true);
+ // This is so that IBackupAgent.Stub.asInterface() works.
+ when(mBackupAgentStub.queryLocalInterface(any())).thenReturn(mBackupAgentStub);
+ when(mConnectionManager.getCallingUid()).thenReturn(Process.SYSTEM_UID);
+
+ // This is going to block until it receives the callback so we need to run it on a
+ // separate thread.
+ Thread testThread = new Thread(() -> setBackupAgentResult(
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD)),
+ "backup-agent-connection-manager-test");
+ testThread.start();
+ // Give the testThread a head start, otherwise agentConnected() might run before
+ // bindToAgentSynchronous() is called.
+ Thread.sleep(500);
+ mConnectionManager.agentDisconnected(TEST_PACKAGE);
+ testThread.join();
+
+ assertThat(mBackupAgentResult).isNull();
+ verify(mActivityManagerInternal).clearPendingBackup(UserHandle.USER_SYSTEM);
+ }
+
+ @Test
+ public void bindToAgentSynchronous_agentConnectedCalled_returnsBackupAgent() throws Exception {
+ when(mActivityManager.bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(),
+ anyInt(), anyBoolean())).thenReturn(true);
+ // This is so that IBackupAgent.Stub.asInterface() works.
+ when(mBackupAgentStub.queryLocalInterface(any())).thenReturn(mBackupAgentStub);
+ when(mConnectionManager.getCallingUid()).thenReturn(Process.SYSTEM_UID);
+
+ // This is going to block until it receives the callback so we need to run it on a
+ // separate thread.
+ Thread testThread = new Thread(() -> setBackupAgentResult(
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD)),
+ "backup-agent-connection-manager-test");
+ testThread.start();
+ // Give the testThread a head start, otherwise agentConnected() might run before
+ // bindToAgentSynchronous() is called.
+ Thread.sleep(500);
+ mConnectionManager.agentConnected(TEST_PACKAGE, mBackupAgentStub);
+ testThread.join();
+
+ assertThat(mBackupAgentResult).isEqualTo(mBackupAgentStub);
+ verify(mActivityManagerInternal, never()).clearPendingBackup(anyInt());
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ public void bindToAgentSynchronous_restrictedModeChangesFlagOff_shouldUseRestrictedMode()
+ throws Exception {
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(true));
+ // Make sure we never hit the code that checks the property.
+ verify(mPackageManager, never()).getPropertyAsUser(any(), any(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ public void bindToAgentSynchronous_keyValueBackup_shouldNotUseRestrictedMode()
+ throws Exception {
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(false));
+ // Make sure we never hit the code that checks the property.
+ verify(mPackageManager, never()).getPropertyAsUser(any(), any(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ public void bindToAgentSynchronous_keyValueRestore_shouldNotUseRestrictedMode()
+ throws Exception {
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_RESTORE, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(false));
+ // Make sure we never hit the code that checks the property.
+ verify(mPackageManager, never()).getPropertyAsUser(any(), any(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ public void bindToAgentSynchronous_packageOptedIn_shouldUseRestrictedMode() throws Exception {
+ reset(mPackageManager);
+ when(mPackageManager.getPropertyAsUser(
+ eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE), eq(TEST_PACKAGE), any(),
+ anyInt())).thenReturn(new PackageManager.Property(
+ PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE, /* value= */ true,
+ TEST_PACKAGE, /* className= */ null));
+
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(true));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ public void bindToAgentSynchronous_packageOptedOut_shouldNotUseRestrictedMode()
+ throws Exception {
+ reset(mPackageManager);
+ when(mPackageManager.getPropertyAsUser(
+ eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE), eq(TEST_PACKAGE), any(),
+ anyInt())).thenReturn(new PackageManager.Property(
+ PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE, /* value= */ false,
+ TEST_PACKAGE, /* className= */ null));
+
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(false));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ @DisableCompatChanges({BackupAgentConnectionManager.OS_DECIDES_BACKUP_RESTRICTED_MODE})
+ public void bindToAgentSynchronous_targetSdkBelowB_shouldUseRestrictedMode() throws Exception {
+ reset(mPackageManager);
+ // Mock that the app has not explicitly set the property.
+ when(mPackageManager.getPropertyAsUser(
+ eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE), eq(TEST_PACKAGE), any(),
+ anyInt())).thenThrow(new PackageManager.NameNotFoundException());
+
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(true));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ @EnableCompatChanges({BackupAgentConnectionManager.OS_DECIDES_BACKUP_RESTRICTED_MODE})
+ public void bindToAgentSynchronous_targetSdkB_notInList_shouldUseRestrictedMode()
+ throws Exception {
+ reset(mPackageManager);
+ // Mock that the app has not explicitly set the property.
+ when(mPackageManager.getPropertyAsUser(
+ eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE), eq(TEST_PACKAGE), any(),
+ anyInt())).thenThrow(new PackageManager.NameNotFoundException());
+ mConnectionManager.clearNoRestrictedModePackages();
+
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(true));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ @EnableCompatChanges({BackupAgentConnectionManager.OS_DECIDES_BACKUP_RESTRICTED_MODE})
+ public void bindToAgentSynchronous_forRestore_targetSdkB_inList_shouldNotUseRestrictedMode()
+ throws Exception {
+ reset(mPackageManager);
+ // Mock that the app has not explicitly set the property.
+ when(mPackageManager.getPropertyAsUser(
+ eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE), eq(TEST_PACKAGE), any(),
+ anyInt())).thenThrow(new PackageManager.NameNotFoundException());
+ mConnectionManager.setNoRestrictedModePackages(Set.of(TEST_PACKAGE), OperationType.RESTORE);
+
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(false));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
+ @EnableCompatChanges({BackupAgentConnectionManager.OS_DECIDES_BACKUP_RESTRICTED_MODE})
+ public void bindToAgentSynchronous_forBackup_targetSdkB_inList_shouldNotUseRestrictedMode()
+ throws Exception {
+ reset(mPackageManager);
+ // Mock that the app has not explicitly set the property.
+ when(mPackageManager.getPropertyAsUser(
+ eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE), eq(TEST_PACKAGE), any(),
+ anyInt())).thenThrow(new PackageManager.NameNotFoundException());
+ mConnectionManager.setNoRestrictedModePackages(Set.of(TEST_PACKAGE), OperationType.BACKUP);
+
+ mConnectionManager.bindToAgentSynchronous(mTestApplicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
+
+ verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
+ /* useRestrictedMode= */ eq(false));
+ }
+
+ @Test
+ public void agentDisconnected_cancelsCurrentOperations() throws Exception {
+ when(mOperationStorage.operationTokensForPackage(eq(TEST_PACKAGE))).thenReturn(
+ ImmutableSet.of(123, 456, 789));
+ when(mConnectionManager.getThreadForCancellation(any())).thenAnswer(invocation -> {
+ Thread testThread = new Thread((Runnable) invocation.getArgument(0),
+ "agent-disconnected-test");
+ setTestThread(testThread);
+ return testThread;
+ });
+
+ mConnectionManager.agentDisconnected(TEST_PACKAGE);
+
+ mTestThread.join();
+ verify(mUserBackupManagerService).handleCancel(eq(123), eq(true));
+ verify(mUserBackupManagerService).handleCancel(eq(456), eq(true));
+ verify(mUserBackupManagerService).handleCancel(eq(789), eq(true));
+ }
+
+ @Test
+ public void unbindAgent_callsAmUnbindBackupAgent() throws Exception {
+ mConnectionManager.unbindAgent(mTestApplicationInfo);
+
+ verify(mActivityManager).unbindBackupAgent(eq(mTestApplicationInfo));
+ }
+
+ // Needed because variables can't be assigned directly inside lambdas in Java.
+ private void setBackupAgentResult(IBackupAgent result) {
+ mBackupAgentResult = result;
+ }
+
+ // Needed because variables can't be assigned directly inside lambdas in Java.
+ private void setTestThread(Thread thread) {
+ mTestThread = thread;
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 07f2188d30eb..7a9e96f1bc4c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -18,20 +18,18 @@ package com.android.server.backup;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
+
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.when;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
-import android.app.ApplicationThreadConstants;
import android.app.IActivityManager;
import android.app.backup.BackupAgent;
import android.app.backup.BackupAnnotations.BackupDestination;
@@ -47,8 +45,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
@@ -57,7 +53,6 @@ import android.util.FeatureFlagUtils;
import android.util.KeyValueListParser;
import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.FlakyTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.backup.internal.BackupHandler;
@@ -69,8 +64,6 @@ import com.android.server.backup.transport.TransportConnection;
import com.android.server.backup.utils.BackupEligibilityRules;
import com.android.server.backup.utils.BackupManagerMonitorEventSender;
-import com.google.common.collect.ImmutableSet;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -84,11 +77,6 @@ import org.mockito.quality.Strictness;
import java.util.Arrays;
import java.util.List;
-import java.util.Set;
-import java.util.function.IntConsumer;
-
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@Presubmit
@RunWith(AndroidJUnit4.class)
@@ -96,7 +84,6 @@ public class UserBackupManagerServiceTest {
private static final String TEST_PACKAGE = "package1";
private static final String[] TEST_PACKAGES = new String[] { TEST_PACKAGE };
private static final String TEST_TRANSPORT = "transport";
- private static final int WORKER_THREAD_TIMEOUT_MILLISECONDS = 100;
@UserIdInt private static final int USER_ID = 0;
@Rule
@@ -278,33 +265,6 @@ public class UserBackupManagerServiceTest {
}
@Test
- @FlakyTest
- public void testAgentDisconnected_cancelsCurrentOperations() throws Exception {
- when(mOperationStorage.operationTokensForPackage(eq("com.android.foo"))).thenReturn(
- ImmutableSet.of(123, 456, 789)
- );
-
- mService.agentDisconnected("com.android.foo");
-
- mService.waitForAsyncOperation();
- verify(mOperationStorage).cancelOperation(eq(123), eq(true), any(IntConsumer.class));
- verify(mOperationStorage).cancelOperation(eq(456), eq(true), any());
- verify(mOperationStorage).cancelOperation(eq(789), eq(true), any());
- }
-
- @Test
- public void testAgentDisconnected_unknownPackageName_cancelsNothing() throws Exception {
- when(mOperationStorage.operationTokensForPackage(eq("com.android.foo"))).thenReturn(
- ImmutableSet.of()
- );
-
- mService.agentDisconnected("com.android.foo");
-
- verify(mOperationStorage, never())
- .cancelOperation(anyInt(), anyBoolean(), any(IntConsumer.class));
- }
-
- @Test
public void testReportDelayedRestoreResult_sendsLogsToMonitor() throws Exception {
PackageInfo packageInfo = getPackageInfo(TEST_PACKAGE);
when(mPackageManager.getPackageInfoAsUser(anyString(),
@@ -324,158 +284,6 @@ public class UserBackupManagerServiceTest {
eq(packageInfo), eq(results), eq(OperationType.RESTORE));
}
- @Test
- @DisableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- public void bindToAgentSynchronous_restrictedModeChangesFlagOff_shouldUseRestrictedMode()
- throws Exception {
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(true));
- // Make sure we never hit the code that checks the property.
- verify(mPackageManager, never()).getPropertyAsUser(any(), any(), any(), anyInt());
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- public void bindToAgentSynchronous_keyValueBackup_shouldNotUseRestrictedMode()
- throws Exception {
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(false));
- // Make sure we never hit the code that checks the property.
- verify(mPackageManager, never()).getPropertyAsUser(any(), any(), any(), anyInt());
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- public void bindToAgentSynchronous_keyValueRestore_shouldNotUseRestrictedMode()
- throws Exception {
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_RESTORE, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(false));
- // Make sure we never hit the code that checks the property.
- verify(mPackageManager, never()).getPropertyAsUser(any(), any(), any(), anyInt());
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- public void bindToAgentSynchronous_packageOptedIn_shouldUseRestrictedMode()
- throws Exception {
- when(mPackageManager.getPropertyAsUser(
- eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE),
- eq(TEST_PACKAGE), any(), anyInt())).thenReturn(new PackageManager.Property(
- PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE, /* value= */ true,
- TEST_PACKAGE, /* className= */ null));
-
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(true));
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- public void bindToAgentSynchronous_packageOptedOut_shouldNotUseRestrictedMode()
- throws Exception {
- when(mPackageManager.getPropertyAsUser(
- eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE),
- eq(TEST_PACKAGE), any(), anyInt())).thenReturn(new PackageManager.Property(
- PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE, /* value= */ false,
- TEST_PACKAGE, /* className= */ null));
-
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(false));
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- @DisableCompatChanges({UserBackupManagerService.OS_DECIDES_BACKUP_RESTRICTED_MODE})
- public void bindToAgentSynchronous_targetSdkBelowB_shouldUseRestrictedMode()
- throws Exception {
- // Mock that the app has not explicitly set the property.
- when(mPackageManager.getPropertyAsUser(
- eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE),
- eq(TEST_PACKAGE), any(), anyInt())).thenThrow(
- new PackageManager.NameNotFoundException()
- );
-
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(true));
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- @EnableCompatChanges({UserBackupManagerService.OS_DECIDES_BACKUP_RESTRICTED_MODE})
- public void bindToAgentSynchronous_targetSdkB_notInList_shouldUseRestrictedMode()
- throws Exception {
- // Mock that the app has not explicitly set the property.
- when(mPackageManager.getPropertyAsUser(
- eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE),
- eq(TEST_PACKAGE), any(), anyInt())).thenThrow(
- new PackageManager.NameNotFoundException()
- );
- mService.clearNoRestrictedModePackages();
-
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(true));
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- @EnableCompatChanges({UserBackupManagerService.OS_DECIDES_BACKUP_RESTRICTED_MODE})
- public void bindToAgentSynchronous_forRestore_targetSdkB_inList_shouldNotUseRestrictedMode()
- throws Exception {
- // Mock that the app has not explicitly set the property.
- when(mPackageManager.getPropertyAsUser(
- eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE),
- eq(TEST_PACKAGE), any(), anyInt())).thenThrow(
- new PackageManager.NameNotFoundException()
- );
- mService.setNoRestrictedModePackages(Set.of(TEST_PACKAGE), OperationType.RESTORE);
-
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(false));
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_RESTRICTED_MODE_CHANGES)
- @EnableCompatChanges({UserBackupManagerService.OS_DECIDES_BACKUP_RESTRICTED_MODE})
- public void bindToAgentSynchronous_forBackup_targetSdkB_inList_shouldNotUseRestrictedMode()
- throws Exception {
- // Mock that the app has not explicitly set the property.
- when(mPackageManager.getPropertyAsUser(
- eq(PackageManager.PROPERTY_USE_RESTRICTED_BACKUP_MODE),
- eq(TEST_PACKAGE), any(), anyInt())).thenThrow(
- new PackageManager.NameNotFoundException()
- );
- mService.setNoRestrictedModePackages(Set.of(TEST_PACKAGE), OperationType.BACKUP);
-
- mService.bindToAgentSynchronous(mTestPackageApplicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_FULL, BackupDestination.CLOUD);
-
- verify(mActivityManager).bindBackupAgent(eq(TEST_PACKAGE), anyInt(), anyInt(), anyInt(),
- /* useRestrictedMode= */ eq(false));
- }
-
private static PackageInfo getPackageInfo(String packageName) {
PackageInfo packageInfo = new PackageInfo();
packageInfo.applicationInfo = new ApplicationInfo();
@@ -487,8 +295,6 @@ public class UserBackupManagerServiceTest {
boolean isEnabledStatePersisted = false;
boolean shouldUseNewBackupEligibilityRules = false;
- private volatile Thread mWorkerThread = null;
-
TestBackupService() {
super(mContext, mPackageManager, mOperationStorage, mTransportManager, mBackupHandler,
createConstants(mContext), mActivityManager, mActivityManagerInternal);
@@ -523,26 +329,8 @@ public class UserBackupManagerServiceTest {
}
@Override
- Thread getThreadForAsyncOperation(String operationName, Runnable operation) {
- mWorkerThread = super.getThreadForAsyncOperation(operationName, operation);
- return mWorkerThread;
- }
-
- @Override
BackupManagerMonitorEventSender getBMMEventSender(IBackupManagerMonitor monitor) {
return mBackupManagerMonitorEventSender;
}
-
- private void waitForAsyncOperation() {
- if (mWorkerThread == null) {
- return;
- }
-
- try {
- mWorkerThread.join(/* millis */ WORKER_THREAD_TIMEOUT_MILLISECONDS);
- } catch (InterruptedException e) {
- fail("Failed waiting for worker thread to complete: " + e.getMessage());
- }
- }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/fullbackup/PerformFullTransportBackupTaskTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/fullbackup/PerformFullTransportBackupTaskTest.java
index 331057398949..e618433862f2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/fullbackup/PerformFullTransportBackupTaskTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/fullbackup/PerformFullTransportBackupTaskTest.java
@@ -33,6 +33,7 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.backup.BackupAgentConnectionManager;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.OperationStorage;
import com.android.server.backup.TransportManager;
@@ -66,6 +67,8 @@ public class PerformFullTransportBackupTaskTest {
@Mock
UserBackupManagerService mBackupManagerService;
@Mock
+ BackupAgentConnectionManager mBackupAgentConnectionManager;
+ @Mock
BackupTransportClient mBackupTransportClient;
@Mock
CountDownLatch mLatch;
@@ -95,6 +98,8 @@ public class PerformFullTransportBackupTaskTest {
when(mBackupManagerService.isSetupComplete()).thenReturn(true);
when(mBackupManagerService.getAgentTimeoutParameters()).thenReturn(
mBackupAgentTimeoutParameters);
+ when(mBackupManagerService.getBackupAgentConnectionManager()).thenReturn(
+ mBackupAgentConnectionManager);
when(mBackupManagerService.getTransportManager()).thenReturn(mTransportManager);
when(mTransportManager.getCurrentTransportClient(any())).thenReturn(mTransportConnection);
when(mTransportConnection.connectOrThrow(any())).thenReturn(mBackupTransportClient);
@@ -142,11 +147,11 @@ public class PerformFullTransportBackupTaskTest {
mTask.run();
- InOrder inOrder = inOrder(mBackupManagerService);
- inOrder.verify(mBackupManagerService).setNoRestrictedModePackages(
+ InOrder inOrder = inOrder(mBackupAgentConnectionManager);
+ inOrder.verify(mBackupAgentConnectionManager).setNoRestrictedModePackages(
eq(Set.of("package1")),
eq(BackupAnnotations.OperationType.BACKUP));
- inOrder.verify(mBackupManagerService).clearNoRestrictedModePackages();
+ inOrder.verify(mBackupAgentConnectionManager).clearNoRestrictedModePackages();
}
private void createTask(String[] packageNames) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
index 055adf68ee0f..351aac357c44 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
@@ -44,6 +44,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.testing.TestableDeviceConfig;
+import com.android.server.backup.BackupAgentConnectionManager;
import com.android.server.backup.Flags;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.internal.BackupHandler;
@@ -95,6 +96,8 @@ public class PerformUnifiedRestoreTaskTest {
private TransportConnection mTransportConnection;
@Mock
private BackupTransportClient mBackupTransportClient;
+ @Mock
+ private BackupAgentConnectionManager mBackupAgentConnectionManager;
private Set<String> mExcludedkeys = new HashSet<>();
private Map<String, String> mBackupData = new HashMap<>();
@@ -122,6 +125,9 @@ public class PerformUnifiedRestoreTaskTest {
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ when(mBackupManagerService.getBackupAgentConnectionManager()).thenReturn(
+ mBackupAgentConnectionManager);
+
mBackupDataSource = new ArrayDeque<>(mBackupData.keySet());
when(mBackupDataInput.readNextHeader())
.then((Answer<Boolean>) invocation -> !mBackupDataSource.isEmpty());
@@ -166,7 +172,7 @@ public class PerformUnifiedRestoreTaskTest {
mRestoreTask.setNoRestrictedModePackages(mBackupTransportClient,
new PackageInfo[]{packageInfo1, packageInfo2});
- verify(mBackupManagerService).setNoRestrictedModePackages(
+ verify(mBackupAgentConnectionManager).setNoRestrictedModePackages(
eq(Set.of("package1")),
eq(BackupAnnotations.OperationType.RESTORE));
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index d66bb00ae879..c6870adb8464 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -65,6 +65,7 @@ import android.app.job.JobInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
+import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -103,10 +104,13 @@ import com.android.server.job.controllers.QuotaController.TimedEvent;
import com.android.server.job.controllers.QuotaController.TimingSession;
import com.android.server.usage.AppStandbyInternal;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
@@ -135,6 +139,9 @@ public class QuotaControllerTest {
private static final int SOURCE_USER_ID = 0;
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
private QuotaController mQuotaController;
private QuotaController.QcConstants mQcConstants;
private JobSchedulerService.Constants mConstants = new JobSchedulerService.Constants();
@@ -303,7 +310,7 @@ public class QuotaControllerTest {
private int getProcessStateQuotaFreeThreshold() {
synchronized (mQuotaController.mLock) {
- return mQuotaController.getProcessStateQuotaFreeThreshold();
+ return mQuotaController.getProcessStateQuotaFreeThreshold(mSourceUid);
}
}
@@ -5197,6 +5204,101 @@ public class QuotaControllerTest {
assertFalse(jobBg2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
}
+ @Test
+ @EnableCompatChanges({QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
+ QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS})
+ @RequiresFlagsEnabled({Flags.FLAG_ENFORCE_QUOTA_POLICY_TO_TOP_STARTED_JOBS,
+ Flags.FLAG_ENFORCE_QUOTA_POLICY_TO_FGS_JOBS})
+ public void testTracking_OutOfQuota_ForegroundAndBackground_CompactChangeOverrides() {
+ setDischarging();
+
+ JobStatus jobBg = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 1);
+ JobStatus jobTop = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 2);
+ trackJobs(jobBg, jobTop);
+ setStandbyBucket(WORKING_INDEX, jobTop, jobBg); // 2 hour window
+ // Now the package only has 20 seconds to run.
+ final long remainingTimeMs = 20 * SECOND_IN_MILLIS;
+ mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+ createTimingSession(
+ JobSchedulerService.sElapsedRealtimeClock.millis() - HOUR_IN_MILLIS,
+ 10 * MINUTE_IN_MILLIS - remainingTimeMs, 1), false);
+
+ InOrder inOrder = inOrder(mJobSchedulerService);
+
+ // UID starts out inactive.
+ setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
+ // Start the job.
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.prepareForExecutionLocked(jobBg);
+ }
+ advanceElapsedClock(remainingTimeMs / 2);
+ // New job starts after UID is in the foreground. Since the app is now in the foreground, it
+ // should continue to have remainingTimeMs / 2 time remaining.
+ setProcessState(ActivityManager.PROCESS_STATE_TOP);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.prepareForExecutionLocked(jobTop);
+ }
+ advanceElapsedClock(remainingTimeMs);
+
+ // Wait for some extra time to allow for job processing.
+ inOrder.verify(mJobSchedulerService,
+ timeout(remainingTimeMs + 2 * SECOND_IN_MILLIS).times(0))
+ .onControllerStateChanged(argThat(jobs -> jobs.size() > 0));
+ synchronized (mQuotaController.mLock) {
+ assertEquals(remainingTimeMs / 2,
+ mQuotaController.getRemainingExecutionTimeLocked(jobBg));
+ assertEquals(remainingTimeMs / 2,
+ mQuotaController.getRemainingExecutionTimeLocked(jobTop));
+ }
+ // Go to a background state.
+ setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+ advanceElapsedClock(remainingTimeMs / 2 + 1);
+ // Only Bg job will be changed from in-quota to out-of-quota.
+ inOrder.verify(mJobSchedulerService,
+ timeout(remainingTimeMs / 2 + 2 * SECOND_IN_MILLIS).times(1))
+ .onControllerStateChanged(argThat(jobs -> jobs.size() == 1));
+ // Top job should still be allowed to run.
+ assertFalse(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+
+ // New jobs to run.
+ JobStatus jobBg2 = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 3);
+ JobStatus jobTop2 = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 4);
+ JobStatus jobFg = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 5);
+ setStandbyBucket(WORKING_INDEX, jobBg2, jobTop2, jobFg);
+
+ advanceElapsedClock(20 * SECOND_IN_MILLIS);
+ setProcessState(ActivityManager.PROCESS_STATE_TOP);
+ inOrder.verify(mJobSchedulerService, timeout(SECOND_IN_MILLIS).times(1))
+ .onControllerStateChanged(argThat(jobs -> jobs.size() == 1));
+ trackJobs(jobFg, jobTop);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.prepareForExecutionLocked(jobTop);
+ }
+ assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertTrue(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+
+ // App still in foreground so everything should be in quota.
+ advanceElapsedClock(20 * SECOND_IN_MILLIS);
+ setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertTrue(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+
+ advanceElapsedClock(20 * SECOND_IN_MILLIS);
+ setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
+ inOrder.verify(mJobSchedulerService, timeout(SECOND_IN_MILLIS).times(1))
+ .onControllerStateChanged(argThat(jobs -> jobs.size() == 2));
+ // App is now in background and out of quota. Fg should now change to out of quota since it
+ // wasn't started. Top should remain in quota since it started when the app was in TOP.
+ assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertFalse(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ assertFalse(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ trackJobs(jobBg2);
+ assertFalse(jobBg2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+ }
+
/**
* Tests that TOP jobs are stopped when an app runs out of quota.
*/
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
index 71c60ad02794..6f5e2b713260 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
@@ -741,11 +741,6 @@ public class StagingManagerTest {
/* stagedSessionErrorCode */ PackageManager.INSTALL_UNKNOWN,
/* stagedSessionErrorMessage */ "no error",
/* preVerifiedDomains */ null,
- /* verifierController */ null,
- /* initialVerificationPolicy */
- PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
- /* currentVerificationPolicy */
- PackageInstaller.VERIFICATION_POLICY_BLOCK_FAIL_CLOSED,
/* installDependencyHelper */ null);
StagingManager.StagedSession stagedSession = spy(session.mStagedSession);
diff --git a/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java b/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
index d3943e32ef07..d12579cd6b11 100644
--- a/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
+++ b/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
@@ -18,10 +18,10 @@ package com.android.server.ondeviceintelligence;
import static com.google.common.truth.Truth.assertThat;
+import android.app.ondeviceintelligence.InferenceInfo;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
-import android.app.ondeviceintelligence.InferenceInfo;
import android.util.Base64;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -32,7 +32,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
import java.util.List;
@RunWith(AndroidJUnit4.class)
@@ -53,8 +52,8 @@ public class InferenceInfoStoreTest {
List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
assertThat(inferenceInfos).hasSize(1);
assertThat(inferenceInfos.get(0).getUid()).isEqualTo(1);
- assertThat(inferenceInfos.get(0).getStartTimeMs()).isEqualTo(1);
- assertThat(inferenceInfos.get(0).getEndTimeMs()).isEqualTo(100);
+ assertThat(inferenceInfos.get(0).getStartTimeMillis()).isEqualTo(1);
+ assertThat(inferenceInfos.get(0).getEndTimeMillis()).isEqualTo(100);
}
@Test
@@ -66,8 +65,8 @@ public class InferenceInfoStoreTest {
List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
assertThat(inferenceInfos).hasSize(1);
assertThat(inferenceInfos.get(0).getUid()).isEqualTo(1);
- assertThat(inferenceInfos.get(0).getStartTimeMs()).isEqualTo(1);
- assertThat(inferenceInfos.get(0).getEndTimeMs()).isEqualTo(100);
+ assertThat(inferenceInfos.get(0).getStartTimeMillis()).isEqualTo(1);
+ assertThat(inferenceInfos.get(0).getEndTimeMillis()).isEqualTo(100);
}
@@ -87,8 +86,8 @@ public class InferenceInfoStoreTest {
List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
assertThat(inferenceInfos).hasSize(2);
assertThat(inferenceInfos.get(0).getUid()).isEqualTo(1);
- assertThat(inferenceInfos.get(0).getStartTimeMs()).isEqualTo(testStartTime - 10);
- assertThat(inferenceInfos.get(0).getEndTimeMs()).isEqualTo(testStartTime + 100);
+ assertThat(inferenceInfos.get(0).getStartTimeMillis()).isEqualTo(testStartTime - 10);
+ assertThat(inferenceInfos.get(0).getEndTimeMillis()).isEqualTo(testStartTime + 100);
inferenceInfoStore.addInferenceInfoFromBundle(bundle);
List<InferenceInfo> inferenceInfos2 = inferenceInfoStore.getLatestInferenceInfo(0);
assertThat(inferenceInfos2).hasSize(1); //previous entries should have been evicted
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 0881b4cf9bcf..e631cb66eaf7 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -66,6 +66,7 @@ import android.os.IHintSession;
import android.os.PerformanceHintManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.SessionCreationConfig;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -200,7 +201,7 @@ public class HintManagerServiceTest {
when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID),
eq(SESSION_TIDS_C), eq(0L), anyInt(),
any(SessionConfig.class))).thenAnswer(fakeCreateWithConfig(SESSION_PTRS[2],
- SESSION_IDS[2]));
+ SESSION_IDS[2]));
when(mIPowerMock.getInterfaceVersion()).thenReturn(6);
when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig);
@@ -305,6 +306,14 @@ public class HintManagerServiceTest {
return mService;
}
+ private SessionCreationConfig makeSessionCreationConfig(int[] tids,
+ long targetWorkDurationNanos) {
+ SessionCreationConfig config = new SessionCreationConfig();
+ config.tids = tids;
+ config.targetWorkDurationNanos = targetWorkDurationNanos;
+ return config;
+ }
+
@Test
public void testInitializeService() {
HintManagerService service = createService();
@@ -316,12 +325,14 @@ public class HintManagerServiceTest {
public void testCreateHintSessionInvalidPid() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(new int[]{TID, 1}, DEFAULT_TARGET_DURATION);
// Make sure we throw exception when adding a TID doesn't belong to the processes
// In this case, we add `init` PID into the list.
SessionConfig config = new SessionConfig();
assertThrows(SecurityException.class,
() -> service.getBinderServiceInstance().createHintSessionWithConfig(token,
- new int[]{TID, 1}, DEFAULT_TARGET_DURATION, SessionTag.OTHER, config));
+ SessionTag.OTHER, creationConfig, config));
}
@Test
@@ -329,17 +340,23 @@ public class HintManagerServiceTest {
HintManagerService service = createService();
IBinder token = new Binder();
makeConfigCreationUnsupported();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig());
assertNotNull(a);
+ creationConfig.tids = SESSION_TIDS_B;
+ creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_B, DOUBLED_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig());
assertNotEquals(a, b);
+ creationConfig.tids = SESSION_TIDS_C;
+ creationConfig.targetWorkDurationNanos = 0L;
IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_C, 0L, SessionTag.OTHER, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig());
assertNotNull(c);
verify(mNativeWrapperMock, times(3)).halCreateHintSession(anyInt(), anyInt(),
any(int[].class), anyLong());
@@ -349,22 +366,28 @@ public class HintManagerServiceTest {
public void testCreateHintSessionWithConfig() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
SessionConfig config = new SessionConfig();
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, config);
+ SessionTag.OTHER, creationConfig, config);
assertNotNull(a);
assertEquals(SESSION_IDS[0], config.id);
SessionConfig config2 = new SessionConfig();
+ creationConfig.tids = SESSION_TIDS_B;
+ creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_B, DOUBLED_TARGET_DURATION, SessionTag.APP, config2);
+ SessionTag.APP, creationConfig, config2);
assertNotEquals(a, b);
assertEquals(SESSION_IDS[1], config2.id);
SessionConfig config3 = new SessionConfig();
+ creationConfig.tids = SESSION_TIDS_C;
+ creationConfig.targetWorkDurationNanos = 0L;
IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_C, 0L, SessionTag.GAME, config3);
+ SessionTag.GAME, creationConfig, config3);
assertNotNull(c);
assertEquals(SESSION_IDS[2], config3.id);
verify(mNativeWrapperMock, times(3)).halCreateHintSessionWithConfig(anyInt(), anyInt(),
@@ -372,13 +395,48 @@ public class HintManagerServiceTest {
}
@Test
+ public void testCreateGraphicsPipelineSessions() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+
+ final int threadCount =
+ service.getBinderServiceInstance().getMaxGraphicsPipelineThreadsCount();
+ long sessionPtr1 = 1111L;
+ long sessionId1 = 11111L;
+ CountDownLatch stopLatch1 = new CountDownLatch(1);
+ int[] tids1 = createThreads(threadCount, stopLatch1);
+ when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(tids1),
+ eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class)))
+ .thenAnswer(fakeCreateWithConfig(sessionPtr1, sessionId1));
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
+
+ creationConfig.modesToEnable = new int[] {1}; // GRAPHICS_PIPELINE
+
+ SessionConfig config = new SessionConfig();
+ IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
+ SessionTag.OTHER, creationConfig, config);
+ assertNotNull(a);
+ assertEquals(sessionId1, config.id);
+
+ creationConfig.tids = createThreads(1, stopLatch1);
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ service.getBinderServiceInstance().createHintSessionWithConfig(token,
+ SessionTag.OTHER, creationConfig, config);
+ });
+ }
+
+ @Test
public void testPauseResumeHintSession() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
// Set session to background and calling updateHintAllowedByProcState() would invoke
// pause();
@@ -414,9 +472,11 @@ public class HintManagerServiceTest {
public void testCloseHintSession() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig());
a.close();
verify(mNativeWrapperMock, times(1)).halCloseHintSession(anyLong());
@@ -426,9 +486,11 @@ public class HintManagerServiceTest {
public void testUpdateTargetWorkDuration() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SESSION_TIDS_A, DEFAULT_TARGET_DURATION, SessionTag.OTHER, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig());
assertThrows(IllegalArgumentException.class, () -> {
a.updateTargetWorkDuration(-1L);
@@ -446,10 +508,12 @@ public class HintManagerServiceTest {
public void testReportActualWorkDuration() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
a.updateTargetWorkDuration(100L);
a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_THREE);
@@ -489,10 +553,12 @@ public class HintManagerServiceTest {
public void testSendHint() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET);
verify(mNativeWrapperMock, times(1)).halSendHint(anyLong(),
@@ -516,10 +582,12 @@ public class HintManagerServiceTest {
public void testDoHintInBackground() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
service.mUidObserver.onUidStateChanged(
a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
@@ -538,10 +606,12 @@ public class HintManagerServiceTest {
public void testDoHintInForeground() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
service.mUidObserver.onUidStateChanged(
a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
@@ -552,10 +622,12 @@ public class HintManagerServiceTest {
public void testSetThreads() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
a.updateTargetWorkDuration(100L);
@@ -591,9 +663,11 @@ public class HintManagerServiceTest {
when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(tids1),
eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class)))
.thenReturn(sessionPtr1);
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, tids1, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
assertNotNull(session1);
// trigger UID state change by making the process foreground->background, but because the
@@ -626,9 +700,11 @@ public class HintManagerServiceTest {
when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(tids1),
eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class)))
.thenReturn(sessionPtr1);
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, tids1, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
assertNotNull(session1);
// let all session 1 threads to exit and the cleanup should force pause the session 1
@@ -734,10 +810,12 @@ public class HintManagerServiceTest {
public void testSetMode() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
a.setMode(0, true);
verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
@@ -746,12 +824,19 @@ public class HintManagerServiceTest {
a.setMode(0, false);
verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
eq(0), eq(false));
+ }
- assertThrows(IllegalArgumentException.class, () -> {
- a.setMode(-1, true);
- });
+ @Test
+ public void testSetModeSessionInBackGround() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
- reset(mNativeWrapperMock);
// Set session to background, then the duration would not be updated.
service.mUidObserver.onUidStateChanged(
a.mUid, ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0, 0);
@@ -763,6 +848,40 @@ public class HintManagerServiceTest {
}
@Test
+ public void testSetModeInvalid() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ a.setMode(-1, true);
+ });
+ }
+
+ @Test
+ public void testSetModeUponSessionCreation() throws Exception {
+ HintManagerService service = createService();
+ IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+ creationConfig.modesToEnable = new int[] {0, 1};
+
+ AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
+ assertNotNull(a);
+ verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
+ eq(0), eq(true));
+ verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
+ eq(1), eq(true));
+ }
+
+ @Test
public void testGetChannel() throws Exception {
HintManagerService service = createService();
Binder token = new Binder();
@@ -950,9 +1069,12 @@ public class HintManagerServiceTest {
private void runAppHintSession(HintManagerService service, int logId,
AtomicReference<Boolean> shouldRun) throws Exception {
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
+
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
// we will start some threads and get their valid TIDs to update
int threadCount = 3;
// the list of TIDs
@@ -1017,10 +1139,12 @@ public class HintManagerServiceTest {
public void testReportActualWorkDuration2() throws Exception {
HintManagerService service = createService();
IBinder token = new Binder();
+ SessionCreationConfig creationConfig =
+ makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
- .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION,
- SessionTag.OTHER, new SessionConfig());
+ .createHintSessionWithConfig(token, SessionTag.OTHER,
+ creationConfig, new SessionConfig());
a.updateTargetWorkDuration(100L);
a.reportActualWorkDuration2(WORK_DURATIONS_FIVE);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java
index 0d5d277b00ef..ed927c6ab699 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java
@@ -26,8 +26,7 @@ import android.content.Context;
import android.os.Process;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
+import android.platform.test.ravenwood.RavenwoodRule;
import com.android.internal.os.PowerStats;
import com.android.server.power.feature.flags.Flags;
@@ -39,10 +38,9 @@ import org.junit.Test;
public class WakelockPowerStatsCollectorTest {
- @Config
- public static final RavenwoodConfig sConfig =
- new RavenwoodConfig.Builder()
- .setProvideMainThread(true)
+ @Rule
+ public final RavenwoodRule mRule =
+ new RavenwoodRule.Builder()
.setSystemPropertyImmutable(
"persist.sys.com.android.server.power.feature.flags."
+ "framework_wakelock_info-override",
diff --git a/services/tests/security/forensic/OWNERS b/services/tests/security/forensic/OWNERS
deleted file mode 100644
index 80c9afb96033..000000000000
--- a/services/tests/security/forensic/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 36824
-
-file:platform/frameworks/base:main:/core/java/android/security/forensic/OWNERS
diff --git a/services/tests/security/forensic/TEST_MAPPING b/services/tests/security/forensic/TEST_MAPPING
deleted file mode 100644
index bd8b2ab7c41f..000000000000
--- a/services/tests/security/forensic/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "postsubmit": [
- {
- "name": "ForensicServiceTests"
- }
- ]
-}
diff --git a/services/tests/security/forensic/Android.bp b/services/tests/security/intrusiondetection/Android.bp
index 77a87afba6a7..00ac90807dff 100644
--- a/services/tests/security/forensic/Android.bp
+++ b/services/tests/security/intrusiondetection/Android.bp
@@ -9,7 +9,7 @@ package {
}
android_test {
- name: "ForensicServiceTests",
+ name: "IntrusionDetectionServiceTests",
srcs: [
"src/**/*.java",
],
diff --git a/services/tests/security/forensic/AndroidManifest.xml b/services/tests/security/intrusiondetection/AndroidManifest.xml
index c5b3d40ce254..f388e7ea8590 100644
--- a/services/tests/security/forensic/AndroidManifest.xml
+++ b/services/tests/security/intrusiondetection/AndroidManifest.xml
@@ -15,7 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.security.forensic.tests">
+ package="com.android.server.security.intrusiondetection.tests">
<uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
@@ -25,6 +25,6 @@
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.server.security.forensic.tests"
- android:label="Frameworks Forensic Services Tests"/>
+ android:targetPackage="com.android.server.security.intrusiondetection.tests"
+ android:label="Frameworks IntrusionDetection Services Tests"/>
</manifest>
diff --git a/services/tests/security/forensic/AndroidTest.xml b/services/tests/security/intrusiondetection/AndroidTest.xml
index bbe2e9c303ce..42cb9e3236e0 100644
--- a/services/tests/security/forensic/AndroidTest.xml
+++ b/services/tests/security/intrusiondetection/AndroidTest.xml
@@ -13,19 +13,19 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Runs Frameworks Forensic Service tests.">
+<configuration description="Runs Frameworks IntrusionDetection Service tests.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-instrumentation" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true"/>
- <option name="test-file-name" value="ForensicServiceTests.apk"/>
+ <option name="test-file-name" value="IntrusionDetectionServiceTests.apk"/>
<option name="install-arg" value="-t" />
</target_preparer>
- <option name="test-tag" value="ForensicServiceTests" />
+ <option name="test-tag" value="IntrusionDetectionServiceTests" />
<test class="com.android.tradefed.testtype.InstrumentationTest" >
- <option name="package" value="com.android.server.security.forensic.tests" />
+ <option name="package" value="com.android.server.security.intrusiondetection.tests" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
diff --git a/services/tests/security/intrusiondetection/OWNERS b/services/tests/security/intrusiondetection/OWNERS
new file mode 100644
index 000000000000..2157972e06e8
--- /dev/null
+++ b/services/tests/security/intrusiondetection/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 36824
+
+file:platform/frameworks/base:main:/core/java/android/security/intrusiondetection/OWNERS
diff --git a/services/tests/security/intrusiondetection/TEST_MAPPING b/services/tests/security/intrusiondetection/TEST_MAPPING
new file mode 100644
index 000000000000..24d63e36e32b
--- /dev/null
+++ b/services/tests/security/intrusiondetection/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "postsubmit": [
+ {
+ "name": "IntrusionDetectionServiceTests"
+ }
+ ]
+}
diff --git a/services/tests/security/forensic/src/com/android/server/security/forensic/ForensicServiceTest.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
index 03c449cc8d69..bc854cf6488b 100644
--- a/services/tests/security/forensic/src/com/android/server/security/forensic/ForensicServiceTest.java
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.android.server.security.forensic;
+package com.android.server.security.intrusiondetection;
-import static android.Manifest.permission.MANAGE_FORENSIC_STATE;
-import static android.Manifest.permission.READ_FORENSIC_STATE;
+import static android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE;
+import static android.Manifest.permission.READ_INTRUSION_DETECTION_STATE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -40,9 +40,9 @@ import android.os.PermissionEnforcer;
import android.os.RemoteException;
import android.os.test.FakePermissionEnforcer;
import android.os.test.TestLooper;
-import android.security.forensic.ForensicEvent;
-import android.security.forensic.IForensicServiceCommandCallback;
-import android.security.forensic.IForensicServiceStateCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceCommandCallback;
+import android.security.intrusiondetection.IIntrusionDetectionServiceStateCallback;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
import androidx.test.core.app.ApplicationProvider;
@@ -56,23 +56,27 @@ import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
import java.util.List;
-public class ForensicServiceTest {
- private static final int STATE_UNKNOWN = IForensicServiceStateCallback.State.UNKNOWN;
- private static final int STATE_DISABLED = IForensicServiceStateCallback.State.DISABLED;
- private static final int STATE_ENABLED = IForensicServiceStateCallback.State.ENABLED;
+public class IntrusionDetectionServiceTest {
+ private static final int STATE_UNKNOWN =
+ IIntrusionDetectionServiceStateCallback.State.UNKNOWN;
+ private static final int STATE_DISABLED =
+ IIntrusionDetectionServiceStateCallback.State.DISABLED;
+ private static final int STATE_ENABLED =
+ IIntrusionDetectionServiceStateCallback.State.ENABLED;
- private static final int ERROR_UNKNOWN = IForensicServiceCommandCallback.ErrorCode.UNKNOWN;
+ private static final int ERROR_UNKNOWN =
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.UNKNOWN;
private static final int ERROR_PERMISSION_DENIED =
- IForensicServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.PERMISSION_DENIED;
private static final int ERROR_TRANSPORT_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.TRANSPORT_UNAVAILABLE;
private static final int ERROR_DATA_SOURCE_UNAVAILABLE =
- IForensicServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
+ IIntrusionDetectionServiceCommandCallback.ErrorCode.DATA_SOURCE_UNAVAILABLE;
private Context mContext;
- private ForensicEventTransportConnection mForensicEventTransportConnection;
+ private IntrusionDetectionEventTransportConnection mIntrusionDetectionEventTransportConnection;
private DataAggregator mDataAggregator;
- private ForensicService mForensicService;
+ private IntrusionDetectionService mIntrusionDetectionService;
private TestLooper mTestLooper;
private Looper mLooper;
private TestLooper mTestLooperOfDataAggregator;
@@ -85,58 +89,58 @@ public class ForensicServiceTest {
mContext = spy(ApplicationProvider.getApplicationContext());
mPermissionEnforcer = new FakePermissionEnforcer();
- mPermissionEnforcer.grant(READ_FORENSIC_STATE);
- mPermissionEnforcer.grant(MANAGE_FORENSIC_STATE);
+ mPermissionEnforcer.grant(READ_INTRUSION_DETECTION_STATE);
+ mPermissionEnforcer.grant(MANAGE_INTRUSION_DETECTION_STATE);
mTestLooper = new TestLooper();
mLooper = mTestLooper.getLooper();
mTestLooperOfDataAggregator = new TestLooper();
mLooperOfDataAggregator = mTestLooperOfDataAggregator.getLooper();
- mForensicService = new ForensicService(new MockInjector(mContext));
- mForensicService.onStart();
+ mIntrusionDetectionService = new IntrusionDetectionService(new MockInjector(mContext));
+ mIntrusionDetectionService.onStart();
}
@Test
public void testAddStateCallback_NoPermission() {
- mPermissionEnforcer.revoke(READ_FORENSIC_STATE);
+ mPermissionEnforcer.revoke(READ_INTRUSION_DETECTION_STATE);
StateCallback scb = new StateCallback();
assertEquals(STATE_UNKNOWN, scb.mState);
assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().addStateCallback(scb));
+ () -> mIntrusionDetectionService.getBinderService().addStateCallback(scb));
}
@Test
public void testRemoveStateCallback_NoPermission() {
- mPermissionEnforcer.revoke(READ_FORENSIC_STATE);
+ mPermissionEnforcer.revoke(READ_INTRUSION_DETECTION_STATE);
StateCallback scb = new StateCallback();
assertEquals(STATE_UNKNOWN, scb.mState);
assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().removeStateCallback(scb));
+ () -> mIntrusionDetectionService.getBinderService().removeStateCallback(scb));
}
@Test
public void testEnable_NoPermission() {
- mPermissionEnforcer.revoke(MANAGE_FORENSIC_STATE);
+ mPermissionEnforcer.revoke(MANAGE_INTRUSION_DETECTION_STATE);
CommandCallback ccb = new CommandCallback();
assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().enable(ccb));
+ () -> mIntrusionDetectionService.getBinderService().enable(ccb));
}
@Test
public void testDisable_NoPermission() {
- mPermissionEnforcer.revoke(MANAGE_FORENSIC_STATE);
+ mPermissionEnforcer.revoke(MANAGE_INTRUSION_DETECTION_STATE);
CommandCallback ccb = new CommandCallback();
assertThrows(SecurityException.class,
- () -> mForensicService.getBinderService().disable(ccb));
+ () -> mIntrusionDetectionService.getBinderService().disable(ccb));
}
@Test
public void testAddStateCallback_Disabled() throws RemoteException {
StateCallback scb = new StateCallback();
assertEquals(STATE_UNKNOWN, scb.mState);
- mForensicService.getBinderService().addStateCallback(scb);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb.mState);
}
@@ -145,35 +149,35 @@ public class ForensicServiceTest {
public void testAddStateCallback_Disabled_TwoStateCallbacks() throws RemoteException {
StateCallback scb1 = new StateCallback();
assertEquals(STATE_UNKNOWN, scb1.mState);
- mForensicService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
StateCallback scb2 = new StateCallback();
assertEquals(STATE_UNKNOWN, scb2.mState);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb2.mState);
}
@Test
public void testRemoveStateCallback() throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
+ mIntrusionDetectionService.setState(STATE_DISABLED);
StateCallback scb1 = new StateCallback();
StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
assertEquals(STATE_DISABLED, scb2.mState);
doReturn(true).when(mDataAggregator).initialize();
- doReturn(true).when(mForensicEventTransportConnection).initialize();
+ doReturn(true).when(mIntrusionDetectionEventTransportConnection).initialize();
- mForensicService.getBinderService().removeStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().removeStateCallback(scb2);
CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
+ mIntrusionDetectionService.getBinderService().enable(ccb);
mTestLooper.dispatchAll();
assertEquals(STATE_ENABLED, scb1.mState);
assertEquals(STATE_DISABLED, scb2.mState);
@@ -182,19 +186,19 @@ public class ForensicServiceTest {
@Test
public void testEnable_FromDisabled_TwoStateCallbacks() throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
+ mIntrusionDetectionService.setState(STATE_DISABLED);
StateCallback scb1 = new StateCallback();
StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
assertEquals(STATE_DISABLED, scb2.mState);
- doReturn(true).when(mForensicEventTransportConnection).initialize();
+ doReturn(true).when(mIntrusionDetectionEventTransportConnection).initialize();
CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
+ mIntrusionDetectionService.getBinderService().enable(ccb);
mTestLooper.dispatchAll();
verify(mDataAggregator, times(1)).enable();
@@ -206,17 +210,17 @@ public class ForensicServiceTest {
@Test
public void testEnable_FromEnabled_TwoStateCallbacks()
throws RemoteException {
- mForensicService.setState(STATE_ENABLED);
+ mIntrusionDetectionService.setState(STATE_ENABLED);
StateCallback scb1 = new StateCallback();
StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_ENABLED, scb1.mState);
assertEquals(STATE_ENABLED, scb2.mState);
CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
+ mIntrusionDetectionService.getBinderService().enable(ccb);
mTestLooper.dispatchAll();
assertEquals(STATE_ENABLED, scb1.mState);
@@ -226,17 +230,17 @@ public class ForensicServiceTest {
@Test
public void testDisable_FromDisabled_TwoStateCallbacks() throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
+ mIntrusionDetectionService.setState(STATE_DISABLED);
StateCallback scb1 = new StateCallback();
StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
assertEquals(STATE_DISABLED, scb2.mState);
CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().disable(ccb);
+ mIntrusionDetectionService.getBinderService().disable(ccb);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
@@ -246,22 +250,22 @@ public class ForensicServiceTest {
@Test
public void testDisable_FromEnabled_TwoStateCallbacks() throws RemoteException {
- mForensicService.setState(STATE_ENABLED);
+ mIntrusionDetectionService.setState(STATE_ENABLED);
StateCallback scb1 = new StateCallback();
StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_ENABLED, scb1.mState);
assertEquals(STATE_ENABLED, scb2.mState);
- doNothing().when(mForensicEventTransportConnection).release();
+ doNothing().when(mIntrusionDetectionEventTransportConnection).release();
ServiceThread mockThread = spy(ServiceThread.class);
mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().disable(ccb);
+ mIntrusionDetectionService.getBinderService().disable(ccb);
mTestLooper.dispatchAll();
mTestLooperOfDataAggregator.dispatchAll();
// TODO: We can verify the data sources once we implement them.
@@ -271,23 +275,23 @@ public class ForensicServiceTest {
assertNull(ccb.mErrorCode);
}
- @Ignore("Enable once the ForensicEventTransportConnection is ready")
+ @Ignore("Enable once the IntrusionDetectionEventTransportConnection is ready")
@Test
public void testEnable_FromDisable_TwoStateCallbacks_TransportUnavailable()
throws RemoteException {
- mForensicService.setState(STATE_DISABLED);
+ mIntrusionDetectionService.setState(STATE_DISABLED);
StateCallback scb1 = new StateCallback();
StateCallback scb2 = new StateCallback();
- mForensicService.getBinderService().addStateCallback(scb1);
- mForensicService.getBinderService().addStateCallback(scb2);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb1);
+ mIntrusionDetectionService.getBinderService().addStateCallback(scb2);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
assertEquals(STATE_DISABLED, scb2.mState);
- doReturn(false).when(mForensicEventTransportConnection).initialize();
+ doReturn(false).when(mIntrusionDetectionEventTransportConnection).initialize();
CommandCallback ccb = new CommandCallback();
- mForensicService.getBinderService().enable(ccb);
+ mIntrusionDetectionService.getBinderService().enable(ccb);
mTestLooper.dispatchAll();
assertEquals(STATE_DISABLED, scb1.mState);
assertEquals(STATE_DISABLED, scb2.mState);
@@ -297,46 +301,49 @@ public class ForensicServiceTest {
@Test
public void testDataAggregator_AddBatchData() {
- mForensicService.setState(STATE_ENABLED);
+ mIntrusionDetectionService.setState(STATE_ENABLED);
ServiceThread mockThread = spy(ServiceThread.class);
mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
SecurityEvent securityEvent = new SecurityEvent(0, new byte[0]);
- ForensicEvent eventOne = new ForensicEvent(securityEvent);
+ IntrusionDetectionEvent eventOne = new IntrusionDetectionEvent(securityEvent);
- ConnectEvent connectEvent = new ConnectEvent("127.0.0.1", 80, null, 0);
- ForensicEvent eventTwo = new ForensicEvent(connectEvent);
+ ConnectEvent connectEvent = new ConnectEvent(
+ "127.0.0.1", 80, null, 0);
+ IntrusionDetectionEvent eventTwo = new IntrusionDetectionEvent(connectEvent);
- DnsEvent dnsEvent = new DnsEvent(null, new String[] {"127.0.0.1"}, 1, null, 0);
- ForensicEvent eventThree = new ForensicEvent(dnsEvent);
+ DnsEvent dnsEvent = new DnsEvent(
+ null, new String[] {"127.0.0.1"}, 1, null, 0);
+ IntrusionDetectionEvent eventThree = new IntrusionDetectionEvent(dnsEvent);
- List<ForensicEvent> events = new ArrayList<>();
+ List<IntrusionDetectionEvent> events = new ArrayList<>();
events.add(eventOne);
events.add(eventTwo);
events.add(eventThree);
- doReturn(true).when(mForensicEventTransportConnection).addData(any());
+ doReturn(true).when(mIntrusionDetectionEventTransportConnection).addData(any());
mDataAggregator.addBatchData(events);
mTestLooperOfDataAggregator.dispatchAll();
mTestLooper.dispatchAll();
- ArgumentCaptor<List<ForensicEvent>> captor = ArgumentCaptor.forClass(List.class);
- verify(mForensicEventTransportConnection).addData(captor.capture());
- List<ForensicEvent> receivedEvents = captor.getValue();
+ ArgumentCaptor<List<IntrusionDetectionEvent>> captor = ArgumentCaptor.forClass(List.class);
+ verify(mIntrusionDetectionEventTransportConnection).addData(captor.capture());
+ List<IntrusionDetectionEvent> receivedEvents = captor.getValue();
assertEquals(receivedEvents.size(), 3);
- assertEquals(receivedEvents.get(0).getType(), ForensicEvent.SECURITY_EVENT);
+ assertEquals(receivedEvents.get(0).getType(), IntrusionDetectionEvent.SECURITY_EVENT);
assertNotNull(receivedEvents.get(0).getSecurityEvent());
- assertEquals(receivedEvents.get(1).getType(), ForensicEvent.NETWORK_EVENT_CONNECT);
+ assertEquals(receivedEvents.get(1).getType(),
+ IntrusionDetectionEvent.NETWORK_EVENT_CONNECT);
assertNotNull(receivedEvents.get(1).getConnectEvent());
- assertEquals(receivedEvents.get(2).getType(), ForensicEvent.NETWORK_EVENT_DNS);
+ assertEquals(receivedEvents.get(2).getType(), IntrusionDetectionEvent.NETWORK_EVENT_DNS);
assertNotNull(receivedEvents.get(2).getDnsEvent());
}
- private class MockInjector implements ForensicService.Injector {
+ private class MockInjector implements IntrusionDetectionService.Injector {
private final Context mContext;
MockInjector(Context context) {
@@ -359,19 +366,22 @@ public class ForensicServiceTest {
}
@Override
- public ForensicEventTransportConnection getForensicEventransportConnection() {
- mForensicEventTransportConnection = spy(new ForensicEventTransportConnection(mContext));
- return mForensicEventTransportConnection;
+ public IntrusionDetectionEventTransportConnection
+ getIntrusionDetectionEventransportConnection() {
+ mIntrusionDetectionEventTransportConnection =
+ spy(new IntrusionDetectionEventTransportConnection(mContext));
+ return mIntrusionDetectionEventTransportConnection;
}
@Override
- public DataAggregator getDataAggregator(ForensicService forensicService) {
- mDataAggregator = spy(new DataAggregator(mContext, forensicService));
+ public DataAggregator getDataAggregator(
+ IntrusionDetectionService intrusionDetectionService) {
+ mDataAggregator = spy(new DataAggregator(mContext, intrusionDetectionService));
return mDataAggregator;
}
}
- private static class StateCallback extends IForensicServiceStateCallback.Stub {
+ private static class StateCallback extends IIntrusionDetectionServiceStateCallback.Stub {
int mState = STATE_UNKNOWN;
@Override
@@ -380,7 +390,7 @@ public class ForensicServiceTest {
}
}
- private static class CommandCallback extends IForensicServiceCommandCallback.Stub {
+ private static class CommandCallback extends IIntrusionDetectionServiceCommandCallback.Stub {
Integer mErrorCode = null;
public void reset() {
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 d5b930769e43..492838e9b4fb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -1136,7 +1136,6 @@ public class AccessibilityManagerServiceTest {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HARDWARE_SHORTCUT_DISABLES_WARNING)
public void enableHardwareShortcutsForTargets_shortcutDialogSetting_isShown() {
// TODO(b/111889696): Remove the user 0 assumption once we support multi-user
assumeTrue("The test is setup to run as a user 0",
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 51276a4db883..0816e7b61165 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -28,7 +28,7 @@ import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE;
import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
-import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS;
+import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS;
import static com.android.server.hdmi.RoutingControlAction.TIMEOUT_ROUTING_INFORMATION_MS;
import static com.android.server.hdmi.RequestSadAction.RETRY_COUNTER_MAX;
@@ -1877,7 +1877,7 @@ public class HdmiCecLocalDeviceTvTest {
mTestLooper.dispatchAll();
// Skip the LauncherX API timeout.
- mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+ mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -1910,7 +1910,7 @@ public class HdmiCecLocalDeviceTvTest {
mTestLooper.dispatchAll();
// Skip the LauncherX API timeout.
- mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+ mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -1946,7 +1946,7 @@ public class HdmiCecLocalDeviceTvTest {
mTestLooper.dispatchAll();
// Skip the LauncherX API timeout.
- mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+ mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -1989,7 +1989,7 @@ public class HdmiCecLocalDeviceTvTest {
mTestLooper.dispatchAll();
// Skip the LauncherX API timeout.
- mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+ mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(requestActiveSource);
@@ -2026,7 +2026,7 @@ public class HdmiCecLocalDeviceTvTest {
mHdmiControlService.sendCecCommand(setStreamPathFromTv);
// Skip the LauncherX API timeout.
- mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_LAUNCHERX_API_CALL_MS);
+ mTestLooper.moveTimeForward(TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS);
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestActiveSource);
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index 510c2bcabad0..b2a7d20fb948 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -664,7 +664,7 @@ public class MediaProjectionManagerServiceTest {
mClockInjector);
MediaProjectionManagerService.MediaProjection projection = createProjectionPreconditions(
service);
- mClock.fastForward(projection.mDefaultTimeoutMs + 10);
+ mClock.fastForward(projection.mDefaultTimeoutMillis + 10);
// Immediate timeout - so no longer valid.
assertThat(projection.isValid()).isFalse();
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 3e748ffb37e9..2c1e37beda26 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -52,6 +52,7 @@ import android.app.usage.UsageStatsManagerInternal;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
@@ -273,6 +274,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
public String getPackageName() {
return SYSTEM_PACKAGE_NAME;
}
+
+ @Override
+ public ContentResolver getContentResolver() {
+ return mContentResolver;
+ }
}
/** ShortcutService with injection override methods. */
@@ -665,6 +671,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
protected ServiceContext mServiceContext;
protected ClientContext mClientContext;
+ protected ContentResolver mContentResolver;
protected ShortcutServiceTestable mService;
protected ShortcutManagerTestable mManager;
@@ -861,6 +868,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
mServiceContext = spy(new ServiceContext());
mClientContext = new ClientContext();
+ mContentResolver = mock(ContentResolver.class);
mMockPackageManager = mock(PackageManager.class);
mMockPackageManagerInternal = mock(PackageManagerInternal.class);
@@ -982,6 +990,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
}
return userProperties;
});
+ when(mMockUserManagerInternal.getUserInfos()).thenReturn(
+ mUserInfos.values().toArray(new UserInfo[0]));
// User 0 and P0 are always running
mRunningUsers.put(USER_0, true);
diff --git a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
index 24bf6ca507e6..b1df0f1e9cce 100644
--- a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
@@ -60,7 +60,7 @@ public class AdvancedProtectionServiceTest {
public void setup() throws Settings.SettingNotFoundException {
mContext = mock(Context.class);
mPermissionEnforcer = new FakePermissionEnforcer();
- mPermissionEnforcer.grant(Manifest.permission.SET_ADVANCED_PROTECTION_MODE);
+ mPermissionEnforcer.grant(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE);
mPermissionEnforcer.grant(Manifest.permission.QUERY_ADVANCED_PROTECTION_MODE);
mStore = new AdvancedProtectionService.AdvancedProtectionStore(mContext) {
@@ -299,7 +299,7 @@ public class AdvancedProtectionServiceTest {
@Test
public void testSetProtection_withoutPermission() {
- mPermissionEnforcer.revoke(Manifest.permission.SET_ADVANCED_PROTECTION_MODE);
+ mPermissionEnforcer.revoke(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE);
assertThrows(SecurityException.class, () -> mService.setAdvancedProtectionEnabled(true));
}
diff --git a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java
index 2238a1be97a1..ee8eb9b35088 100644
--- a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java
@@ -19,12 +19,14 @@ package com.android.server.security.authenticationpolicy;
import static android.adaptiveauth.Flags.FLAG_ENABLE_ADAPTIVE_AUTH;
import static android.adaptiveauth.Flags.FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS;
import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS;
+import static android.security.authenticationpolicy.AuthenticationPolicyManager.ERROR_UNSUPPORTED;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;
import static com.android.server.security.authenticationpolicy.AuthenticationPolicyService.MAX_ALLOWED_FAILED_AUTH_ATTEMPTS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -95,6 +97,8 @@ public class AuthenticationPolicyServiceTest {
private WindowManagerInternal mWindowManager;
@Mock
private UserManagerInternal mUserManager;
+ @Mock
+ private SecureLockDeviceServiceInternal mSecureLockDeviceService;
@Captor
ArgumentCaptor<LockSettingsStateListener> mLockSettingsStateListenerCaptor;
@@ -123,6 +127,11 @@ public class AuthenticationPolicyServiceTest {
LocalServices.addService(WindowManagerInternal.class, mWindowManager);
LocalServices.removeServiceForTest(UserManagerInternal.class);
LocalServices.addService(UserManagerInternal.class, mUserManager);
+ if (android.security.Flags.secureLockdown()) {
+ LocalServices.removeServiceForTest(SecureLockDeviceServiceInternal.class);
+ LocalServices.addService(SecureLockDeviceServiceInternal.class,
+ mSecureLockDeviceService);
+ }
mAuthenticationPolicyService = new AuthenticationPolicyService(
mContext, mLockPatternUtils);
@@ -136,6 +145,12 @@ public class AuthenticationPolicyServiceTest {
// Set PRIMARY_USER_ID as the parent of MANAGED_PROFILE_USER_ID
when(mUserManager.getProfileParentId(eq(MANAGED_PROFILE_USER_ID)))
.thenReturn(PRIMARY_USER_ID);
+ if (android.security.Flags.secureLockdown()) {
+ when(mSecureLockDeviceService.enableSecureLockDevice(any()))
+ .thenReturn(ERROR_UNSUPPORTED);
+ when(mSecureLockDeviceService.disableSecureLockDevice(any()))
+ .thenReturn(ERROR_UNSUPPORTED);
+ }
}
@After
@@ -143,6 +158,9 @@ public class AuthenticationPolicyServiceTest {
LocalServices.removeServiceForTest(LockSettingsInternal.class);
LocalServices.removeServiceForTest(WindowManagerInternal.class);
LocalServices.removeServiceForTest(UserManagerInternal.class);
+ if (android.security.Flags.secureLockdown()) {
+ LocalServices.removeServiceForTest(SecureLockDeviceServiceInternal.class);
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 3bc089fb3f5d..842c441e09f2 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -691,6 +691,40 @@ public class SystemConfigTest {
assertThat(actual).isEqualTo(expected);
}
+ /**
+ * Tests that readPermissions works correctly for the tags:
+ * disabled-in-sku, enabled-in-sku-override.
+ * I.e. that disabled-in-sku add package to block list and
+ * enabled-in-sku-override removes package from the list.
+ */
+ @Test
+ public void testDisablePackageInSku() throws Exception {
+ final String disable_in_sku =
+ "<config>\n"
+ + " <disabled-in-sku package=\"com.sony.product1.app\"/>\n"
+ + " <disabled-in-sku package=\"com.sony.product2.app\"/>\n"
+ + "</config>\n";
+
+ final String enable_in_sku_override =
+ "<config>\n"
+ + " <enabled-in-sku-override package=\"com.sony.product2.app\"/>\n"
+ + "</config>\n";
+
+ final File folder1 = createTempSubfolder("folder1");
+ createTempFile(folder1, "permissionFile1.xml", disable_in_sku);
+
+ final File folder2 = createTempSubfolder("folder2");
+ createTempFile(folder2, "permissionFile2.xml", enable_in_sku_override);
+
+ readPermissions(folder1, /* Grant all permission flags */ ~0);
+ readPermissions(folder2, /* Grant all permission flags */ ~0);
+
+ final ArraySet<String> blocklist = mSysConfig.getDisabledUntilUsedPreinstalledCarrierApps();
+
+ assertThat(blocklist).contains("com.sony.product1.app");
+ assertThat(blocklist).doesNotContain("com.sony.product2.app");
+ }
+
private void parseSharedLibraries(String contents) throws IOException {
File folder = createTempSubfolder("permissions_folder");
createTempFile(folder, "permissions.xml", contents);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 6af65423415b..dd278fccad14 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -2170,6 +2170,174 @@ public class GroupHelperTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testRemoveChildNotification_summaryForceGrouped() {
+ // Check that removing all child notifications from a group will trigger empty summary
+ // force grouping re-evaluation
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ // Post summaries without children, below the force grouping limit
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(summary);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ // Post a valid (full) group
+ final int summaryId = 4242;
+ final int numChildren = 3;
+ final ArrayList<NotificationRecord> childrenToRemove = new ArrayList<>();
+ NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+ String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp " + summaryId, true);
+ notificationList.add(summary);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ for (int i = 0; i < numChildren; i++) {
+ NotificationRecord child = getNotificationRecord(pkg, summaryId + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + summaryId, false);
+ notificationList.add(child);
+ // schedule all children for removal
+ childrenToRemove.add(child);
+ }
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+
+ // Remove all child notifications from the valid group => summary without children
+ Mockito.reset(mCallback);
+ for (NotificationRecord r: childrenToRemove) {
+ notificationList.remove(r);
+ mGroupHelper.onNotificationRemoved(r, notificationList);
+ }
+ // Only call onGroupedNotificationRemovedWithDelay with the summary notification
+ mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
+ summaryByGroup);
+
+ // Check that the summaries were force grouped
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testRemoveChildNotification_groupBecomesSingleton() {
+ // Check that removing child notifications from a group will trigger singleton force
+ // grouping re-evaluation
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ // Post singleton groups, under forced group limit
+ for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT - 1; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i,
+ String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(summary);
+ NotificationRecord child = getNotificationRecord(pkg, i + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + i, false);
+ notificationList.add(child);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ // Post a valid (full) group
+ final int summaryId = 4242;
+ final int numChildren = 3;
+ final ArrayList<NotificationRecord> childrenToRemove = new ArrayList<>();
+ NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+ String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp " + summaryId, true);
+ notificationList.add(summary);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ for (int i = 0; i < numChildren; i++) {
+ NotificationRecord child = getNotificationRecord(pkg, summaryId + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + summaryId, false);
+ notificationList.add(child);
+
+ // schedule all children except one for removal
+ if (i < numChildren - 1) {
+ childrenToRemove.add(child);
+ }
+ }
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+
+ // Remove some child notifications from the valid group, transform into a singleton group
+ Mockito.reset(mCallback);
+ for (NotificationRecord r: childrenToRemove) {
+ notificationList.remove(r);
+ mGroupHelper.onNotificationRemoved(r, notificationList);
+ }
+ // Only call onGroupedNotificationRemovedWithDelay with the summary notification
+ mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
+ summaryByGroup);
+
+ // Check that the singleton groups were force grouped
+ final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+ AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+ eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+ eq(expectedGroupKey), eq(true));
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+ verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+ any());
+ verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary(
+ anyString());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+ public void testRemoveAllGroupNotifications_noForceGrouping() {
+ // Check that removing all notifications from a group will not trigger any force grouping
+ // re-evaluation
+ final List<NotificationRecord> notificationList = new ArrayList<>();
+ final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+ final String pkg = "package";
+ // Post summaries without children, below the force grouping limit
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+ NotificationRecord summary = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+ UserHandle.SYSTEM, "testGrp " + i, true);
+ notificationList.add(summary);
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ }
+ // Post a valid (full) group
+ final int summaryId = 4242;
+ final int numChildren = 3;
+ final String groupToRemove = "testRemoveGrp";
+ NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+ String.valueOf(summaryId), UserHandle.SYSTEM, groupToRemove + summaryId, true);
+ notificationList.add(summary);
+ summaryByGroup.put(summary.getGroupKey(), summary);
+ for (int i = 0; i < numChildren; i++) {
+ NotificationRecord child = getNotificationRecord(pkg, summaryId + 42,
+ String.valueOf(i + 42), UserHandle.SYSTEM, groupToRemove + summaryId, false);
+ notificationList.add(child);
+ }
+ mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+ verifyZeroInteractions(mCallback);
+
+ // Remove all child notifications from the valid group => summary without children
+ Mockito.reset(mCallback);
+ for (NotificationRecord r: notificationList) {
+ if (r.getGroupKey().contains(groupToRemove)) {
+ r.isCanceled = true;
+ mGroupHelper.onNotificationRemoved(r, notificationList);
+ }
+ }
+ // Only call onGroupedNotificationRemovedWithDelay with the summary notification
+ mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
+ summaryByGroup);
+ // Check that nothing was force grouped
+ verifyZeroInteractions(mCallback);
+ }
+
+ @Test
@EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
public void testMoveAggregateGroups_updateChannel() {
final String pkg = "package";
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index 9eddcc94e650..decbaacdcef9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -60,8 +60,6 @@ import android.testing.TestableContext;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
-import android.util.Log;
-import android.util.Slog;
import android.util.Xml;
import androidx.test.runner.AndroidJUnit4;
@@ -729,4 +727,79 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
.containsExactly(TYPE_PROMOTION);
}
+
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsAndDenies() {
+ // Given that a package is allowed to have its type adjusted,
+ String allowedPackage = "allowed.package";
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
+ mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true);
+
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
+ assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+
+ // Set type adjustment disallowed for this package
+ mAssistants.setTypeAdjustmentForPackageState(allowedPackage, false);
+
+ // Then the package is marked as denied
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+ .containsExactly(allowedPackage);
+ assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+
+ // Set type adjustment allowed again
+ mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true);
+
+ // Then the package is marked as allowed again
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
+ assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+ }
+
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void testSetAssistantAdjustmentKeyTypeStateForPackage_deniesMultiple() {
+ // Given packages not allowed to have their type adjusted,
+ String deniedPkg1 = "denied.Pkg1";
+ String deniedPkg2 = "denied.Pkg2";
+ String deniedPkg3 = "denied.Pkg3";
+ // Set type adjustment disallowed for these packages
+ mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false);
+ mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, false);
+ mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false);
+
+ // Then the packages are marked as denied
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+ .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg2, deniedPkg3));
+ assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1));
+ assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2));
+ assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3));
+
+ // And when we re-allow one of them,
+ mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, true);
+
+ // Then the rest of the original packages are still marked as denied.
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+ .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
+ assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1));
+ assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2));
+ assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3));
+ }
+
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+ public void testSetAssistantAdjustmentKeyTypeStateForPackage_readWriteXml() throws Exception {
+ mAssistants.loadDefaultsFromConfig(true);
+ String deniedPkg1 = "denied.Pkg1";
+ String allowedPkg2 = "allowed.Pkg2";
+ String deniedPkg3 = "denied.Pkg3";
+ // Set type adjustment disallowed or allowed for these packages
+ mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false);
+ mAssistants.setTypeAdjustmentForPackageState(allowedPkg2, true);
+ mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false);
+
+ writeXmlAndReload(USER_ALL);
+
+ assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
+ .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
+ }
} \ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index b34b1fb39a7f..bf3333349b82 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -907,10 +907,18 @@ public class NotificationListenersTest extends UiServiceTestCase {
ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
verify(mNm.mHandler, times(1)).post(runnableCaptor.capture());
runnableCaptor.getValue().run();
- ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
- ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
- verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
- StatusBarNotification sbnResult = sbnCaptor.getValue().get();
+ StatusBarNotification sbnResult = null;
+ if (android.app.Flags.noSbnholder()) {
+ ArgumentCaptor<StatusBarNotification> sbnCaptor =
+ ArgumentCaptor.forClass(StatusBarNotification.class);
+ verify(sysuiListener, times(1)).onNotificationPostedFull(sbnCaptor.capture(), any());
+ sbnResult = sbnCaptor.getValue();
+ } else {
+ ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
+ ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
+ verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
+ sbnResult = sbnCaptor.getValue().get();
+ }
assertThat(sbnResult.getNotification()
.extras.getCharSequence(Notification.EXTRA_TITLE).toString())
.isEqualTo("new title");
@@ -920,7 +928,7 @@ public class NotificationListenersTest extends UiServiceTestCase {
}
@Test
- public void testListenerPostLifeimteExtension_postsToAppropriateListeners() throws Exception {
+ public void testListenerPostLifetimeExtension_postsToAppropriateListeners() throws Exception {
mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
// Create original notification, with FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY.
@@ -998,16 +1006,29 @@ public class NotificationListenersTest extends UiServiceTestCase {
r.run();
}
- ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
- ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
- verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
- StatusBarNotification sbnResult = sbnCaptor.getValue().get();
+ StatusBarNotification sbnResult = null;
+ if (android.app.Flags.noSbnholder()) {
+ ArgumentCaptor<StatusBarNotification> sbnCaptor =
+ ArgumentCaptor.forClass(StatusBarNotification.class);
+ verify(sysuiListener, times(1)).onNotificationPostedFull(sbnCaptor.capture(), any());
+ sbnResult = sbnCaptor.getValue();
+ } else {
+ ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
+ ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
+ verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
+ sbnResult = sbnCaptor.getValue().get();
+ }
assertThat(sbnResult.getNotification()
.extras.getCharSequence(Notification.EXTRA_TITLE).toString())
.isEqualTo("new title");
- verify(otherListener1, times(1)).onNotificationPosted(any(), any());
- verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+ if (android.app.Flags.noSbnholder()) {
+ verify(otherListener1, times(1)).onNotificationPostedFull(any(), any());
+ verify(otherListener2, times(1)).onNotificationPostedFull(any(), any());
+ } else {
+ verify(otherListener1, times(1)).onNotificationPosted(any(), any());
+ verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+ }
}
@Test
@@ -1083,16 +1104,29 @@ public class NotificationListenersTest extends UiServiceTestCase {
r.run();
}
- ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
- ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
- verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
- StatusBarNotification sbnResult = sbnCaptor.getValue().get();
+ StatusBarNotification sbnResult = null;
+ if (android.app.Flags.noSbnholder()) {
+ ArgumentCaptor<StatusBarNotification> sbnCaptor =
+ ArgumentCaptor.forClass(StatusBarNotification.class);
+ verify(sysuiListener, times(1)).onNotificationPostedFull(sbnCaptor.capture(), any());
+ sbnResult = sbnCaptor.getValue();
+ } else {
+ ArgumentCaptor<IStatusBarNotificationHolder> sbnCaptor =
+ ArgumentCaptor.forClass(IStatusBarNotificationHolder.class);
+ verify(sysuiListener, times(1)).onNotificationPosted(sbnCaptor.capture(), any());
+ sbnResult = sbnCaptor.getValue().get();
+ }
assertThat(sbnResult.getNotification()
.extras.getCharSequence(Notification.EXTRA_TITLE).toString())
.isEqualTo("new title");
- verify(otherListener1, times(1)).onNotificationPosted(any(), any());
- verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+ if (android.app.Flags.noSbnholder()) {
+ verify(otherListener1, times(1)).onNotificationPostedFull(any(), any());
+ verify(otherListener2, times(1)).onNotificationPostedFull(any(), any());
+ } else {
+ verify(otherListener1, times(1)).onNotificationPosted(any(), any());
+ verify(otherListener2, times(1)).onNotificationPosted(any(), any());
+ }
}
/**
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 704c1b858b8d..863f42f3d1c1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -232,7 +232,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
import android.content.pm.ModuleInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
@@ -337,12 +336,12 @@ import com.android.server.utils.quota.MultiRateLimiter;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -361,9 +360,6 @@ import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
@@ -378,6 +374,9 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
@SmallTest
@RunWith(ParameterizedAndroidJunit4.class)
@RunWithLooper
@@ -3094,6 +3093,92 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+ public void testScheduleGroupHelperWithDelay_onChildNotificationCanceled() throws Exception {
+ // Post summary + 2 child notification
+ final String originalGroupName = "originalGroup";
+ final int summaryId = 0;
+ final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel,
+ summaryId + 1, originalGroupName, false);
+ mService.addNotification(r1);
+ final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel,
+ summaryId + 2, originalGroupName, false);
+ mService.addNotification(r2);
+ final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel,
+ summaryId, originalGroupName, true);
+ mService.addNotification(summary);
+ final String originalGroupKey = summary.getGroupKey();
+ assertThat(mService.mSummaryByGroupKey).containsEntry(originalGroupKey, summary);
+
+ // Cancel the child notifications
+ mBinderService.cancelNotificationWithTag(r1.getSbn().getPackageName(),
+ r1.getSbn().getPackageName(), r1.getSbn().getTag(),
+ r1.getSbn().getId(), r1.getSbn().getUserId());
+ waitForIdle();
+
+ mBinderService.cancelNotificationWithTag(r2.getSbn().getPackageName(),
+ r2.getSbn().getPackageName(), r2.getSbn().getTag(),
+ r2.getSbn().getId(), r2.getSbn().getUserId());
+ waitForIdle();
+
+ mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+ waitForIdle();
+
+ // Check that onGroupedNotificationRemovedWithDelay was called only once
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any());
+ verify(mGroupHelper, times(1)).onGroupedNotificationRemovedWithDelay(eq(summary), any(),
+ any());
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+ android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+ public void testCleanupScheduleGroupHelperWithDelay_onAllNotificationCanceled()
+ throws Exception {
+ // Post summary + 2 child notification
+ final String originalGroupName = "originalGroup";
+ final int summaryId = 0;
+ final NotificationRecord r1 = generateNotificationRecord(mTestNotificationChannel,
+ summaryId + 1, originalGroupName, false);
+ mService.addNotification(r1);
+ final NotificationRecord r2 = generateNotificationRecord(mTestNotificationChannel,
+ summaryId + 2, originalGroupName, false);
+ mService.addNotification(r2);
+ final NotificationRecord summary = generateNotificationRecord(mTestNotificationChannel,
+ summaryId, originalGroupName, true);
+ mService.addNotification(summary);
+ final String originalGroupKey = summary.getGroupKey();
+ assertThat(mService.mSummaryByGroupKey).containsEntry(originalGroupKey, summary);
+
+ // Cancel all notifications: children + summary
+ mBinderService.cancelNotificationWithTag(r1.getSbn().getPackageName(),
+ r1.getSbn().getPackageName(), r1.getSbn().getTag(),
+ r1.getSbn().getId(), r1.getSbn().getUserId());
+ waitForIdle();
+
+ mBinderService.cancelNotificationWithTag(r2.getSbn().getPackageName(),
+ r2.getSbn().getPackageName(), r2.getSbn().getTag(),
+ r2.getSbn().getId(), r2.getSbn().getUserId());
+ waitForIdle();
+
+ mBinderService.cancelNotificationWithTag(summary.getSbn().getPackageName(),
+ summary.getSbn().getPackageName(), summary.getSbn().getTag(),
+ summary.getSbn().getId(), summary.getSbn().getUserId());
+ waitForIdle();
+
+ mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+ waitForIdle();
+
+ // Check that onGroupedNotificationRemovedWithDelay was never called: summary was canceled
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r1), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(r2), any());
+ verify(mGroupHelper, times(1)).onNotificationRemoved(eq(summary), any());
+ verify(mGroupHelper, never()).onGroupedNotificationRemovedWithDelay(any(), any(), any());
+ }
+
+ @Test
public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
when(mAmi.applyForegroundServiceNotification(
any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY);
@@ -7534,6 +7619,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+ when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
// Set up notifications that will be adjusted
final NotificationRecord r1 = spy(generateNotificationRecord(
@@ -17142,6 +17228,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.WorkerHandler.class);
mService.setHandler(handler);
when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+ when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
Bundle signals = new Bundle();
signals.putInt(KEY_TYPE, TYPE_NEWS);
@@ -17176,10 +17263,44 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @EnableFlags({android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION,
+ android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI})
+ public void testApplyAdjustment_keyTypeForDisallowedPackage_DoesNotApply() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addNotification(r);
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+ when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
+ when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+
+ Bundle signals = new Bundle();
+ signals.putInt(KEY_TYPE, TYPE_NEWS);
+ Adjustment adjustment = new Adjustment(
+ r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+ mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+
+ waitForIdle();
+
+ r.applyAdjustments();
+
+ assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
+
+ // When we block adjustments for this package
+ when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false);
+
+ signals.putInt(KEY_TYPE, TYPE_PROMOTION);
+ mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+ waitForIdle();
+ r.applyAdjustments();
+ // Then the adjustment is not applied.
+ assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
+ }
+
+ @Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testSetCanBePromoted_granted() throws Exception {
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
// qualifying posted notification
Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
.setSmallIcon(android.R.drawable.sym_def_app_icon)
@@ -17254,8 +17375,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testSetCanBePromoted_granted_onlyNotifiesOnce() throws Exception {
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
// qualifying posted notification
Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
.setSmallIcon(android.R.drawable.sym_def_app_icon)
@@ -17285,8 +17404,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testSetCanBePromoted_revoked() throws Exception {
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
// start from true state
mBinderService.setCanBePromoted(mPkg, mUid, true, true);
@@ -17350,8 +17467,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testSetCanBePromoted_revoked_onlyNotifiesOnce() throws Exception {
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
// start from true state
mBinderService.setCanBePromoted(mPkg, mUid, true, true);
@@ -17387,8 +17502,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
public void testPostPromotableNotification() throws Exception {
mBinderService.setCanBePromoted(mPkg, mUid, true, true);
assertThat(mBinderService.appCanBePromoted(mPkg, mUid)).isTrue();
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
.setSmallIcon(android.R.drawable.sym_def_app_icon)
@@ -17415,8 +17528,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testPostPromotableNotification_noPermission() throws Exception {
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
+ mBinderService.setCanBePromoted(mPkg, mUid, false, true);
+ assertThat(mBinderService.appCanBePromoted(mPkg, mUid)).isFalse();
+
Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
.setSmallIcon(android.R.drawable.sym_def_app_icon)
.setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
@@ -17444,8 +17558,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testPostPromotableNotification_unimportantNotification() throws Exception {
mBinderService.setCanBePromoted(mPkg, mUid, true, true);
- mContext.getTestablePermissions().setPermission(
- android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
Notification n = new Notification.Builder(mContext, mMinChannel.getId())
.setSmallIcon(android.R.drawable.sym_def_app_icon)
.setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index dda060d5d586..80e86a15156a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -256,6 +256,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
return FlagsParameterization.allCombinationsOf(
+ android.app.Flags.FLAG_API_RICH_ONGOING,
FLAG_NOTIFICATION_CLASSIFICATION, FLAG_MODES_UI);
}
@@ -6511,12 +6512,21 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
+ @DisableFlags(android.app.Flags.FLAG_UI_RICH_ONGOING)
public void testNoAppHasPermissionToPromoteByDefault() {
mHelper.setShowBadge(PKG_P, UID_P, true);
assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isFalse();
}
@Test
+ @EnableFlags({android.app.Flags.FLAG_API_RICH_ONGOING,
+ android.app.Flags.FLAG_UI_RICH_ONGOING})
+ public void testAllAppsHavePermissionToPromoteByDefault() {
+ mHelper.setShowBadge(PKG_P, UID_P, true);
+ assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isTrue();
+ }
+
+ @Test
@EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
public void testSetCanBePromoted() {
mHelper.setCanBePromoted(PKG_P, UID_P, true, true);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index bf61d06a80a7..09da0156eb82 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -7363,6 +7363,20 @@ public class ZenModeHelperTest extends UiServiceTestCase {
verify(callback, never()).onZenModeChanged();
}
+ @Test
+ @EnableFlags(FLAG_MODES_MULTIUSER)
+ public void getNotificationPolicy_fromUserWithoutZenConfig_returnsDefaultPolicy() {
+ // Set a custom policy for the current user to double check we return a default one below.
+ mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, new Policy(0, 0, 0), ORIGIN_SYSTEM,
+ SYSTEM_UID);
+
+ Policy ghostPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.of(5552368));
+
+ assertThat(ghostPolicy).isNotNull();
+ assertThat(ZenAdapters.notificationPolicyToZenPolicy(ghostPolicy))
+ .isEqualTo(mZenModeHelper.getDefaultZenPolicy());
+ }
+
private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
@Nullable ZenPolicy zenPolicy) {
ZenRule rule = new ZenRule();
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java
index 81026fdf4749..d5548a4f375e 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java
@@ -39,6 +39,7 @@ import android.os.Handler;
import android.os.PersistableBundle;
import android.os.VibrationEffect;
import android.os.test.TestLooper;
+import android.os.vibrator.BasicPwleSegment;
import android.os.vibrator.Flags;
import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.PrimitiveSegment;
@@ -80,7 +81,12 @@ public class DeviceAdapterTest {
private static final int TEST_MIN_ENVELOPE_EFFECT_CONTROL_POINT_DURATION_MILLIS = 20;
private static final float[] TEST_FREQUENCIES_HZ = new float[]{30f, 50f, 100f, 120f, 150f};
private static final float[] TEST_OUTPUT_ACCELERATIONS_GS =
- new float[]{0.3f, 0.5f, 1.0f, 0.8f, 0.6f};
+ new float[]{0.0f, 3.0f, 4.0f, 2.0f, 1.0f};
+
+ private static final float[] TEST_BASIC_FREQUENCIES_HZ = new float[]{50f, 200f, 400f, 500f};
+ private static final float[] TEST_BASIC_OUTPUT_ACCELERATIONS_GS =
+ new float[]{0.05f, 0.5f, 2.0f, 1.0f};
+
private static final float PWLE_V2_MIN_FREQUENCY = TEST_FREQUENCIES_HZ[0];
private static final float PWLE_V2_MAX_FREQUENCY =
TEST_FREQUENCIES_HZ[TEST_FREQUENCIES_HZ.length - 1];
@@ -397,6 +403,46 @@ public class DeviceAdapterTest {
}
@Test
+ @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public void testBasicPwleSegment_withoutPwleV2Capability_returnsNull() {
+ VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+ new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.5f, 100),
+ new BasicPwleSegment(0.2f, 0.8f, 0.2f, 0.4f, 20),
+ new BasicPwleSegment(0.8f, 0.2f, 0.4f, 0.5f, 100),
+ new BasicPwleSegment(0.2f, 0.65f, 0.5f, 0.5f, 50)),
+ /* repeatIndex= */ 1);
+
+ VibrationEffect.Composed adaptedEffect =
+ (VibrationEffect.Composed) mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect);
+ assertThat(adaptedEffect).isNull();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public void testBasicPwleSegment_withPwleV2Capability_returnsAdaptedSegments() {
+ VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
+ new BasicPwleSegment(0.0f, 0.5f, 0.0f, 0.5f, 20),
+ new BasicPwleSegment(0.5f, 1.0f, 0.5f, 1.0f, 100),
+ new BasicPwleSegment(1.0f, 0.0f, 1.0f, 0.5f, 100)),
+ /* repeatIndex= */ 1);
+
+
+ VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList(
+ new PwleSegment(0.0f, 0.16522837f, 63.52442f, 281.7622f, 20),
+ new PwleSegment(0.16522837f, 1.0f, 281.7622f, 500f, 100),
+ new PwleSegment(1.0f, 0.0f, 500, 281.7622f, 100)),
+ /* repeatIndex= */ 1);
+
+ SparseArray<VibratorController> vibrators = new SparseArray<>();
+ vibrators.put(PWLE_V2_VIBRATOR_ID,
+ createPwleV2VibratorController(PWLE_V2_VIBRATOR_ID, TEST_BASIC_FREQUENCIES_HZ,
+ TEST_BASIC_OUTPUT_ACCELERATIONS_GS));
+ DeviceAdapter adapter = new DeviceAdapter(mVibrationSettings, vibrators);
+
+ assertThat(adapter.adaptToVibrator(PWLE_V2_VIBRATOR_ID, effect)).isEqualTo(expected);
+ }
+
+ @Test
@DisableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
public void testPrimitiveWithRelativeDelay_withoutFlag_returnsNull() {
VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList(
@@ -477,11 +523,17 @@ public class DeviceAdapterTest {
}
private VibratorController createPwleV2VibratorController(int vibratorId) {
+ return createPwleV2VibratorController(vibratorId, TEST_FREQUENCIES_HZ,
+ TEST_OUTPUT_ACCELERATIONS_GS);
+ }
+
+ private VibratorController createPwleV2VibratorController(int vibratorId, float[] frequencies,
+ float[] accelerations) {
FakeVibratorControllerProvider provider = createVibratorProviderWithEffects(
IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2);
provider.setResonantFrequency(TEST_RESONANT_FREQUENCY);
- provider.setFrequenciesHz(TEST_FREQUENCIES_HZ);
- provider.setOutputAccelerationsGs(TEST_OUTPUT_ACCELERATIONS_GS);
+ provider.setFrequenciesHz(frequencies);
+ provider.setOutputAccelerationsGs(accelerations);
provider.setMaxEnvelopeEffectSize(TEST_MAX_ENVELOPE_EFFECT_SIZE);
provider.setMinEnvelopeEffectControlPointDurationMillis(
TEST_MIN_ENVELOPE_EFFECT_CONTROL_POINT_DURATION_MILLIS);
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
index eb44daabd002..b4345b62c251 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -905,10 +905,10 @@ public class VibrationThreadTest {
fakeVibrator.setMinEnvelopeEffectControlPointDurationMillis(20);
VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
- .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 30)
+ .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30)
+ .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 30)
.build();
HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
@@ -930,6 +930,41 @@ public class VibrationThreadTest {
@Test
@EnableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
+ public void vibrate_singleVibratorBasicPwle_runsComposePwleV2() {
+ FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+ fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2);
+ fakeVibrator.setResonantFrequency(150);
+ fakeVibrator.setFrequenciesHz(new float[]{50f, 100f, 120f, 150f});
+ fakeVibrator.setOutputAccelerationsGs(new float[]{0.05f, 1.0f, 3.0f, 2.0f});
+ fakeVibrator.setMaxEnvelopeEffectSize(10);
+ fakeVibrator.setMinEnvelopeEffectControlPointDurationMillis(20);
+
+ VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
+ .setInitialSharpness(/*initialSharpness=*/ 1.0f)
+ .addControlPoint(/*intensity=*/ 1.0f, /*sharpness=*/ 1.0f, /*durationMillis=*/ 20)
+ .addControlPoint(/*intensity=*/ 1.0f, /*sharpness=*/ 1.0f, /*durationMillis=*/ 100)
+ .addControlPoint(/*intensity=*/ 0.0f, /*sharpness=*/ 1.0f, /*durationMillis=*/ 100)
+ .build();
+
+ HalVibration vibration = startThreadAndDispatcher(effect);
+ waitForCompletion();
+
+ verify(mManagerHooks).noteVibratorOn(eq(UID), eq(220L));
+ verify(mManagerHooks).noteVibratorOff(eq(UID));
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
+ assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+ assertEquals(Arrays.asList(
+ expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 0),
+ expectedPwle(/*amplitude=*/ 1.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 20),
+ expectedPwle(/*amplitude=*/ 1.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 100),
+ expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 150f, /*timeMillis=*/ 100)
+ ), fakeVibrator.getEffectPwlePoints(vibration.id));
+
+ }
+
+ @Test
+ @EnableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS)
public void vibrate_singleVibratorPwle_withInitialFrequency_runsComposePwleV2() {
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2);
@@ -941,10 +976,10 @@ public class VibrationThreadTest {
VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
.setInitialFrequencyHz(/*initialFrequencyHz=*/ 30)
- .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30)
- .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 20)
- .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*timeMillis=*/ 30)
+ .addControlPoint(/*amplitude=*/ 0.1f, /*frequencyHz=*/ 60f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.3f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30)
+ .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 20)
+ .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 120f, /*durationMillis=*/ 30)
.build();
HalVibration vibration = startThreadAndDispatcher(effect);
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
index efe1af336ecd..8b861ed553ce 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
@@ -79,6 +79,7 @@ public class SoundTriggerMiddlewareLoggingLatencyTest {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.adoptShellPermissionIdentity(Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG,
Manifest.permission.READ_DEVICE_CONFIG);
Identity identity = new Identity();
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 6e6b70d319ab..5f2f3ed67432 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -17,10 +17,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.wmtests">
- <!-- Uses API introduced in P (28) -->
+ <!-- Uses API introduced in S (31). Using SDK 31+ avoids Google Play Protect popups. -->
<uses-sdk
android:minSdkVersion="1"
- android:targetSdkVersion="28" />
+ android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
diff --git a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
index 6f9c8904ca32..038e1357159b 100644
--- a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
@@ -40,7 +40,7 @@ import org.junit.runner.RunWith;
*/
@MediumTest
@RunWith(AndroidJUnit4.class)
-@DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_PRESS_GESTURES)
+@DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_KEY_GESTURES)
public class CombinationKeyTests extends ShortcutKeyTestBase {
private static final long A11Y_KEY_HOLD_MILLIS = 3500;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 7f260f85a755..70f57eb40385 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -357,6 +357,25 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase {
assertEquals(activity1.app, mAtm.mTopApp);
}
+ @Test
+ public void testTopResumedActivity_deferResume() {
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ activity2.setState(ActivityRecord.State.RESUMED, "test");
+ assertEquals(activity2.app, mAtm.mTopApp);
+ reset(activity2);
+
+ // Verify that no top-resumed activity changes to the client while defer-resume enabled.
+ mSupervisor.beginDeferResume();
+ activity1.getTask().moveToFront("test");
+ activity1.setState(ActivityRecord.State.RESUMED, "test");
+ verify(activity2, never()).scheduleTopResumedActivityChanged(eq(false));
+
+ // Verify that the change is scheduled to the client after defer-resumed disabled
+ mSupervisor.endDeferResume();
+ verify(activity2).scheduleTopResumedActivityChanged(eq(false));
+ }
+
/**
* We need to launch home again after user unlocked for those displays that do not have
* encryption aware home app.
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
index b91a5b7afe26..d5ed048032e7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
@@ -17,8 +17,8 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
@@ -228,9 +228,8 @@ public class AppCompatCameraOverridesTest extends WindowTestsBase {
}
@Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
- public void testShouldApplyCameraCompatFreeformTreatment_overrideEnabled_returnsFalse() {
+ public void testShouldApplyCameraCompatFreeformTreatment_notEnabledByOverride_returnsFalse() {
runTestScenario((robot) -> {
robot.activity().createActivityWithComponentInNewTask();
@@ -239,19 +238,9 @@ public class AppCompatCameraOverridesTest extends WindowTestsBase {
}
@Test
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
- public void testShouldApplyCameraCompatFreeformTreatment_disabledByOverride_returnsFalse() {
- runTestScenario((robot) -> {
- robot.activity().createActivityWithComponentInNewTask();
-
- robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
- });
- }
-
- @Test
- @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
- public void testShouldApplyCameraCompatFreeformTreatment_notDisabledByOverride_returnsTrue() {
+ public void testShouldApplyCameraCompatFreeformTreatment_overrideAndFlagEnabled_returnsTrue() {
runTestScenario((robot) -> {
robot.activity().createActivityWithComponentInNewTask();
@@ -261,8 +250,9 @@ public class AppCompatCameraOverridesTest extends WindowTestsBase {
@Test
@EnableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA,
- OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
- public void testShouldRecomputeConfigurationForCameraCompat() {
+ OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA,
+ OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
+ public void testShouldRecomputeConfigurationForFreeformTreatment() {
runTestScenario((robot) -> {
robot.conf().enableCameraCompatSplitScreenAspectRatio(true);
robot.applyOnActivity((a) -> {
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index d6be9159694b..40da9ea2d718 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -66,6 +66,7 @@ import android.view.WindowManager;
import android.window.BackAnimationAdapter;
import android.window.BackMotionEvent;
import android.window.BackNavigationInfo;
+import android.window.IBackAnimationHandoffHandler;
import android.window.IOnBackInvokedCallback;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedCallbackInfo;
@@ -780,6 +781,10 @@ public class BackNavigationControllerTests extends WindowTestsBase {
@Override
public void setTriggerBack(boolean triggerBack) {
}
+
+ @Override
+ public void setHandoffHandler(IBackAnimationHandoffHandler unused) {
+ }
};
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java
index ade591d006f5..da010ae3c96a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java
@@ -333,7 +333,8 @@ public class BackgroundActivityStartControllerExemptionTests {
int realCallingPid = REGULAR_PID_2;
// setup state
- mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid, true);
+ mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid,
+ WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, true);
when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);
// prepare call
@@ -367,7 +368,8 @@ public class BackgroundActivityStartControllerExemptionTests {
int realCallingPid = REGULAR_PID_2;
// setup state
- mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, true);
+ mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid,
+ WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, true);
when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);
// prepare call
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
index e447565a55bd..c427583d3001 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
@@ -25,7 +25,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
@@ -96,61 +96,55 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
private static final String TEST_PACKAGE_1 = "com.android.frameworks.wmtests";
private static final String TEST_PACKAGE_2 = "com.test.package.two";
private static final String CAMERA_ID_1 = "camera-1";
- private static final String CAMERA_ID_2 = "camera-2";
- private CameraManager mMockCameraManager;
- private Handler mMockHandler;
private AppCompatConfiguration mAppCompatConfiguration;
private CameraManager.AvailabilityCallback mCameraAvailabilityCallback;
private CameraCompatFreeformPolicy mCameraCompatFreeformPolicy;
private ActivityRecord mActivity;
- private Task mTask;
private ActivityRefresher mActivityRefresher;
@Before
public void setUp() throws Exception {
mAppCompatConfiguration = mDisplayContent.mWmService.mAppCompatConfiguration;
spyOn(mAppCompatConfiguration);
- when(mAppCompatConfiguration.isCameraCompatTreatmentEnabled())
- .thenReturn(true);
- when(mAppCompatConfiguration.isCameraCompatRefreshEnabled())
- .thenReturn(true);
+ when(mAppCompatConfiguration.isCameraCompatTreatmentEnabled()).thenReturn(true);
+ when(mAppCompatConfiguration.isCameraCompatRefreshEnabled()).thenReturn(true);
when(mAppCompatConfiguration.isCameraCompatRefreshCycleThroughStopEnabled())
.thenReturn(true);
- mMockCameraManager = mock(CameraManager.class);
+ final CameraManager mockCameraManager = mock(CameraManager.class);
doAnswer(invocation -> {
mCameraAvailabilityCallback = invocation.getArgument(1);
return null;
- }).when(mMockCameraManager).registerAvailabilityCallback(
+ }).when(mockCameraManager).registerAvailabilityCallback(
any(Executor.class), any(CameraManager.AvailabilityCallback.class));
- when(mContext.getSystemService(CameraManager.class)).thenReturn(mMockCameraManager);
+ when(mContext.getSystemService(CameraManager.class)).thenReturn(mockCameraManager);
mDisplayContent.setIgnoreOrientationRequest(true);
- mMockHandler = mock(Handler.class);
+ final Handler mockHandler = mock(Handler.class);
- when(mMockHandler.postDelayed(any(Runnable.class), anyLong())).thenAnswer(
+ when(mockHandler.postDelayed(any(Runnable.class), anyLong())).thenAnswer(
invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
});
- mActivityRefresher = new ActivityRefresher(mDisplayContent.mWmService, mMockHandler);
- CameraStateMonitor cameraStateMonitor =
- new CameraStateMonitor(mDisplayContent, mMockHandler);
- mCameraCompatFreeformPolicy =
- new CameraCompatFreeformPolicy(mDisplayContent, cameraStateMonitor,
- mActivityRefresher);
+ mActivityRefresher = new ActivityRefresher(mDisplayContent.mWmService, mockHandler);
+ final CameraStateMonitor cameraStateMonitor = new CameraStateMonitor(mDisplayContent,
+ mockHandler);
+ mCameraCompatFreeformPolicy = new CameraCompatFreeformPolicy(mDisplayContent,
+ cameraStateMonitor, mActivityRefresher);
setDisplayRotation(Surface.ROTATION_90);
mCameraCompatFreeformPolicy.start();
cameraStateMonitor.startListeningToCameraState();
}
- @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testFullscreen_doesNotActivateCameraCompatMode() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT, WINDOWING_MODE_FULLSCREEN);
doReturn(false).when(mActivity).inFreeformWindowingMode();
@@ -160,23 +154,26 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
assertNotInCameraCompatMode();
}
- @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testOrientationUnspecified_doesNotActivateCameraCompatMode() {
configureActivity(SCREEN_ORIENTATION_UNSPECIFIED);
assertNotInCameraCompatMode();
}
- @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testNoCameraConnection_doesNotActivateCameraCompatMode() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
assertNotInCameraCompatMode();
}
- @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testCameraConnected_deviceInPortrait_portraitCameraCompatMode() throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
setDisplayRotation(Surface.ROTATION_0);
@@ -187,6 +184,8 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
}
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testCameraConnected_deviceInLandscape_portraitCameraCompatMode() throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
setDisplayRotation(Surface.ROTATION_270);
@@ -197,6 +196,8 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
}
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testCameraConnected_deviceInPortrait_landscapeCameraCompatMode() throws Exception {
configureActivity(SCREEN_ORIENTATION_LANDSCAPE);
setDisplayRotation(Surface.ROTATION_0);
@@ -207,6 +208,8 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
}
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testCameraConnected_deviceInLandscape_landscapeCameraCompatMode() throws Exception {
configureActivity(SCREEN_ORIENTATION_LANDSCAPE);
setDisplayRotation(Surface.ROTATION_270);
@@ -216,8 +219,9 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
assertActivityRefreshRequested(/* refreshRequested */ false);
}
- @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testCameraReconnected_cameraCompatModeAndRefresh() throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
setDisplayRotation(Surface.ROTATION_270);
@@ -236,6 +240,8 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
}
@Test
+ @EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testCameraOpenedForDifferentPackage_notInCameraCompatMode() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
@@ -246,27 +252,32 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
- @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
- public void testShouldApplyCameraCompatFreeformTreatment_overrideEnabled_returnsFalse() {
+ public void testShouldApplyCameraCompatFreeformTreatment_overrideNotEnabled_returnsFalse() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mActivity.info
- .isChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT));
- assertFalse(mCameraCompatFreeformPolicy.isCameraCompatForFreeformEnabledForActivity(
- mActivity));
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+ assertFalse(mCameraCompatFreeformPolicy.isTreatmentEnabledForActivity(mActivity,
+ /* checkOrientation */ true));
}
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
- public void testShouldApplyCameraCompatFreeformTreatment_notDisabledByOverride_returnsTrue() {
+ @EnableCompatChanges(OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT)
+ public void testShouldApplyCameraCompatFreeformTreatment_enabledByOverride_returnsTrue() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
- assertTrue(mCameraCompatFreeformPolicy.isCameraCompatForFreeformEnabledForActivity(
- mActivity));
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+ assertTrue(mActivity.info
+ .isChangeEnabled(OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT));
+ assertTrue(mCameraCompatFreeformPolicy.isTreatmentEnabledForActivity(mActivity,
+ /* checkOrientation */ true));
}
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testShouldRefreshActivity_appBoundsChanged_returnsTrue() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
Configuration oldConfiguration = createConfiguration(/* letterbox= */ false);
@@ -279,6 +290,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testShouldRefreshActivity_displayRotationChanged_returnsTrue() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
Configuration oldConfiguration = createConfiguration(/* letterbox= */ true);
@@ -294,6 +306,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testShouldRefreshActivity_appBoundsNorDisplayChanged_returnsFalse() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
Configuration oldConfiguration = createConfiguration(/* letterbox= */ true);
@@ -309,6 +322,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testOnActivityConfigurationChanging_refreshDisabledViaFlag_noRefresh()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
@@ -324,6 +338,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testOnActivityConfigurationChanging_cycleThroughStopDisabled() throws Exception {
when(mAppCompatConfiguration.isCameraCompatRefreshCycleThroughStopEnabled())
.thenReturn(false);
@@ -338,6 +353,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
@@ -352,6 +368,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testGetCameraCompatAspectRatio_activityNotInCameraCompat_returnsDefaultAspRatio() {
configureActivity(SCREEN_ORIENTATION_FULL_USER);
@@ -365,6 +382,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testGetCameraCompatAspectRatio_activityInCameraCompat_returnsConfigAspectRatio() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
final float configAspectRatio = 1.5f;
@@ -380,6 +398,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
@Test
@EnableFlags(FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT})
public void testGetCameraCompatAspectRatio_inCameraCompatPerAppOverride_returnDefAspectRatio() {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
final float configAspectRatio = 1.5f;
@@ -406,7 +425,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
private void configureActivityAndDisplay(@ScreenOrientation int activityOrientation,
@Orientation int naturalOrientation, @WindowingMode int windowingMode) {
- mTask = new TaskBuilder(mSupervisor)
+ final Task task = new TaskBuilder(mSupervisor)
.setDisplay(mDisplayContent)
.setWindowingMode(windowingMode)
.build();
@@ -416,7 +435,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
.setComponent(ComponentName.createRelative(mContext,
com.android.server.wm.CameraCompatFreeformPolicyTests.class.getName()))
.setScreenOrientation(activityOrientation)
- .setTask(mTask)
+ .setTask(task)
.build();
spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
@@ -429,13 +448,11 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
}
private void assertInCameraCompatMode(@CameraCompatTaskInfo.FreeformCameraCompatMode int mode) {
- assertEquals(mode, mActivity.mAppCompatController.getAppCompatCameraOverrides()
- .getFreeformCameraCompatMode());
+ assertEquals(mode, mCameraCompatFreeformPolicy.getCameraCompatMode(mActivity));
}
private void assertNotInCameraCompatMode() {
- assertEquals(CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController
- .getAppCompatCameraOverrides().getFreeformCameraCompatMode());
+ assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_NONE);
}
private void assertActivityRefreshRequested(boolean refreshRequested) throws Exception {
@@ -471,7 +488,8 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase {
private Configuration createConfiguration(boolean letterbox) {
final Configuration configuration = new Configuration();
- Rect bounds = letterbox ? new Rect(300, 0, 700, 600) : new Rect(0, 0, 1000, 600);
+ Rect bounds = letterbox ? new Rect(/*left*/ 300, /*top*/ 0, /*right*/ 700, /*bottom*/ 600)
+ : new Rect(/*left*/ 0, /*top*/ 0, /*right*/ 1000, /*bottom*/ 600);
configuration.windowConfiguration.setAppBounds(bounds);
return configuration;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index df17cd1d24b7..7ed8283efffd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -496,24 +496,6 @@ public class RecentTasksTest extends WindowTestsBase {
}
@Test
- public void testAppendOrganizedChildTaskInfo() {
- final Task root = createTaskBuilder(".CreatedByOrganizerRoot").build();
- root.mCreatedByOrganizer = true;
- // Add organized and non-organized child.
- final Task child1 = createTaskBuilder(".Task1").setParentTask(root).build();
- final Task child2 = createTaskBuilder(".Task2").setParentTask(root).build();
- doReturn(true).when(child1).isOrganized();
- doReturn(false).when(child2).isOrganized();
- mRecentTasks.add(root);
-
- // Make sure only organized child will be appended.
- final List<RecentTaskInfo> infos = getRecentTasks(0 /* flags */);
- final List<RecentTaskInfo> childrenTaskInfos = infos.get(0).childrenTaskInfos;
- assertEquals(childrenTaskInfos.size(), 1);
- assertEquals(childrenTaskInfos.get(0).taskId, child1.mTaskId);
- }
-
- @Test
public void testAddTasksHomeClearUntrackedTasks_expectFinish() {
// There may be multiple tasks with the same base intent by flags (FLAG_ACTIVITY_NEW_TASK |
// FLAG_ACTIVITY_MULTIPLE_TASK). If the previous task is still active, it should be removed
@@ -1420,46 +1402,6 @@ public class RecentTasksTest extends WindowTestsBase {
}
@Test
- public void testLastSnapshotData_snapshotSaved() {
- final TaskSnapshot snapshot = createSnapshot(new Point(100, 100), new Point(80, 80));
- final Task task1 = createTaskBuilder(".Task").build();
- task1.onSnapshotChanged(snapshot);
-
- mRecentTasks.add(task1);
- final List<RecentTaskInfo> infos = getRecentTasks(0 /* flags */);
- final RecentTaskInfo.PersistedTaskSnapshotData lastSnapshotData =
- infos.get(0).lastSnapshotData;
- assertTrue(lastSnapshotData.taskSize.equals(100, 100));
- assertTrue(lastSnapshotData.bufferSize.equals(80, 80));
- }
-
- @Test
- public void testLastSnapshotData_noBuffer() {
- final Task task1 = createTaskBuilder(".Task").build();
- final TaskSnapshot snapshot = createSnapshot(new Point(100, 100), null);
- task1.onSnapshotChanged(snapshot);
-
- mRecentTasks.add(task1);
- final List<RecentTaskInfo> infos = getRecentTasks(0 /* flags */);
- final RecentTaskInfo.PersistedTaskSnapshotData lastSnapshotData =
- infos.get(0).lastSnapshotData;
- assertTrue(lastSnapshotData.taskSize.equals(100, 100));
- assertNull(lastSnapshotData.bufferSize);
- }
-
- @Test
- public void testLastSnapshotData_notSet() {
- final Task task1 = createTaskBuilder(".Task").build();
-
- mRecentTasks.add(task1);
- final List<RecentTaskInfo> infos = getRecentTasks(0 /* flags */);
- final RecentTaskInfo.PersistedTaskSnapshotData lastSnapshotData =
- infos.get(0).lastSnapshotData;
- assertNull(lastSnapshotData.taskSize);
- assertNull(lastSnapshotData.bufferSize);
- }
-
- @Test
public void testCreateRecentTaskInfo_detachedTask() {
final Task task = createTaskBuilder(".Task").build();
final ComponentName componentName = getUniqueComponentName();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index 3d08ca2905f3..cc38f02ccc4c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -270,6 +270,46 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
}
@Test
+ public void testInsetsAnimationAppOverridePreferredModeId() {
+ final WindowState overrideWindow = createWindow("overrideWindow");
+ overrideWindow.mAttrs.packageName = "com.android.test";
+ overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID;
+ parcelLayoutParams(overrideWindow);
+ assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
+ assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+ assertEquals(FRAME_RATE_VOTE_LOW_EXACT, overrideWindow.mFrameRateVote);
+ assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+
+ overrideWindow.notifyInsetsAnimationRunningStateChanged(true);
+ assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
+ assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+ assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
+ assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ }
+
+ @Test
+ public void testInsetsAnimationAppOverridePreferredRefreshRate() {
+ final WindowState overrideWindow = createWindow("overrideWindow");
+ overrideWindow.mAttrs.packageName = "com.android.test";
+ overrideWindow.mAttrs.preferredRefreshRate = LOW_REFRESH_RATE;
+ parcelLayoutParams(overrideWindow);
+ assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
+ assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+ assertEquals(FRAME_RATE_VOTE_LOW_PREFERRED, overrideWindow.mFrameRateVote);
+ assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+
+ overrideWindow.notifyInsetsAnimationRunningStateChanged(true);
+ assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
+ assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
+ assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
+ assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ }
+
+ @Test
public void testAnimatingCamera() {
final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
cameraUsingWindow.mAttrs.packageName = "com.android.test";
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 41f1e2359c88..ad6611827524 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -4863,7 +4863,7 @@ public class SizeCompatTests extends WindowTestsBase {
@Test
@EnableFlags(Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING)
- public void testCameraCompatAspectRatio_defualtAspectRatioAppliedWhenGreater() {
+ public void testCameraCompatAspectRatio_defaultAspectRatioAppliedWhenGreater() {
// Needed to create camera compat policy in DisplayContent.
allowDesktopMode();
// Create display that has all stable insets and does not rotate.
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 817c368745d1..410fa2879600 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -82,9 +82,9 @@ import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
-import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
import android.util.ArrayMap;
import android.util.Rational;
import android.view.Display;
@@ -544,6 +544,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
}
@Test
+ @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
public void testSetActivityWindowingMode() {
final ActivityRecord record = makePipableActivity();
final Task rootTask = record.getRootTask();
@@ -1302,7 +1303,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
}
@Test
- @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+ @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
public void testEnterPipParams() {
final StubOrganizer o = new StubOrganizer();
mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o);
@@ -1318,7 +1319,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
}
@Test
- @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+ @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
public void testChangePipParams() {
class ChangeSavingOrganizer extends StubOrganizer {
RunningTaskInfo mChangedInfo;
@@ -1890,6 +1891,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
@SuppressWarnings("GuardedBy")
@Test
+ @RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
public void testResumeTopsWhenLeavingPinned() {
final ActivityRecord home = new ActivityBuilder(mAtm).setTask(
mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask()).build();
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6490cbe3e31a..7cfdec664a92 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9734,6 +9734,35 @@ public class CarrierConfigManager {
"carrier_supported_satellite_services_per_provider_bundle";
/**
+ * A PersistableBundle that contains a list of key-value pairs, where the values are integer
+ * arrays.
+ * <p>
+ * Keys are the IDs of regional satellite configs as strings and values are
+ * integer arrays of earfcns in the corresponding regions.
+ *
+ * An example config for two regions "1" and "2":
+ * <pre>{@code
+ * <carrier_config>
+ * <pbundle_as_map name="regional_satellite_earfcn_bundle">
+ * <int-array name = "1" num = "2">
+ * <item value = "100"/>
+ * <item value = "200"/>
+ * </int-array>
+ * <int-array name = "2" num = "1">
+ * <item value = "200"/>
+ * </int-array>
+ * </pbundle_as_map>
+ * </carrier_config>
+ * }</pre>
+ * <p>
+ * This config is empty by default.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+ public static final String KEY_REGIONAL_SATELLITE_EARFCN_BUNDLE =
+ "regional_satellite_earfcn_bundle";
+
+ /**
* This config enables modem to scan satellite PLMNs specified as per
* {@link #KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE} and attach to same
* in case cellular networks are not enabled. This will need specific agreement between
@@ -11264,6 +11293,9 @@ public class CarrierConfigManager {
sDefaults.putPersistableBundle(
KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,
PersistableBundle.EMPTY);
+ sDefaults.putPersistableBundle(
+ KEY_REGIONAL_SATELLITE_EARFCN_BUNDLE,
+ PersistableBundle.EMPTY);
sDefaults.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false);
sDefaults.putInt(KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT, 180);
sDefaults.putIntArray(KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY,
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6f2c8623fd71..9c961c1f0df0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -12239,9 +12239,10 @@ public class TelephonyManager {
* @param subId Subscription ID
* @return true if IMS status is registered, false if the IMS status is not registered or a
* RemoteException occurred.
- * Use {@link ImsMmTelManager.RegistrationCallback} instead.
* @hide
+ * @deprecated Use {@link ImsMmTelManager#getRegistrationState(Executor, Consumer)} instead.
*/
+ @Deprecated
public boolean isImsRegistered(int subId) {
try {
return getITelephony().isImsRegistered(subId);
@@ -12259,8 +12260,10 @@ public class TelephonyManager {
* @return true if IMS status is registered, false if the IMS status is not registered or a
* RemoteException occurred.
* @see SubscriptionManager#getDefaultSubscriptionId()
+ * @deprecated Use {@link ImsMmTelManager#getRegistrationState(Executor, Consumer)} instead.
* @hide
*/
+ @Deprecated
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public boolean isImsRegistered() {
try {
@@ -12277,9 +12280,10 @@ public class TelephonyManager {
* @return true if Voice over LTE is available or false if it is unavailable or unknown.
* @see SubscriptionManager#getDefaultSubscriptionId()
* <p>
- * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
+ * @Deprecated Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
* @hide
*/
+ @Deprecated
@UnsupportedAppUsage
public boolean isVolteAvailable() {
try {
@@ -12297,9 +12301,10 @@ public class TelephonyManager {
* used during creation, the default subscription ID will be used. To query the
* underlying technology that VT is available on, use {@link #getImsRegTechnologyForMmTel}.
* @return true if VT is available, or false if it is unavailable or unknown.
- * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
+ * @Deprecated Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
* @hide
*/
+ @Deprecated
@UnsupportedAppUsage
public boolean isVideoTelephonyAvailable() {
try {
@@ -12313,9 +12318,10 @@ public class TelephonyManager {
* Returns the Status of Wi-Fi calling (Voice over WiFi) for the subscription ID specified.
* @param subId the subscription ID.
* @return true if VoWiFi is available, or false if it is unavailable or unknown.
- * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
+ * @Deprecated Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
* @hide
*/
+ @Deprecated
@UnsupportedAppUsage
public boolean isWifiCallingAvailable() {
try {
@@ -12336,9 +12342,11 @@ public class TelephonyManager {
* other sim's internet, or
* - {@link ImsRegistrationImplBase#REGISTRATION_TECH_NONE} if we are not registered or the
* result is unavailable.
- * Use {@link ImsMmTelManager.RegistrationCallback} instead.
+ * @Deprecated Use {@link ImsMmTelManager#registerImsRegistrationCallback(Executor, RegistrationCallback)}
+ * or {@link ImsMmTelManager#getRegistrationTransportType(Executor, Consumer)} instead.
* @hide
*/
+ @Deprecated
public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel() {
try {
return getITelephony().getImsRegTechnologyForMmTel(getSubId());
diff --git a/telephony/java/android/telephony/satellite/EarfcnRange.java b/telephony/java/android/telephony/satellite/EarfcnRange.java
index 38043b570c2f..207b25d60d90 100644
--- a/telephony/java/android/telephony/satellite/EarfcnRange.java
+++ b/telephony/java/android/telephony/satellite/EarfcnRange.java
@@ -24,6 +24,8 @@ import android.os.Parcelable;
import com.android.internal.telephony.flags.Flags;
+import java.util.Objects;
+
/**
* EARFCN (E-UTRA Absolute Radio Frequency Channel Number): A number that identifies a
* specific frequency channel in LTE/5G NR, used to define the carrier frequency.
@@ -73,10 +75,10 @@ public final class EarfcnRange implements Parcelable {
* @param startEarfcn The starting earfcn value.
* @param endEarfcn The ending earfcn value.
*/
- public EarfcnRange(@IntRange(from = 0, to = 65535) int endEarfcn,
- @IntRange(from = 0, to = 65535) int startEarfcn) {
- mEndEarfcn = endEarfcn;
+ public EarfcnRange(@IntRange(from = 0, to = 65535) int startEarfcn,
+ @IntRange(from = 0, to = 65535) int endEarfcn) {
mStartEarfcn = startEarfcn;
+ mEndEarfcn = endEarfcn;
}
@Override
@@ -85,6 +87,7 @@ public final class EarfcnRange implements Parcelable {
}
@Override
+ @NonNull
public String toString() {
return "startEarfcn: " + mStartEarfcn + ", " + "endEarfcn: " + mEndEarfcn;
}
@@ -121,4 +124,17 @@ public final class EarfcnRange implements Parcelable {
public @IntRange(from = 0, to = 65535) int getEndEarfcn() {
return mEndEarfcn;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof EarfcnRange that)) return false;
+
+ return (that.mStartEarfcn == mStartEarfcn) && (that.mEndEarfcn == mEndEarfcn);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mStartEarfcn, mEndEarfcn);
+ }
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java b/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java
index c3ae70b48854..c1a6ae850985 100644
--- a/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java
+++ b/telephony/java/android/telephony/satellite/SatelliteAccessConfiguration.java
@@ -24,7 +24,9 @@ import androidx.annotation.NonNull;
import com.android.internal.telephony.flags.Flags;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* SatelliteAccessConfiguration is used to store satellite access configuration
@@ -44,25 +46,25 @@ public final class SatelliteAccessConfiguration implements Parcelable {
* The list of tag IDs associated with the current location
*/
@NonNull
- private int[] mTagIds;
+ private List<Integer> mTagIdList;
/**
* Constructor for {@link SatelliteAccessConfiguration}.
*
* @param satelliteInfos The list of {@link SatelliteInfo} objects representing the satellites
* accessible with this configuration.
- * @param tagIds The list of tag IDs associated with this configuration.
+ * @param tagIdList The list of tag IDs associated with this configuration.
*/
public SatelliteAccessConfiguration(@NonNull List<SatelliteInfo> satelliteInfos,
- @NonNull int[] tagIds) {
+ @NonNull List<Integer> tagIdList) {
mSatelliteInfoList = satelliteInfos;
- mTagIds = tagIds;
+ mTagIdList = tagIdList;
}
public SatelliteAccessConfiguration(Parcel in) {
mSatelliteInfoList = in.createTypedArrayList(SatelliteInfo.CREATOR);
- mTagIds = new int[in.readInt()];
- in.readIntArray(mTagIds);
+ mTagIdList = new ArrayList<>();
+ in.readList(mTagIdList, Integer.class.getClassLoader(), Integer.class);
}
public static final Creator<SatelliteAccessConfiguration> CREATOR =
@@ -91,12 +93,7 @@ public final class SatelliteAccessConfiguration implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeTypedList(mSatelliteInfoList);
- if (mTagIds != null && mTagIds.length > 0) {
- dest.writeInt(mTagIds.length);
- dest.writeIntArray(mTagIds);
- } else {
- dest.writeInt(0);
- }
+ dest.writeList(mTagIdList);
}
/**
@@ -116,7 +113,34 @@ public final class SatelliteAccessConfiguration implements Parcelable {
* @return The list of tag IDs.
*/
@NonNull
- public int[] getTagIds() {
- return mTagIds;
+ public List<Integer> getTagIds() {
+ return mTagIdList;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SatelliteAccessConfiguration that)) return false;
+
+ return mSatelliteInfoList.equals(that.mSatelliteInfoList)
+ && Objects.equals(mTagIdList, that.mTagIdList);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(mSatelliteInfoList);
+ result = 31 * result + Objects.hashCode(mTagIdList);
+ return result;
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("SatelliteAccessConfiguration{");
+ sb.append("mSatelliteInfoList=").append(mSatelliteInfoList);
+ sb.append(", mTagIds=").append(mTagIdList);
+ sb.append('}');
+ return sb.toString();
}
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteInfo.java b/telephony/java/android/telephony/satellite/SatelliteInfo.java
index bca907e49993..7ff231812c8a 100644
--- a/telephony/java/android/telephony/satellite/SatelliteInfo.java
+++ b/telephony/java/android/telephony/satellite/SatelliteInfo.java
@@ -17,6 +17,7 @@
package android.telephony.satellite;
import android.annotation.FlaggedApi;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
@@ -25,7 +26,9 @@ import androidx.annotation.NonNull;
import com.android.internal.telephony.flags.Flags;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.UUID;
/**
@@ -47,17 +50,18 @@ public class SatelliteInfo implements Parcelable {
* Position information of a satellite.
* This includes the longitude and altitude of the satellite.
*/
+ @Nullable
private SatellitePosition mPosition;
/**
- * The frequency bands to scan. Bands and earfcns won't overlap.
+ * The frequency band list to scan. Bands and earfcns won't overlap.
* Bands will be filled only if the whole band is needed.
* Maximum length of the vector is 8.
*/
- private int[] mBands;
+ private List<Integer> mBandList;
/**
- * EARFCN (E-UTRA Absolute Radio Frequency Channel Number) Ranges
+ * EARFCN (E-UTRA Absolute Radio Frequency Channel Number) range list
* The supported frequency range list.
* Maximum length of the vector is 8.
*/
@@ -71,13 +75,8 @@ public class SatelliteInfo implements Parcelable {
}
mPosition = in.readParcelable(SatellitePosition.class.getClassLoader(),
SatellitePosition.class);
- int numBands = in.readInt();
- mBands = new int[numBands];
- if (numBands > 0) {
- for (int i = 0; i < numBands; i++) {
- mBands[i] = in.readInt();
- }
- }
+ mBandList = new ArrayList<>();
+ in.readList(mBandList, Integer.class.getClassLoader(), Integer.class);
mEarfcnRangeList = in.createTypedArrayList(EarfcnRange.CREATOR);
}
@@ -86,15 +85,15 @@ public class SatelliteInfo implements Parcelable {
*
* @param satelliteId The ID of the satellite.
* @param satellitePosition The {@link SatellitePosition} of the satellite.
- * @param bands The list of frequency bands supported by the satellite.
+ * @param bandList The list of frequency bandList supported by the satellite.
* @param earfcnRanges The list of {@link EarfcnRange} objects representing the EARFCN
* ranges supported by the satellite.
*/
- public SatelliteInfo(@NonNull UUID satelliteId, @NonNull SatellitePosition satellitePosition,
- @NonNull int[] bands, @NonNull List<EarfcnRange> earfcnRanges) {
+ public SatelliteInfo(@NonNull UUID satelliteId, @Nullable SatellitePosition satellitePosition,
+ @NonNull List<Integer> bandList, @NonNull List<EarfcnRange> earfcnRanges) {
mId = satelliteId;
mPosition = satellitePosition;
- mBands = bands;
+ mBandList = bandList;
mEarfcnRangeList = earfcnRanges;
}
@@ -119,12 +118,7 @@ public class SatelliteInfo implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeParcelable(new ParcelUuid(mId), flags);
dest.writeParcelable(mPosition, flags);
- if (mBands != null && mBands.length > 0) {
- dest.writeInt(mBands.length);
- dest.writeIntArray(mBands);
- } else {
- dest.writeInt(0);
- }
+ dest.writeList(mBandList);
dest.writeTypedList(mEarfcnRangeList);
}
@@ -141,8 +135,10 @@ public class SatelliteInfo implements Parcelable {
/**
* Returns the position of the satellite.
*
- * @return The {@link SatellitePosition} of the satellite.
+ * @return The {@link SatellitePosition} of the satellite, or {@code null} if the position is
+ * not available.
*/
+ @Nullable
public SatellitePosition getSatellitePosition() {
return mPosition;
}
@@ -153,8 +149,8 @@ public class SatelliteInfo implements Parcelable {
* @return The list of frequency bands.
*/
@NonNull
- public int[] getBands() {
- return mBands;
+ public List<Integer> getBands() {
+ return mBandList;
}
/**
@@ -166,4 +162,35 @@ public class SatelliteInfo implements Parcelable {
public List<EarfcnRange> getEarfcnRanges() {
return mEarfcnRangeList;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SatelliteInfo that)) return false;
+
+ return mId.equals(that.mId)
+ && Objects.equals(mPosition, that.mPosition)
+ && Objects.equals(mBandList, that.mBandList)
+ && mEarfcnRangeList.equals(that.mEarfcnRangeList);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(mId, mPosition, mEarfcnRangeList);
+ result = 31 * result + Objects.hashCode(mBandList);
+ return result;
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("SatelliteInfo{");
+ sb.append("mId=").append(mId);
+ sb.append(", mPosition=").append(mPosition);
+ sb.append(", mBandList=").append(mBandList);
+ sb.append(", mEarfcnRangeList=").append(mEarfcnRangeList);
+ sb.append('}');
+ return sb.toString();
+ }
}
diff --git a/telephony/java/android/telephony/satellite/SatellitePosition.java b/telephony/java/android/telephony/satellite/SatellitePosition.java
index 1e8c0180f456..dd463e00ebb5 100644
--- a/telephony/java/android/telephony/satellite/SatellitePosition.java
+++ b/telephony/java/android/telephony/satellite/SatellitePosition.java
@@ -23,6 +23,8 @@ import androidx.annotation.NonNull;
import com.android.internal.telephony.flags.Flags;
+import java.util.Objects;
+
/**
* The position of a satellite in Earth orbit.
*
@@ -111,4 +113,24 @@ public class SatellitePosition implements Parcelable {
public double getAltitudeKm() {
return mAltitudeKm;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SatellitePosition that)) return false;
+
+ return Double.compare(that.mLongitudeDegree, mLongitudeDegree) == 0
+ && Double.compare(that.mAltitudeKm, mAltitudeKm) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mLongitudeDegree, mAltitudeKm);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ return "mLongitudeDegree: " + mLongitudeDegree + ", " + "mAltitudeKm: " + mAltitudeKm;
+ }
}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java b/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
index 2cd625eec032..4d495adf727b 100644
--- a/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
@@ -18,7 +18,9 @@ package android.app.jank.tests;
import static org.junit.Assert.assertEquals;
+import android.app.jank.AppJankStats;
import android.app.jank.Flags;
+import android.app.jank.FrameOverrunHistogram;
import android.app.jank.JankDataProcessor;
import android.app.jank.StateTracker;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -39,6 +41,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
@RunWith(AndroidJUnit4.class)
@@ -154,6 +157,73 @@ public class JankDataProcessorTest {
assertEquals(totalFrames, histogramFrames);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void mergeAppJankStats_confirmStatAddedToPendingStats() {
+ HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
+ mJankDataProcessor.getPendingJankStats();
+
+ assertEquals(pendingStats.size(), 0);
+
+ AppJankStats jankStats = getAppJankStats();
+ mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
+
+ pendingStats = mJankDataProcessor.getPendingJankStats();
+
+ assertEquals(pendingStats.size(), 1);
+ }
+
+ /**
+ * This test confirms matching states are combined into one pending stat. When JankStats are
+ * merged from outside the platform they will contain widget category, widget id and widget
+ * state. If an incoming JankStats matches a pending stat on all those fields the incoming
+ * JankStat will be merged into the existing stat.
+ */
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void mergeAppJankStats_confirmStatsWithMatchingStatesAreCombinedIntoOnePendingStat() {
+ AppJankStats jankStats = getAppJankStats();
+ mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
+
+ HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
+ mJankDataProcessor.getPendingJankStats();
+ assertEquals(pendingStats.size(), 1);
+
+ AppJankStats secondJankStat = getAppJankStats();
+ mJankDataProcessor.mergeJankStats(secondJankStat, sActivityName);
+
+ pendingStats = mJankDataProcessor.getPendingJankStats();
+
+ assertEquals(pendingStats.size(), 1);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void mergeAppJankStats_whenStatsWithMatchingStatesMerge_confirmFrameCountsAdded() {
+ AppJankStats jankStats = getAppJankStats();
+ mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
+ mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
+
+ HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
+ mJankDataProcessor.getPendingJankStats();
+
+ String statKey = pendingStats.keySet().iterator().next();
+ JankDataProcessor.PendingJankStat pendingStat = pendingStats.get(statKey);
+
+ assertEquals(pendingStats.size(), 1);
+ // The same jankStats objects are merged twice, this should result in the frame counts being
+ // doubled.
+ assertEquals(jankStats.getJankyFrameCount() * 2, pendingStat.getJankyFrames());
+ assertEquals(jankStats.getTotalFrameCount() * 2, pendingStat.getTotalFrames());
+
+ int[] originalHistogramBuckets = jankStats.getFrameOverrunHistogram().getBucketCounters();
+ int[] frameOverrunBuckets = pendingStat.getFrameOverrunBuckets();
+
+ for (int i = 0; i < frameOverrunBuckets.length; i++) {
+ assertEquals(originalHistogramBuckets[i] * 2, frameOverrunBuckets[i]);
+ }
+ }
+
// TODO b/375005277 add tests that cover logging and releasing resources back to pool.
private long getTotalFramesCounted() {
@@ -276,4 +346,26 @@ public class JankDataProcessorTest {
return mockData;
}
+ private AppJankStats getAppJankStats() {
+ AppJankStats jankStats = new AppJankStats(
+ /*App Uid*/APP_ID,
+ /*Widget Id*/"test widget id",
+ /*Widget Category*/AppJankStats.SCROLL,
+ /*Widget State*/AppJankStats.SCROLLING,
+ /*Total Frames*/100,
+ /*Janky Frames*/25,
+ getOverrunHistogram()
+ );
+ return jankStats;
+ }
+
+ private FrameOverrunHistogram getOverrunHistogram() {
+ FrameOverrunHistogram overrunHistogram = new FrameOverrunHistogram();
+ overrunHistogram.addFrameOverrunMillis(-2);
+ overrunHistogram.addFrameOverrunMillis(1);
+ overrunHistogram.addFrameOverrunMillis(5);
+ overrunHistogram.addFrameOverrunMillis(25);
+ return overrunHistogram;
+ }
+
}
diff --git a/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml b/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml
index d8eb9ff37e78..da510fcd4d63 100644
--- a/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml
+++ b/tests/CtsSurfaceControlTestsStaging/AndroidManifest.xml
@@ -18,12 +18,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.view.surfacecontroltests">
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"/>
+ <uses-permission android:name="android.permission.OBSERVE_PICTURE_PROFILES"/>
+
<application android:debuggable="true" android:testOnly="true">
<uses-library android:name="android.test.runner"/>
<activity
android:name=".GraphicsActivity"
android:exported="false">
</activity>
+ <activity android:name=".SurfaceControlPictureProfileTestActivity"
+ android:exported="true"
+ android:turnScreenOn="true"
+ android:showWhenLocked="true"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml b/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml
index 5c0163fcfa7e..025bf378d82f 100644
--- a/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml
+++ b/tests/CtsSurfaceControlTestsStaging/AndroidTest.xml
@@ -21,6 +21,9 @@
<option name="install-arg" value="-t" />
<option name="test-file-name" value="CtsSurfaceControlTestsStaging.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer" >
+ <option name="flag-value" value="media_tv/android.media.tv.flags.apply_picture_profiles=true" />
+ </target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.view.surfacecontroltests" />
<option name="hidden-api-checks" value="false" />
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java
new file mode 100644
index 000000000000..135f7102b8a9
--- /dev/null
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.surfacecontroltests;
+
+import static android.Manifest.permission.OBSERVE_PICTURE_PROFILES;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import static java.util.Arrays.stream;
+
+import android.hardware.HardwareBuffer;
+import android.media.quality.PictureProfileHandle;
+import android.os.Process;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlActivePicture;
+import android.view.SurfaceControlActivePictureListener;
+import android.view.SurfaceView;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.LongStream;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SurfaceControlPictureProfileTest {
+ private static final String TAG = SurfaceControlPictureProfileTest.class.getSimpleName();
+
+ private SurfaceControl[] mSurfaceControls;
+ private SurfaceControl mSurfaceControl;
+
+ @Rule
+ public ActivityTestRule<SurfaceControlPictureProfileTestActivity> mActivityRule =
+ new ActivityTestRule<>(SurfaceControlPictureProfileTestActivity.class);
+
+ @Before
+ public void setup() {
+ SurfaceView[] surfaceViews = mActivityRule.getActivity().getSurfaceViews();
+ mSurfaceControls = new SurfaceControl[surfaceViews.length];
+ // Create a child surface control so we can set a buffer, priority and profile handle all
+ // on one single surface control
+ for (int i = 0; i < mSurfaceControls.length; ++i) {
+ mSurfaceControls[i] = new SurfaceControl.Builder().setName("test").setHidden(false)
+ .setParent(surfaceViews[i].getSurfaceControl()).build();
+ }
+ mSurfaceControl = mSurfaceControls[0];
+ }
+
+ @Test
+ public void whenPictureProfileApplied_noExecptionsThrown() {
+ assumeTrue("Skipping test because feature flag is disabled",
+ com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+ // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+ assumeTrue("Skipping test because no picture profile support",
+ SurfaceControl.getMaxPictureProfiles() > 0);
+
+ // TODO(b/337330263): Load the handle from MediaQualityManager instead
+ PictureProfileHandle handle = new PictureProfileHandle(1);
+ HardwareBuffer buffer = getSolidBuffer(100, 100);
+ new SurfaceControl.Transaction()
+ .setBuffer(mSurfaceControl, buffer)
+ .setPictureProfileHandle(mSurfaceControl, handle)
+ .apply();
+ }
+
+ @Test
+ public void whenStartsListening_callsListener() {
+ assumeTrue("Skipping test because feature flag is disabled",
+ com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+ // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+ assumeTrue("Skipping test because no picture profile support",
+ SurfaceControl.getMaxPictureProfiles() > 0);
+
+ BlockingQueue<SurfaceControlActivePicture[]> picturesQueue = new LinkedBlockingQueue<>();
+ SurfaceControlActivePicture[] pictures;
+ SurfaceControlActivePictureListener listener = new SurfaceControlActivePictureListener() {
+ @Override
+ public void onActivePicturesChanged(SurfaceControlActivePicture[] pictures) {
+ picturesQueue.add(pictures);
+ }
+ };
+ // TODO(b/337330263): Call MediaQualityManager.addActivePictureListener instead
+ adoptShellPermissionIdentity(OBSERVE_PICTURE_PROFILES);
+ listener.startListening();
+ {
+ HardwareBuffer buffer = getSolidBuffer(100, 100);
+ new SurfaceControl.Transaction().setBuffer(mSurfaceControl, buffer).apply();
+ }
+
+ pictures = pollMs(picturesQueue, 200);
+ assertThat(pictures).isNotNull();
+ assertThat(pictures).isEmpty();
+ }
+
+ @Test
+ public void whenPictureProfileApplied_callsListenerWithUidAndProfileId() {
+ assumeTrue("Skipping test because feature flag is disabled",
+ com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+ // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+ assumeTrue("Skipping test because no picture profile support",
+ SurfaceControl.getMaxPictureProfiles() > 0);
+
+ BlockingQueue<SurfaceControlActivePicture[]> picturesQueue = new LinkedBlockingQueue<>();
+ SurfaceControlActivePicture[] pictures;
+ SurfaceControlActivePictureListener listener = new SurfaceControlActivePictureListener() {
+ @Override
+ public void onActivePicturesChanged(SurfaceControlActivePicture[] pictures) {
+ picturesQueue.add(pictures);
+ }
+ };
+ // TODO(b/337330263): Call MediaQualityManager.addActivePictureListener instead
+ adoptShellPermissionIdentity(OBSERVE_PICTURE_PROFILES);
+ listener.startListening();
+ {
+ HardwareBuffer buffer = getSolidBuffer(100, 100);
+ new SurfaceControl.Transaction().setBuffer(mSurfaceControl, buffer).apply();
+ }
+
+ pictures = pollMs(picturesQueue, 200);
+ assertThat(pictures).isNotNull();
+ assertThat(pictures).isEmpty();
+
+ // TODO(b/337330263): Load the handle from MediaQualityManager instead
+ PictureProfileHandle handle = new PictureProfileHandle(1);
+ HardwareBuffer buffer = getSolidBuffer(100, 100);
+ new SurfaceControl.Transaction()
+ .setBuffer(mSurfaceControl, buffer)
+ .setPictureProfileHandle(mSurfaceControl, handle)
+ .apply();
+
+ pictures = pollMs(picturesQueue, 200);
+ assertThat(pictures).isNotNull();
+ assertThat(stream(pictures).map(picture -> picture.getPictureProfileHandle().getId()))
+ .containsExactly(handle.getId());
+ assertThat(stream(pictures).map(picture -> picture.getOwnerUid()))
+ .containsExactly(Process.myUid());
+ }
+
+ @Test
+ public void whenPriorityChanges_callsListenerOnlyForLowerPriorityLayers() {
+ assumeTrue("Skipping test because feature flag is disabled",
+ com.android.graphics.libgui.flags.Flags.applyPictureProfiles());
+ // TODO(b/337330263): Call MediaQualityManager.getMaxPictureProfiles instead
+ int maxPictureProfiles = SurfaceControl.getMaxPictureProfiles();
+ assumeTrue("Skipping test because no picture profile support", maxPictureProfiles > 0);
+
+ BlockingQueue<SurfaceControlActivePicture[]> picturesQueue = new LinkedBlockingQueue<>();
+ SurfaceControlActivePicture[] pictures;
+ SurfaceControlActivePictureListener listener = new SurfaceControlActivePictureListener() {
+ @Override
+ public void onActivePicturesChanged(SurfaceControlActivePicture[] pictures) {
+ picturesQueue.add(pictures);
+ }
+ };
+ // TODO(b/337330263): Call MediaQualityManager.addActivePictureListener instead
+ adoptShellPermissionIdentity(OBSERVE_PICTURE_PROFILES);
+ listener.startListening();
+ {
+ HardwareBuffer buffer = getSolidBuffer(100, 100);
+ new SurfaceControl.Transaction().setBuffer(mSurfaceControl, buffer).apply();
+ }
+
+ pictures = pollMs(picturesQueue, 200);
+ assertThat(pictures).isNotNull();
+ assertThat(pictures).isEmpty();
+
+ SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+ // Use one more picture profile than allowed
+ for (int i = 0; i <= maxPictureProfiles; ++i) {
+ // Increase the number of surface views as necessary to support device configuration.
+ assertThat(i).isLessThan(mSurfaceControls.length);
+
+ // TODO(b/337330263): Load the handle from MediaQualityManager instead
+ PictureProfileHandle handle = new PictureProfileHandle(i + 1);
+ HardwareBuffer buffer = getSolidBuffer(100, 100);
+ transaction
+ .setBuffer(mSurfaceControls[i], buffer)
+ .setPictureProfileHandle(mSurfaceControls[i], handle)
+ .setContentPriority(mSurfaceControls[i], 0);
+ }
+ // Make the first layer low priority (high value)
+ transaction.setContentPriority(mSurfaceControls[0], 2);
+ // Make the last layer higher priority (lower value)
+ transaction.setContentPriority(mSurfaceControls[maxPictureProfiles], 1);
+ transaction.apply();
+
+ pictures = pollMs(picturesQueue, 200);
+ assertThat(pictures).isNotNull();
+ assertThat(stream(pictures).map(picture -> picture.getLayerId()))
+ .containsNoDuplicates();
+ // Expect all but the first layer to be listed as an active picture
+ assertThat(stream(pictures).map(picture -> picture.getPictureProfileHandle().getId()))
+ .containsExactlyElementsIn(toIterableRange(2, maxPictureProfiles + 1));
+
+ // Change priority and ensure that the first layer gets access
+ new SurfaceControl.Transaction().setContentPriority(mSurfaceControls[0], 0).apply();
+ pictures = pollMs(picturesQueue, 200);
+ assertThat(pictures).isNotNull();
+ // Expect all but the last layer to be listed as an active picture
+ assertThat(stream(pictures).map(picture -> picture.getPictureProfileHandle().getId()))
+ .containsExactlyElementsIn(toIterableRange(1, maxPictureProfiles));
+ }
+
+ private static SurfaceControlActivePicture[] pollMs(
+ BlockingQueue<SurfaceControlActivePicture[]> picturesQueue, int waitMs) {
+ SurfaceControlActivePicture[] pictures = null;
+ long nowMs = System.currentTimeMillis();
+ long endTimeMs = nowMs + waitMs;
+ while (nowMs < endTimeMs && pictures == null) {
+ try {
+ pictures = picturesQueue.poll(endTimeMs - nowMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ // continue polling until timeout when interrupted
+ }
+ nowMs = System.currentTimeMillis();
+ }
+ return pictures;
+ }
+
+ Iterable<Long> toIterableRange(int start, int stop) {
+ return () -> LongStream.rangeClosed(start, stop).iterator();
+ }
+
+ private void adoptShellPermissionIdentity(String permission) {
+ getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(permission);
+ }
+
+ private HardwareBuffer getSolidBuffer(int width, int height) {
+ // We can assume that RGBA_8888 format is supported for every platform.
+ return HardwareBuffer.create(
+ width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_CPU_WRITE_OFTEN);
+ }
+}
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java
new file mode 100644
index 000000000000..42fcb261fa9d
--- /dev/null
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlPictureProfileTestActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.surfacecontroltests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.SurfaceView;
+
+public class SurfaceControlPictureProfileTestActivity extends Activity {
+ private SurfaceView[] mSurfaceViews;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.picture_profile_test_layout);
+ mSurfaceViews = new SurfaceView[3];
+ mSurfaceViews[0] = (SurfaceView) findViewById(R.id.surfaceview1);
+ mSurfaceViews[1] = (SurfaceView) findViewById(R.id.surfaceview2);
+ mSurfaceViews[2] = (SurfaceView) findViewById(R.id.surfaceview3);
+ }
+
+ public SurfaceView getSurfaceView() {
+ return mSurfaceViews[0];
+ }
+
+ public SurfaceView[] getSurfaceViews() {
+ return mSurfaceViews;
+ }
+}
diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml b/tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml
new file mode 100644
index 000000000000..9aa25785d9f2
--- /dev/null
+++ b/tests/CtsSurfaceControlTestsStaging/src/main/res/layout/picture_profile_test_layout.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <SurfaceView android:id="@+id/surfaceview1"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <SurfaceView android:id="@+id/surfaceview2"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+ <SurfaceView android:id="@+id/surfaceview3"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+</LinearLayout>
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
index 01cdbb810379..e59b6bd0617c 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
@@ -35,7 +35,7 @@ import org.junit.runners.Parameterized
/**
* Test the back and forward transition between 2 activities.
*
- * To run this test: `atest FlickerTestsAppLaunch:ActivitiesTransitionTest`
+ * To run this test: `atest FlickerTestsAppLaunch:ActivityTransitionTest`
*
* Actions:
* ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
index 3d9321c0b830..2bf8cc40d0a0 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
@@ -30,7 +30,7 @@ import org.junit.runners.Parameterized
/**
* Test cold launching an app from launcher
*
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppColdFromIcon`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIconColdTest`
*
* Actions:
* ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
index 92075303028c..9c6bf9de37ce 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
@@ -30,7 +30,7 @@ import org.junit.runners.Parameterized
/**
* Test launching an app after cold opening camera
*
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppAfterCameraTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIntentColdAfterCameraTest`
*
* Notes: Some default assertions are inherited [OpenAppTransition]
*/
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
index cbe7c3241df3..1a53a611c8d7 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
@@ -35,7 +35,7 @@ import org.junit.runners.Parameterized
/**
* Test cold launching an app from launcher
*
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppColdTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIntentColdTest`
*
* Actions:
* ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
index b2941e70a2ed..14b6a18bfe2e 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
@@ -34,7 +34,7 @@ import org.junit.runners.Parameterized
/**
* Test warm launching an app from launcher
*
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppWarmTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromIntentWarmTest`
*
* Actions:
* ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
index 4048e0c89619..f30fe96b9d05 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
@@ -41,7 +41,7 @@ import org.junit.runners.Parameterized
*
* This test assumes the device doesn't have AOD enabled
*
- * To run this test: `atest FlickerTestsAppLaunch:OpenAppNonResizeableTest`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenAppFromLockscreenViaIntentTest`
*
* Actions:
* ```
diff --git a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
index 41423fd9eefe..9c552eb478d4 100644
--- a/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
+++ b/tests/FlickerTests/AppLaunch/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
@@ -41,7 +41,7 @@ import org.junit.runners.Parameterized
/**
* Test cold launching camera from launcher by double pressing power button
*
- * To run this test: `atest FlickerTestsAppLaunch:OpenCameraOnDoubleClickPowerButton`
+ * To run this test: `atest FlickerTestsAppLaunch:OpenCameraFromHomeOnDoubleClickPowerButtonTest`
*
* Actions:
* ```
@@ -140,14 +140,8 @@ class OpenCameraFromHomeOnDoubleClickPowerButtonTest(flicker: LegacyFlickerTest)
@Postsubmit
@Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- flicker.assertLayers {
- this.visibleLayersShownMoreThanOneConsecutiveEntry(
- LayersTraceSubject.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS +
- listOf(CAMERA_BACKGROUND)
- )
- }
- }
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
@Postsubmit
@Test
@@ -170,12 +164,5 @@ class OpenCameraFromHomeOnDoubleClickPowerButtonTest(flicker: LegacyFlickerTest)
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
-
- private val CAMERA_BACKGROUND =
- ComponentNameMatcher(
- "Background for SurfaceView" +
- "[com.google.android.GoogleCamera/" +
- "com.google.android.apps.camera.legacy.app.activity.main.CameraActivity]"
- )
}
}
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index d2c9eb30e2fc..64328275085d 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -92,7 +92,7 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) :
}
/** Move an app to Desktop by dragging the app handle at the top. */
- fun enterDesktopModeWithDrag(
+ private fun enterDesktopModeWithDrag(
wmHelper: WindowManagerStateHelper,
device: UiDevice,
motionEventHelper: MotionEventHelper = MotionEventHelper(getInstrumentation(), TOUCH)
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/StartMediaProjectionAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/StartMediaProjectionAppHelper.kt
index 69fde0168b14..9e488486e16a 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/StartMediaProjectionAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/StartMediaProjectionAppHelper.kt
@@ -65,10 +65,45 @@ constructor(
.waitForAndVerify()
}
+ fun startSingleAppMediaProjectionWithExtraIntent(
+ wmHelper: WindowManagerStateHelper,
+ targetApp: StandardAppHelper
+ ) {
+ clickStartMediaProjectionWithExtraIntentButton()
+ chooseSingleAppOption()
+ startScreenSharing()
+ selectTargetApp(targetApp.appName)
+ wmHelper
+ .StateSyncBuilder()
+ .withAppTransitionIdle()
+ .withHomeActivityVisible()
+ .waitForAndVerify()
+ }
+
+ fun startSingleAppMediaProjectionFromRecents(
+ wmHelper: WindowManagerStateHelper,
+ targetApp: StandardAppHelper,
+ recentTasksIndex: Int = 0,
+ ) {
+ clickStartMediaProjectionButton()
+ chooseSingleAppOption()
+ startScreenSharing()
+ selectTargetAppRecent(recentTasksIndex)
+ wmHelper
+ .StateSyncBuilder()
+ .withAppTransitionIdle()
+ .withWindowSurfaceAppeared(targetApp)
+ .waitForAndVerify()
+ }
+
private fun clickStartMediaProjectionButton() {
findObject(By.res(packageName, START_MEDIA_PROJECTION_BUTTON_ID)).also { it.click() }
}
+ private fun clickStartMediaProjectionWithExtraIntentButton() {
+ findObject(By.res(packageName, START_MEDIA_PROJECTION_NEW_INTENT_BUTTON_ID)).also { it.click() }
+ }
+
private fun chooseEntireScreenOption() {
findObject(By.res(SCREEN_SHARE_OPTIONS_PATTERN)).also { it.click() }
@@ -92,6 +127,13 @@ constructor(
findObject(By.text(targetAppName)).also { it.click() }
}
+ private fun selectTargetAppRecent(recentTasksIndex: Int) {
+ // Scroll to to find target app to launch then click app icon it to start capture
+ val recentsTasksRecycler =
+ findObject(By.res(SYSTEMUI_PACKAGE, MEDIA_PROJECTION_RECENT_TASKS))
+ recentsTasksRecycler.children[recentTasksIndex].also{ it.click() }
+ }
+
private fun chooseSingleAppOption() {
findObject(By.res(SCREEN_SHARE_OPTIONS_PATTERN)).also { it.click() }
@@ -116,8 +158,10 @@ constructor(
const val TIMEOUT: Long = 5000L
const val ACCEPT_RESOURCE_ID: String = "android:id/button1"
const val START_MEDIA_PROJECTION_BUTTON_ID: String = "button_start_mp"
+ const val START_MEDIA_PROJECTION_NEW_INTENT_BUTTON_ID: String = "button_start_mp_new_intent"
val SCREEN_SHARE_OPTIONS_PATTERN: Pattern =
Pattern.compile("$SYSTEMUI_PACKAGE:id/screen_share_mode_(options|spinner)")
+ const val MEDIA_PROJECTION_RECENT_TASKS: String = "media_projection_recent_tasks_recycler"
const val ENTIRE_SCREEN_STRING_RES_NAME: String =
"screen_share_permission_dialog_option_entire_screen"
const val SINGLE_APP_STRING_RES_NAME: String =
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml
index 46f01e6c9752..c34d2003ef42 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_start_media_projection.xml
@@ -16,17 +16,27 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
android:orientation="vertical"
android:background="@android:color/holo_orange_light">
<Button
android:id="@+id/button_start_mp"
- android:layout_width="500dp"
- android:layout_height="500dp"
+ android:layout_margin="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:text="Start Media Projection"
android:textAppearance="?android:attr/textAppearanceLarge"/>
+ <Button
+ android:id="@+id/button_start_mp_new_intent"
+ android:layout_margin="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical|center_horizontal"
+ android:text="Start Media Projection with extra intent"
+ android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout> \ No newline at end of file
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/StartMediaProjectionActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/StartMediaProjectionActivity.java
index a24a48269d7c..b29b87450197 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/StartMediaProjectionActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/StartMediaProjectionActivity.java
@@ -19,7 +19,8 @@ package com.android.server.wm.flicker.testapp;
import static com.android.wm.shell.flicker.utils.MediaProjectionUtils.EXTRA_MESSENGER;
import static com.android.wm.shell.flicker.utils.MediaProjectionUtils.MSG_SERVICE_DESTROYED;
import static com.android.wm.shell.flicker.utils.MediaProjectionUtils.MSG_START_FOREGROUND_DONE;
-import static com.android.wm.shell.flicker.utils.MediaProjectionUtils.REQUEST_CODE;
+import static com.android.wm.shell.flicker.utils.MediaProjectionUtils.REQUEST_CODE_NORMAL;
+import static com.android.wm.shell.flicker.utils.MediaProjectionUtils.REQUEST_CODE_EXTRA_INTENT;
import android.app.Activity;
import android.content.ComponentName;
@@ -71,13 +72,17 @@ public class StartMediaProjectionActivity extends Activity {
setContentView(R.layout.activity_start_media_projection);
Button startMediaProjectionButton = findViewById(R.id.button_start_mp);
+ Button startMediaProjectionButton2 = findViewById(R.id.button_start_mp_new_intent);
startMediaProjectionButton.setOnClickListener(v ->
- startActivityForResult(mService.createScreenCaptureIntent(), REQUEST_CODE));
+ startActivityForResult(mService.createScreenCaptureIntent(), REQUEST_CODE_NORMAL));
+ startMediaProjectionButton2.setOnClickListener(v ->
+ startActivityForResult(mService.createScreenCaptureIntent(),
+ REQUEST_CODE_EXTRA_INTENT));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode != REQUEST_CODE) {
+ if (requestCode != REQUEST_CODE_NORMAL && requestCode != REQUEST_CODE_EXTRA_INTENT) {
throw new IllegalStateException("Unknown request code: " + requestCode);
}
if (resultCode != RESULT_OK) {
@@ -85,6 +90,11 @@ public class StartMediaProjectionActivity extends Activity {
}
Log.d(TAG, "onActivityResult");
startMediaProjectionService(resultCode, data);
+ if (requestCode == REQUEST_CODE_EXTRA_INTENT) {
+ Intent startMain = new Intent(Intent.ACTION_MAIN);
+ startMain.addCategory(Intent.CATEGORY_HOME);
+ startActivity(startMain);
+ }
}
private void startMediaProjectionService(int resultCode, Intent resultData) {
@@ -122,7 +132,7 @@ public class StartMediaProjectionActivity extends Activity {
displayBounds.width(), displayBounds.height(), PixelFormat.RGBA_8888, 1);
mVirtualDisplay = mMediaProjection.createVirtualDisplay(
- "DanielDisplay",
+ "TestDisplay",
displayBounds.width(),
displayBounds.height(),
DisplayMetrics.DENSITY_HIGH,
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 34350ab98046..36a89f95aa6f 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -1361,7 +1361,7 @@ class KeyGestureControllerTests {
@Parameters(method = "systemGesturesTestArguments_forKeyCombinations")
@EnableFlags(
com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER,
- com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_PRESS_GESTURES
+ com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER_MULTI_KEY_GESTURES
)
fun testKeyCombinationGestures(test: TestData) {
setupKeyGestureController()
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 05a0f8f34337..fe974e3da3be 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -138,7 +138,8 @@ public class CrashRecoveryTest {
new File(InstrumentationRegistry.getContext().getFilesDir(),
"package-watchdog.xml").delete();
adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG,
- Manifest.permission.WRITE_DEVICE_CONFIG);
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
mTestLooper = new TestLooper();
mSpyContext = spy(InstrumentationRegistry.getContext());
when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index a540a8d567a1..c25bed21a602 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -152,7 +152,8 @@ public class PackageWatchdogTest {
new File(InstrumentationRegistry.getContext().getFilesDir(),
"package-watchdog.xml").delete();
adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG,
- Manifest.permission.WRITE_DEVICE_CONFIG);
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
mTestLooper = new TestLooper();
mSpyContext = spy(InstrumentationRegistry.getContext());
when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
index 314e95229d29..a6aa877c9097 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
@@ -82,7 +82,8 @@ public class NetworkStagedRollbackTest {
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
Manifest.permission.FORCE_STOP_PACKAGES,
- Manifest.permission.WRITE_DEVICE_CONFIG);
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
}
/**
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 4cddcfeb91dc..32deb2e8fdfc 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -70,7 +70,8 @@ public class StagedRollbackTest {
Manifest.permission.DELETE_PACKAGES,
Manifest.permission.TEST_MANAGE_ROLLBACKS,
Manifest.permission.FORCE_STOP_PACKAGES,
- Manifest.permission.WRITE_DEVICE_CONFIG);
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG);
}
/**
diff --git a/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index 8913e8c1996e..05308464cb9b 100644
--- a/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Tracing/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -89,7 +89,7 @@ public class LegacyProtoLogImplTest {
//noinspection ResultOfMethodCallIgnored
mFile.delete();
mProtoLog = new LegacyProtoLogImpl(mFile, mViewerConfigFilename,
- 1024 * 1024, mReader, 1024, () -> {});
+ 1024 * 1024, mReader, 1024, (instance) -> {});
}
@After
diff --git a/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java b/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java
index 44641f7a1e12..ed256e72b415 100644
--- a/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java
+++ b/tests/Tracing/src/com/android/internal/protolog/ProcessedPerfettoProtoLogImplTest.java
@@ -41,6 +41,7 @@ import android.tools.traces.io.ResultWriter;
import android.tools.traces.monitors.PerfettoTraceMonitor;
import android.tools.traces.protolog.ProtoLogTrace;
import android.tracing.perfetto.DataSource;
+import android.tracing.perfetto.DataSourceParams;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -95,14 +96,14 @@ public class ProcessedPerfettoProtoLogImplTest {
);
private static ProtoLogConfigurationService sProtoLogConfigurationService;
+ private static ProtoLogDataSource sTestDataSource;
private static PerfettoProtoLogImpl sProtoLog;
private static Protolog.ProtoLogViewerConfig.Builder sViewerConfigBuilder;
- private static Runnable sCacheUpdater;
+ private static ProtoLogCacheUpdater sCacheUpdater;
private static ProtoLogViewerConfigReader sReader;
- public ProcessedPerfettoProtoLogImplTest() throws IOException {
- }
+ public ProcessedPerfettoProtoLogImplTest() throws IOException { }
@BeforeClass
public static void setUp() throws Exception {
@@ -155,12 +156,18 @@ public class ProcessedPerfettoProtoLogImplTest {
.thenAnswer(it -> new AutoClosableProtoInputStream(
sViewerConfigBuilder.build().toByteArray()));
- sCacheUpdater = () -> {};
+ sCacheUpdater = (instance) -> {};
sReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
+ sTestDataSource = new ProtoLogDataSource(TEST_PROTOLOG_DATASOURCE_NAME);
+ DataSourceParams params =
+ new DataSourceParams.Builder()
+ .setBufferExhaustedPolicy(
+ DataSourceParams
+ .PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP)
+ .build();
+ sTestDataSource.register(params);
+ busyWaitForDataSourceRegistration(TEST_PROTOLOG_DATASOURCE_NAME);
- final ProtoLogDataSourceBuilder dataSourceBuilder =
- (onStart, onFlush, onStop) -> new ProtoLogDataSource(
- onStart, onFlush, onStop, TEST_PROTOLOG_DATASOURCE_NAME);
final ViewerConfigFileTracer tracer = (dataSource, viewerConfigFilePath) -> {
Utils.dumpViewerConfig(dataSource, () -> {
if (!viewerConfigFilePath.equals(MOCK_VIEWER_CONFIG_FILE)) {
@@ -171,14 +178,13 @@ public class ProcessedPerfettoProtoLogImplTest {
});
};
sProtoLogConfigurationService =
- new ProtoLogConfigurationServiceImpl(dataSourceBuilder, tracer);
+ new ProtoLogConfigurationServiceImpl(sTestDataSource, tracer);
- sProtoLog = new ProcessedPerfettoProtoLogImpl(
+ sProtoLog = new ProcessedPerfettoProtoLogImpl(sTestDataSource,
MOCK_VIEWER_CONFIG_FILE, viewerConfigInputStreamProvider, sReader,
- () -> sCacheUpdater.run(), TestProtoLogGroup.values(), dataSourceBuilder,
+ (instance) -> sCacheUpdater.update(instance), TestProtoLogGroup.values(),
sProtoLogConfigurationService);
-
- busyWaitForDataSourceRegistration(TEST_PROTOLOG_DATASOURCE_NAME);
+ sProtoLog.enable();
}
@Before
@@ -606,7 +612,7 @@ public class ProcessedPerfettoProtoLogImplTest {
@Test
public void cacheIsUpdatedWhenTracesStartAndStop() {
final AtomicInteger cacheUpdateCallCount = new AtomicInteger(0);
- sCacheUpdater = cacheUpdateCallCount::incrementAndGet;
+ sCacheUpdater = (instance) -> cacheUpdateCallCount.incrementAndGet();
PerfettoTraceMonitor traceMonitor1 = PerfettoTraceMonitor.newBuilder()
.enableProtoLog(true,
diff --git a/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java b/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java
index ce519b7a1576..49249333b72b 100644
--- a/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java
+++ b/tests/Tracing/src/com/android/internal/protolog/ProtologDataSourceTest.java
@@ -67,9 +67,6 @@ public class ProtologDataSourceTest {
@Test
public void allEnabledTraceMode() {
- final ProtoLogDataSource ds =
- new ProtoLogDataSource((idx, c) -> {}, () -> {}, (idx, c) -> {});
-
final ProtoLogDataSource.TlsState tlsState = createTlsState(
DataSourceConfigOuterClass.DataSourceConfig.newBuilder().setProtologConfig(
ProtologConfig.ProtoLogConfig.newBuilder()
@@ -154,8 +151,7 @@ public class ProtologDataSourceTest {
private ProtoLogDataSource.TlsState createTlsState(
DataSourceConfigOuterClass.DataSourceConfig config) {
- final ProtoLogDataSource ds =
- Mockito.spy(new ProtoLogDataSource((idx, c) -> {}, () -> {}, (idx, c) -> {}));
+ final ProtoLogDataSource ds = Mockito.spy(new ProtoLogDataSource());
ProtoInputStream configStream = new ProtoInputStream(config.toByteArray());
final ProtoLogDataSource.Instance dsInstance = Mockito.spy(
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 3828a71d7b28..4ab8e6abbbef 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -70,7 +70,6 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.Uri;
-import android.net.vcn.Flags;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
@@ -293,8 +292,6 @@ public class VcnManagementServiceTest {
doReturn(Collections.singleton(TRANSPORT_WIFI))
.when(mMockDeps)
.getRestrictedTransports(any(), any(), any());
-
- mSetFlagsRule.enableFlags(Flags.FLAG_FIX_CONFIG_GARBAGE_COLLECTION);
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 108942ee754a..9222ff4bf52c 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -16,6 +16,7 @@
package com.android.protolog.tool
+import com.android.internal.protolog.common.IProtoLog
import com.android.internal.protolog.common.LogLevel
import com.android.internal.protolog.common.ProtoLogToolInjected
import com.android.protolog.tool.CommandOptions.Companion.USAGE
@@ -319,6 +320,7 @@ object ProtoLogTool {
MethodCallExpr()
.setName("isEnabled")
.setArguments(NodeList(
+ NameExpr("protoLogInstance"),
FieldAccessExpr()
.setScope(NameExpr(protoLogGroupsClassName))
.setName(group.value.name),
@@ -332,6 +334,7 @@ object ProtoLogTool {
}
cacheClass.addMethod("update").setPrivate(true).setStatic(true)
+ .addParameter(IProtoLog::class.java, "protoLogInstance")
.setBody(updateBlockStmt)
classDeclaration.addMember(cacheClass)