diff options
651 files changed, 9295 insertions, 3994 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index a80194cf53d2..48d6392f8b9b 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -346,6 +346,12 @@ cc_aconfig_library { mode: "test", } +cc_aconfig_library { + name: "android.os.flags-aconfig-cc-host", + aconfig_declarations: "android.os.flags-aconfig", + host_supported: true, +} + // VirtualDeviceManager cc_aconfig_library { name: "android.companion.virtualdevice.flags-aconfig-cc", diff --git a/core/api/current.txt b/core/api/current.txt index 2d10c05912aa..05b67eef0985 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -8084,7 +8084,7 @@ package android.app.admin { method public CharSequence getStartUserSessionMessage(@NonNull android.content.ComponentName); method @Deprecated public boolean getStorageEncryption(@Nullable android.content.ComponentName); method public int getStorageEncryptionStatus(); - method @FlaggedApi("android.app.admin.flags.esim_management_enabled") @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS) public java.util.Set<java.lang.Integer> getSubscriptionsIds(); + method @FlaggedApi("android.app.admin.flags.esim_management_enabled") @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS) public java.util.Set<java.lang.Integer> getSubscriptionIds(); method @Nullable public android.app.admin.SystemUpdatePolicy getSystemUpdatePolicy(); method @Nullable public android.os.PersistableBundle getTransferOwnershipBundle(); method @Nullable public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(@Nullable android.content.ComponentName, @NonNull android.content.ComponentName); @@ -15750,6 +15750,7 @@ package android.graphics { method public void drawRect(@NonNull android.graphics.RectF, @NonNull android.graphics.Paint); method public void drawRect(@NonNull android.graphics.Rect, @NonNull android.graphics.Paint); method public void drawRect(float, float, float, float, @NonNull android.graphics.Paint); + method @FlaggedApi("com.android.graphics.hwui.flags.draw_region") public void drawRegion(@NonNull android.graphics.Region, @NonNull android.graphics.Paint); method public void drawRenderNode(@NonNull android.graphics.RenderNode); method public void drawRoundRect(@NonNull android.graphics.RectF, float, float, @NonNull android.graphics.Paint); method public void drawRoundRect(float, float, float, float, float, float, @NonNull android.graphics.Paint); @@ -52446,8 +52447,8 @@ package android.view { method public final void cancelPendingInputEvents(); method public boolean checkInputConnectionProxy(android.view.View); method public void clearAnimation(); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void clearCredentialManagerRequest(); method public void clearFocus(); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void clearPendingCredentialRequest(); method public void clearViewTranslationCallback(); method public static int combineMeasuredStates(int, int); method protected int computeHorizontalScrollExtent(); @@ -52556,8 +52557,6 @@ package android.view { method @FlaggedApi("android.view.flags.sensitive_content_app_protection_api") public final int getContentSensitivity(); method @UiContext public final android.content.Context getContext(); method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo(); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public final android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException> getCredentialManagerCallback(); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public final android.credentials.GetCredentialRequest getCredentialManagerRequest(); method public final boolean getDefaultFocusHighlightEnabled(); method public static int getDefaultSize(int, int); method public android.view.Display getDisplay(); @@ -52642,6 +52641,8 @@ package android.view { method public int getPaddingTop(); method public final android.view.ViewParent getParent(); method public android.view.ViewParent getParentForAccessibility(); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public final android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException> getPendingCredentialCallback(); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public final android.credentials.GetCredentialRequest getPendingCredentialRequest(); method public float getPivotX(); method public float getPivotY(); method public android.view.PointerIcon getPointerIcon(); @@ -52942,7 +52943,6 @@ package android.view { method public void setContentDescription(CharSequence); method @FlaggedApi("android.view.flags.sensitive_content_app_protection_api") public final void setContentSensitivity(int); method public void setContextClickable(boolean); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void setCredentialManagerRequest(@NonNull android.credentials.GetCredentialRequest, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>); method public void setDefaultFocusHighlightEnabled(boolean); method @Deprecated public void setDrawingCacheBackgroundColor(@ColorInt int); method @Deprecated public void setDrawingCacheEnabled(boolean); @@ -53021,6 +53021,7 @@ package android.view { method public void setOverScrollMode(int); method public void setPadding(int, int, int, int); method public void setPaddingRelative(int, int, int, int); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void setPendingCredentialRequest(@NonNull android.credentials.GetCredentialRequest, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>); method public void setPivotX(float); method public void setPivotY(float); method public void setPointerIcon(android.view.PointerIcon); @@ -53824,10 +53825,10 @@ package android.view { method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void clearCredentialManagerRequest(); method @Nullable public abstract android.view.autofill.AutofillId getAutofillId(); method public abstract int getChildCount(); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException> getCredentialManagerCallback(); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public android.credentials.GetCredentialRequest getCredentialManagerRequest(); method public abstract android.os.Bundle getExtras(); method public abstract CharSequence getHint(); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException> getPendingCredentialCallback(); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") @Nullable public android.credentials.GetCredentialRequest getPendingCredentialRequest(); method public abstract CharSequence getText(); method public abstract int getTextSelectionEnd(); method public abstract int getTextSelectionStart(); @@ -53850,7 +53851,6 @@ package android.view { method public abstract void setClickable(boolean); method public abstract void setContentDescription(CharSequence); method public abstract void setContextClickable(boolean); - method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void setCredentialManagerRequest(@NonNull android.credentials.GetCredentialRequest, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>); method public abstract void setDataIsSensitive(boolean); method public abstract void setDimens(int, int, int, int, int, int); method public abstract void setElevation(float); @@ -53869,6 +53869,7 @@ package android.view { method public void setMaxTextLength(int); method public void setMinTextEms(int); method public abstract void setOpaque(boolean); + method @FlaggedApi("android.service.autofill.autofill_credman_dev_integration") public void setPendingCredentialRequest(@NonNull android.credentials.GetCredentialRequest, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>); method public void setReceiveContentMimeTypes(@Nullable String[]); method public abstract void setSelected(boolean); method public abstract void setText(CharSequence); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index b73f1993ee4c..fb2a4ac944a9 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1306,6 +1306,7 @@ package android.app.admin { public class DevicePolicyManager { method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public int checkProvisioningPrecondition(@NonNull String, @NonNull String); + method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void clearAuditLogEventCallback(); method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public android.os.UserHandle createAndProvisionManagedProfile(@NonNull android.app.admin.ManagedProfileProvisioningParams) throws android.app.admin.ProvisioningException; method @Nullable public android.content.Intent createProvisioningIntentFromNfcIntent(@NonNull android.content.Intent); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void finalizeWorkProfileProvisioning(@NonNull android.os.UserHandle, @Nullable android.accounts.Account); @@ -1342,7 +1343,7 @@ package android.app.admin { method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public boolean setActiveProfileOwner(@NonNull android.content.ComponentName, String) throws java.lang.IllegalArgumentException; method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_EXEMPTIONS) public void setApplicationExemptions(@NonNull String, @NonNull java.util.Set<java.lang.Integer>) throws android.content.pm.PackageManager.NameNotFoundException; method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void setAuditLogEnabled(boolean); - method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void setAuditLogEventCallback(@NonNull java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.util.List<android.app.admin.SecurityLog.SecurityEvent>>); + method @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void setAuditLogEventCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.admin.SecurityLog.SecurityEvent>>); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setDeviceProvisioningConfigApplied(); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setDpcDownloaded(boolean); method @FlaggedApi("android.app.admin.flags.device_policy_size_tracking_enabled") @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setMaxPolicyStorageLimit(int); @@ -14213,7 +14214,6 @@ package android.telecom { method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall(); method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @RequiresPermission(allOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isInSelfManagedCall(@NonNull String, @NonNull android.os.UserHandle); - method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @RequiresPermission(allOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean isInSelfManagedCall(@NonNull String, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle); field public static final String ACTION_CURRENT_TTY_MODE_CHANGED = "android.telecom.action.CURRENT_TTY_MODE_CHANGED"; @@ -15393,7 +15393,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String); method public boolean needsOtaServiceProvisioning(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled(); - method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @RequiresPermission(android.Manifest.permission.DUMP) public void persistEmergencyCallDiagnosticData(@NonNull String, @NonNull android.telephony.TelephonyManager.EmergencyCallDiagnosticData); + method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @RequiresPermission(android.Manifest.permission.READ_DROPBOX_DATA) public void persistEmergencyCallDiagnosticData(@NonNull String, @NonNull android.telephony.TelephonyManager.EmergencyCallDiagnosticData); method @RequiresPermission(android.Manifest.permission.REBOOT) public int prepareForUnattendedReboot(); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerCarrierPrivilegesCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesCallback); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 15f1eb4148cd..892567c6a587 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1624,8 +1624,6 @@ package android.hardware.camera2.params { package android.hardware.devicestate { @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_property_api") public final class DeviceState { - ctor @Deprecated public DeviceState(@IntRange(from=android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER, to=android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER) int, @NonNull String, int); - ctor public DeviceState(@IntRange(from=android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER, to=android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER) int, @NonNull String, @NonNull java.util.Set<java.lang.Integer>); field public static final int PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = 8; // 0x8 } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 39823a863b4a..fae434828222 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -6054,20 +6054,6 @@ public class ActivityManager { } /** - * Checks if the "modern" broadcast queue is enabled. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.DUMP) - public boolean isModernBroadcastQueueEnabled() { - try { - return getService().isModernBroadcastQueueEnabled(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Checks if the process represented by the given {@code pid} is frozen. * * @hide diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 062b89ed57ba..e28a6ce9b423 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -226,12 +226,6 @@ public abstract class ActivityManagerInternal { public abstract boolean isSystemReady(); /** - * @return {@code true} if system is using the "modern" broadcast queue, - * {@code false} otherwise. - */ - public abstract boolean isModernQueueEnabled(); - - /** * Enforce capability restrictions on use of the given BroadcastOptions */ public abstract void enforceBroadcastOptionsPermissions(@Nullable Bundle options, diff --git a/core/java/android/app/DreamManager.java b/core/java/android/app/DreamManager.java index 7c8b0fd499e3..ef6982e4a13c 100644 --- a/core/java/android/app/DreamManager.java +++ b/core/java/android/app/DreamManager.java @@ -185,6 +185,22 @@ public class DreamManager { } /** + * Whether dreaming can start given user settings and the current dock/charge state. + * + * @hide + */ + @UserHandleAware + @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) + public boolean canStartDreaming(boolean isScreenOn) { + try { + return mService.canStartDreaming(isScreenOn); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return false; + } + + /** * Returns whether the device is Dreaming. * * <p> This is only used for testing the dream service APIs. diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 7a95720c1cf4..5e6b54b1d0ea 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -898,10 +898,6 @@ interface IActivityManager { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") void forceDelayBroadcastDelivery(in String targetPackage, long delayedDurationMs); - /** Checks if the modern broadcast queue is enabled. */ - @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") - boolean isModernBroadcastQueueEnabled(); - /** Checks if the process represented by the given pid is frozen. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DUMP)") boolean isProcessFrozen(int pid); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index b25ebf69d14c..620bbaf4bbf5 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -14090,9 +14090,7 @@ public class DevicePolicyManager { try { return mService.isAuditLogEnabled(mContext.getPackageName()); } catch (RemoteException re) { - re.rethrowFromSystemServer(); - // unreachable - return false; + throw re.rethrowFromSystemServer(); } } @@ -14102,8 +14100,8 @@ public class DevicePolicyManager { * is enforced by the caller. Disabling the policy clears the callback. Each time a new callback * is set, it will first be invoked with all the audit log events available at the time. * - * @param callback callback to invoke when new audit log events become available or {@code null} - * to clear the callback. + * @param callback The callback to invoke when new audit log events become available. + * @param executor The executor through which the callback should be invoked. * @hide */ @SystemApi @@ -14111,11 +14109,10 @@ public class DevicePolicyManager { @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) public void setAuditLogEventCallback( @NonNull @CallbackExecutor Executor executor, - @Nullable Consumer<List<SecurityEvent>> callback) { + @NonNull Consumer<List<SecurityEvent>> callback) { throwIfParentInstance("setAuditLogEventCallback"); - final IAuditLogEventsCallback wrappedCallback = callback == null - ? null - : new IAuditLogEventsCallback.Stub() { + final IAuditLogEventsCallback wrappedCallback = + new IAuditLogEventsCallback.Stub() { @Override public void onNewAuditLogEvents(List<SecurityEvent> events) { executor.execute(() -> callback.accept(events)); @@ -14124,7 +14121,25 @@ public class DevicePolicyManager { try { mService.setAuditLogEventsCallback(mContext.getPackageName(), wrappedCallback); } catch (RemoteException re) { - re.rethrowFromSystemServer(); + throw re.rethrowFromSystemServer(); + } + } + + /** + * Clears audit log event callback. If a callback was set previously, it may still get invoked + * after this call returns if it was already scheduled. + * + * @hide + */ + @SystemApi + @FlaggedApi(FLAG_SECURITY_LOG_V2_ENABLED) + @RequiresPermission(permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING) + public void clearAuditLogEventCallback() { + throwIfParentInstance("clearAuditLogEventCallback"); + try { + mService.setAuditLogEventsCallback(mContext.getPackageName(), null); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); } } @@ -17442,24 +17457,24 @@ public class DevicePolicyManager { } /** - * Returns the subscription ids of all subscriptions which was downloaded by the calling + * Returns the subscription ids of all subscriptions which were downloaded by the calling * admin. * * <p> This returns only the subscriptions which were downloaded by the calling admin via * {@link android.telephony.euicc.EuiccManager#downloadSubscription}. - * If a susbcription is returned by this method then in it subject to management controls + * If a subscription is returned by this method then in it subject to management controls * and cannot be removed by users. * * <p> Callable by device owners and profile owners. * - * @throws SecurityException if the caller is not authorized to call this method - * @return ids of all managed subscriptions currently downloaded by an admin on the device + * @throws SecurityException if the caller is not authorized to call this method. + * @return ids of all managed subscriptions currently downloaded by an admin on the device. */ @FlaggedApi(FLAG_ESIM_MANAGEMENT_ENABLED) @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS) @NonNull - public Set<Integer> getSubscriptionsIds() { - throwIfParentInstance("getSubscriptionsIds"); + public Set<Integer> getSubscriptionIds() { + throwIfParentInstance("getSubscriptionIds"); if (mService != null) { try { return intArrayToSet(mService.getSubscriptionIds(mContext.getPackageName())); diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 89199ca0d493..75485626d2ef 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -1297,7 +1297,7 @@ public class AssistStructure implements Parcelable { */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) @Nullable - public GetCredentialRequest getCredentialManagerRequest() { + public GetCredentialRequest getPendingCredentialRequest() { return mGetCredentialRequest; } @@ -1306,7 +1306,7 @@ public class AssistStructure implements Parcelable { */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) @Nullable - public ResultReceiver getCredentialManagerCallback() { + public ResultReceiver getPendingCredentialCallback() { return mGetCredentialResultReceiver; } @@ -2191,14 +2191,14 @@ public class AssistStructure implements Parcelable { @Nullable @Override - public GetCredentialRequest getCredentialManagerRequest() { + public GetCredentialRequest getPendingCredentialRequest() { return mNode.mGetCredentialRequest; } @Nullable @Override public OutcomeReceiver< - GetCredentialResponse, GetCredentialException> getCredentialManagerCallback() { + GetCredentialResponse, GetCredentialException> getPendingCredentialCallback() { return mNode.mGetCredentialCallback; } @@ -2267,7 +2267,7 @@ public class AssistStructure implements Parcelable { } @Override - public void setCredentialManagerRequest(@NonNull GetCredentialRequest request, + public void setPendingCredentialRequest(@NonNull GetCredentialRequest request, @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) { mNode.mGetCredentialRequest = request; mNode.mGetCredentialCallback = callback; @@ -2654,7 +2654,7 @@ public class AssistStructure implements Parcelable { + ", isCredential=" + node.isCredential() ); } - GetCredentialRequest getCredentialRequest = node.getCredentialManagerRequest(); + GetCredentialRequest getCredentialRequest = node.getPendingCredentialRequest(); if (getCredentialRequest == null) { Log.i(TAG, prefix + " No Credential Manager Request"); } else { diff --git a/core/java/android/app/usage/OWNERS b/core/java/android/app/usage/OWNERS index a4bf98504591..57d958f2b1f5 100644 --- a/core/java/android/app/usage/OWNERS +++ b/core/java/android/app/usage/OWNERS @@ -3,6 +3,7 @@ yamasani@google.com mwachens@google.com varunshah@google.com +guanxin@google.com per-file *StorageStats* = file:/core/java/android/os/storage/OWNERS per-file *Broadcast* = sudheersai@google.com diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index a64ee5b38cc1..88527059b3f9 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1519,6 +1519,16 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { private static final long CHECK_MIN_WIDTH_HEIGHT_FOR_MULTI_WINDOW = 197654537L; /** + * The activity is targeting a SDK version that should receive the changed behavior of + * configuration insets decouple. + * + * @hide + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) + public static final long INSETS_DECOUPLED_CONFIGURATION_ENFORCED = 151861875L; + + /** * Optional set of a certificates identifying apps that are allowed to embed this activity. From * the "knownActivityEmbeddingCerts" attribute. */ diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig index 610057bffdbf..92cb9cc1d8dc 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -46,6 +46,7 @@ flag { flag { name: "use_art_service_v2" + is_exported: true namespace: "package_manager_service" description: "Feature flag to enable the features that rely on new ART Service APIs that are in the VIC version of the ART module." bug: "304741685" @@ -61,6 +62,7 @@ flag { flag { name: "rollback_lifetime" + is_exported: true namespace: "package_manager_service" description: "Feature flag to enable custom rollback lifetime during install." bug: "299670324" @@ -156,6 +158,7 @@ flag { flag { name: "recoverability_detection" + is_exported: true namespace: "package_manager_service" description: "Feature flag to enable recoverability detection feature. It includes GMS core rollback and improvements to rescue party." bug: "291135724" diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index faa2c7018d6f..dfb77c046c9a 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -34,17 +34,22 @@ import android.util.Log; import android.util.LruCache; import android.util.Pair; import android.util.Printer; +import com.android.internal.util.RingBuffer; import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; + import java.io.File; import java.io.IOException; import java.lang.ref.Reference; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; -import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; +import java.util.Locale; import java.util.Map; import java.util.function.BinaryOperator; import java.util.function.UnaryOperator; @@ -185,7 +190,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen SQLiteDatabaseConfiguration configuration, int connectionId, boolean primaryConnection) { mPool = pool; - mRecentOperations = new OperationLog(mPool); + mRecentOperations = new OperationLog(); mConfiguration = new SQLiteDatabaseConfiguration(configuration); mConnectionId = connectionId; mIsPrimaryConnection = primaryConnection; @@ -307,6 +312,16 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } + /** Record the start of a transaction for logging and debugging. */ + void recordBeginTransaction(String mode) { + mRecentOperations.beginTransaction(mode); + } + + /** Record the end of a transaction for logging and debugging. */ + void recordEndTransaction(boolean successful) { + mRecentOperations.endTransaction(successful); + } + private void setPageSize() { if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { final long newValue = SQLiteGlobal.getDefaultPageSize(); @@ -1337,6 +1352,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } printer.println(" isPrimaryConnection: " + mIsPrimaryConnection); printer.println(" onlyAllowReadOnlyOperations: " + mOnlyAllowReadOnlyOperations); + printer.println(" totalLongOperations: " + mRecentOperations.getTotalLongOperations()); mRecentOperations.dump(printer); @@ -1595,51 +1611,39 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } - private static final class OperationLog { + private final class OperationLog { private static final int MAX_RECENT_OPERATIONS = 20; private static final int COOKIE_GENERATION_SHIFT = 8; private static final int COOKIE_INDEX_MASK = 0xff; + // Operations over 2s are long. Save the last ten. + private static final long LONG_OPERATION_THRESHOLD_MS = 2_000; + private static final int MAX_LONG_OPERATIONS = 10; + private final Operation[] mOperations = new Operation[MAX_RECENT_OPERATIONS]; - private int mIndex; - private int mGeneration; - private final SQLiteConnectionPool mPool; + private int mIndex = -1; + private int mGeneration = 0; + private final Operation mTransaction = new Operation(); private long mResultLong = Long.MIN_VALUE; private String mResultString; - OperationLog(SQLiteConnectionPool pool) { - mPool = pool; - } + private final RingBuffer<Operation> mLongOperations = + new RingBuffer<>(()->{return new Operation();}, + (n) ->{return new Operation[n];}, + MAX_LONG_OPERATIONS); + private int mTotalLongOperations = 0; public int beginOperation(String kind, String sql, Object[] bindArgs) { mResultLong = Long.MIN_VALUE; mResultString = null; synchronized (mOperations) { - final int index = (mIndex + 1) % MAX_RECENT_OPERATIONS; - Operation operation = mOperations[index]; - if (operation == null) { - operation = new Operation(); - mOperations[index] = operation; - } else { - operation.mFinished = false; - operation.mException = null; - if (operation.mBindArgs != null) { - operation.mBindArgs.clear(); - } - } - operation.mStartWallTime = System.currentTimeMillis(); - operation.mStartTime = SystemClock.uptimeMillis(); + Operation operation = newOperationLocked(); operation.mKind = kind; operation.mSql = sql; - operation.mPath = mPool.getPath(); - operation.mResultLong = Long.MIN_VALUE; - operation.mResultString = null; if (bindArgs != null) { if (operation.mBindArgs == null) { operation.mBindArgs = new ArrayList<Object>(); - } else { - operation.mBindArgs.clear(); } for (int i = 0; i < bindArgs.length; i++) { final Object arg = bindArgs[i]; @@ -1651,16 +1655,44 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } } - operation.mCookie = newOperationCookieLocked(index); if (Trace.isTagEnabled(Trace.TRACE_TAG_DATABASE)) { Trace.asyncTraceBegin(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(), operation.mCookie); } - mIndex = index; return operation.mCookie; } } + public void beginTransaction(String kind) { + synchronized (mOperations) { + Operation operation = newOperationLocked(); + operation.mKind = kind; + mTransaction.copyFrom(operation); + + if (Trace.isTagEnabled(Trace.TRACE_TAG_DATABASE)) { + Trace.asyncTraceBegin(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(), + operation.mCookie); + } + } + } + + /** + * Fetch a new operation from the ring buffer. The operation is properly initialized. + * This advances mIndex to point to the next element. + */ + private Operation newOperationLocked() { + final int index = (mIndex + 1) % MAX_RECENT_OPERATIONS; + Operation operation = mOperations[index]; + if (operation == null) { + mOperations[index] = new Operation(); + operation = mOperations[index]; + } + operation.start(); + operation.mCookie = newOperationCookieLocked(index); + mIndex = index; + return operation; + } + public void failOperation(int cookie, Exception ex) { synchronized (mOperations) { final Operation operation = getOperationLocked(cookie); @@ -1684,6 +1716,20 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } + public boolean endTransaction(boolean success) { + synchronized (mOperations) { + mTransaction.mResultLong = success ? 1 : 0; + final long execTime = finishOperationLocked(mTransaction); + final Operation operation = getOperationLocked(mTransaction.mCookie); + if (operation != null) { + operation.copyFrom(mTransaction); + } + mTransaction.setEmpty(); + return NoPreloadHolder.DEBUG_LOG_SLOW_QUERIES + && SQLiteDebug.shouldLogSlowQuery(execTime); + } + } + public void logOperation(int cookie, String detail) { synchronized (mOperations) { logOperationLocked(cookie, detail); @@ -1705,9 +1751,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen Trace.asyncTraceEnd(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(), operation.mCookie); } - operation.mEndTime = SystemClock.uptimeMillis(); - operation.mFinished = true; - final long execTime = operation.mEndTime - operation.mStartTime; + final long execTime = finishOperationLocked(operation); mPool.onStatementExecuted(execTime); return NoPreloadHolder.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery( execTime); @@ -1732,10 +1776,22 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen return generation << COOKIE_GENERATION_SHIFT | index; } + /** Close out the operation and return the elapsed time. */ + private long finishOperationLocked(Operation operation) { + operation.mEndTime = SystemClock.uptimeMillis(); + operation.mFinished = true; + final long elapsed = operation.mEndTime - operation.mStartTime; + if (elapsed > LONG_OPERATION_THRESHOLD_MS) { + mLongOperations.getNextSlot().copyFrom(operation); + mTotalLongOperations++; + } + return elapsed; + } + private Operation getOperationLocked(int cookie) { final int index = cookie & COOKIE_INDEX_MASK; final Operation operation = mOperations[index]; - return operation.mCookie == cookie ? operation : null; + return (operation != null && operation.mCookie == cookie) ? operation : null; } public String describeCurrentOperation() { @@ -1750,48 +1806,87 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } - public void dump(Printer printer) { + /** + * Dump an Operation if it is not in the recent operations list. Return 1 if the + * operation was dumped and 0 if not. + */ + private int dumpIfNotRecentLocked(Printer pw, Operation op, int counter) { + if (op == null || op.isEmpty() || getOperationLocked(op.mCookie) != null) { + return 0; + } + pw.println(op.describe(counter)); + return 1; + } + + private void dumpRecentLocked(Printer printer) { synchronized (mOperations) { printer.println(" Most recently executed operations:"); int index = mIndex; - Operation operation = mOperations[index]; - if (operation != null) { - // Note: SimpleDateFormat is not thread-safe, cannot be compile-time created, - // and is relatively expensive to create during preloading. This method is only - // used when dumping a connection, which is a rare (mainly error) case. - SimpleDateFormat opDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - int n = 0; - do { - StringBuilder msg = new StringBuilder(); - msg.append(" ").append(n).append(": ["); - String formattedStartTime = opDF.format(new Date(operation.mStartWallTime)); - msg.append(formattedStartTime); - msg.append("] "); - operation.describe(msg, false); // Never dump bingargs in a bugreport - printer.println(msg.toString()); - - if (index > 0) { - index -= 1; - } else { - index = MAX_RECENT_OPERATIONS - 1; - } - n += 1; - operation = mOperations[index]; - } while (operation != null && n < MAX_RECENT_OPERATIONS); - } else { + if (index == 0) { printer.println(" <none>"); + return; + } + + // Operations are dumped in order of most recent first. + int counter = 0; + int n = 0; + Operation operation = mOperations[index]; + do { + printer.println(operation.describe(counter)); + + if (index > 0) { + index -= 1; + } else { + index = MAX_RECENT_OPERATIONS - 1; + } + n++; + counter++; + operation = mOperations[index]; + } while (operation != null && n < MAX_RECENT_OPERATIONS); + counter += dumpIfNotRecentLocked(printer, mTransaction, counter); + } + } + + private void dumpLongLocked(Printer printer) { + printer.println(" Operations exceeding " + LONG_OPERATION_THRESHOLD_MS + "ms:"); + if (mLongOperations.isEmpty()) { + printer.println(" <none>"); + return; + } + Operation[] longOps = mLongOperations.toArray(); + for (int i = 0; i < longOps.length; i++) { + if (longOps[i] != null) { + printer.println(longOps[i].describe(i)); } } } + + public long getTotalLongOperations() { + return mTotalLongOperations; + } + + public void dump(Printer printer) { + synchronized (mOperations) { + dumpRecentLocked(printer); + dumpLongLocked(printer); + } + } } - private static final class Operation { + private final class Operation { // Trim all SQL statements to 256 characters inside the trace marker. // This limit gives plenty of context while leaving space for other // entries in the trace buffer (and ensures atrace doesn't truncate the // marker for us, potentially losing metadata in the process). private static final int MAX_TRACE_METHOD_NAME_LEN = 256; + // The reserved start time that indicates the Operation is empty. + private static final long EMPTY_OPERATION = -1; + + // The formatter for the timestamp. + private static final DateTimeFormatter sDateTime = + DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS", Locale.US); + public long mStartWallTime; // in System.currentTimeMillis() public long mStartTime; // in SystemClock.uptimeMillis(); public long mEndTime; // in SystemClock.uptimeMillis(); @@ -1801,16 +1896,58 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen public boolean mFinished; public Exception mException; public int mCookie; - public String mPath; public long mResultLong; // MIN_VALUE means "value not set". public String mResultString; + /** Reset the object to begin a new operation. */ + void start() { + mStartWallTime = System.currentTimeMillis(); + mStartTime = SystemClock.uptimeMillis(); + mEndTime = Long.MIN_VALUE; + mKind = null; + mSql = null; + if (mBindArgs != null) mBindArgs.clear(); + mFinished = false; + mException = null; + mCookie = -1; + mResultLong = Long.MIN_VALUE; + mResultString = null; + } + + /** + * Initialize from the source object. This is meant to clone the object for use in a + * transaction operation. To that end, the local bind args are set to null. + */ + void copyFrom(Operation r) { + mStartWallTime = r.mStartWallTime; + mStartTime = r.mStartTime; + mEndTime = r.mEndTime; + mKind = r.mKind; + mSql = r.mSql; + mBindArgs = null; + mFinished = r.mFinished; + mException = r.mException; + mCookie = r.mCookie; + mResultLong = r.mResultLong; + mResultString = r.mResultString; + } + + /** Mark the operation empty. */ + void setEmpty() { + mStartWallTime = EMPTY_OPERATION; + } + + /** Return true if the operation is empty. */ + boolean isEmpty() { + return mStartWallTime == EMPTY_OPERATION; + } + public void describe(StringBuilder msg, boolean allowDetailedLog) { msg.append(mKind); if (mFinished) { msg.append(" took ").append(mEndTime - mStartTime).append("ms"); } else { - msg.append(" started ").append(System.currentTimeMillis() - mStartWallTime) + msg.append(" started ").append(SystemClock.uptimeMillis() - mStartTime) .append("ms ago"); } msg.append(" - ").append(getStatus()); @@ -1839,7 +1976,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } msg.append("]"); } - msg.append(", path=").append(mPath); + msg.append(", path=").append(mPool.getPath()); if (mException != null) { msg.append(", exception=\"").append(mException.getMessage()).append("\""); } @@ -1851,6 +1988,21 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } + /** + * Convert a wall-clock time in milliseconds to logcat format. + */ + private String timeString(long millis) { + return sDateTime.withZone(ZoneId.systemDefault()).format(Instant.ofEpochMilli(millis)); + } + + public String describe(int n) { + final StringBuilder msg = new StringBuilder(); + final String start = timeString(mStartWallTime); + msg.append(" ").append(n).append(": [").append(start).append("] "); + describe(msg, false); // Never dump bingargs in a bugreport + return msg.toString(); + } + private String getStatus() { if (!mFinished) { return "running"; @@ -1864,7 +2016,6 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen return methodName.substring(0, MAX_TRACE_METHOD_NAME_LEN); return methodName; } - } /** diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java index ad335b62f05e..15d7d6675c8e 100644 --- a/core/java/android/database/sqlite/SQLiteConnectionPool.java +++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java @@ -1175,7 +1175,7 @@ public final class SQLiteConnectionPool implements Closeable { + ", isLegacyCompatibilityWalEnabled=" + isCompatibilityWalEnabled + ", journalMode=" + TextUtils.emptyIfNull(mConfiguration.resolveJournalMode()) + ", syncMode=" + TextUtils.emptyIfNull(mConfiguration.resolveSyncMode())); - printer.println(" IsReadOnlyDatabase=" + mConfiguration.isReadOnlyDatabase()); + printer.println(" IsReadOnlyDatabase: " + mConfiguration.isReadOnlyDatabase()); if (isCompatibilityWalEnabled) { printer.println(" Compatibility WAL enabled: wal_syncmode=" diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java index 7d9f02d6a96d..3b14d9d71b3e 100644 --- a/core/java/android/database/sqlite/SQLiteSession.java +++ b/core/java/android/database/sqlite/SQLiteSession.java @@ -312,6 +312,15 @@ public final class SQLiteSession { cancellationSignal); } + private String modeString(int transactionMode) { + switch (transactionMode) { + case TRANSACTION_MODE_IMMEDIATE: return "TRANSACTION-IMMEDIATE"; + case TRANSACTION_MODE_EXCLUSIVE: return "TRANSACTION-EXCLUSIVE"; + case TRANSACTION_MODE_DEFERRED: return "TRANSACTION-DEFERRED"; + default: return "TRANSACTION"; + } + } + private void beginTransactionUnchecked(int transactionMode, SQLiteTransactionListener transactionListener, int connectionFlags, CancellationSignal cancellationSignal) { @@ -321,6 +330,7 @@ public final class SQLiteSession { if (mTransactionStack == null) { acquireConnection(null, connectionFlags, cancellationSignal); // might throw + mConnection.recordBeginTransaction(modeString(transactionMode)); } try { // Set up the transaction such that we can back out safely @@ -465,6 +475,7 @@ public final class SQLiteSession { mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw } } finally { + mConnection.recordEndTransaction(successful); releaseConnection(); // might throw } } diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig index 3ba8be4cc2ab..ff07498836af 100644 --- a/core/java/android/hardware/biometrics/flags.aconfig +++ b/core/java/android/hardware/biometrics/flags.aconfig @@ -2,6 +2,7 @@ package: "android.hardware.biometrics" flag { name: "last_authentication_time" + is_exported: true namespace: "wallet_integration" description: "Feature flag for adding getLastAuthenticationTime API to BiometricManager" bug: "301979982" @@ -9,6 +10,7 @@ flag { flag { name: "add_key_agreement_crypto_object" + is_exported: true namespace: "biometrics" description: "Feature flag for adding KeyAgreement api to CryptoObject." bug: "282058146" diff --git a/core/java/android/hardware/devicestate/DeviceState.java b/core/java/android/hardware/devicestate/DeviceState.java index e35e80126388..905d911248ca 100644 --- a/core/java/android/hardware/devicestate/DeviceState.java +++ b/core/java/android/hardware/devicestate/DeviceState.java @@ -25,8 +25,9 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; - -import com.android.internal.util.Preconditions; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArraySet; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -37,8 +38,7 @@ import java.util.Objects; import java.util.Set; /** - * A state of the device defined by the {@link DeviceStateProvider} and managed by the - * {@link DeviceStateManagerService}. + * A state of the device managed by {@link DeviceStateManager}. * <p> * Device state is an abstract concept that allows mapping the current state of the device to the * state of the system. This is useful for variable-state devices, like foldable or rollable @@ -268,68 +268,88 @@ public final class DeviceState { @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface DeviceStateProperties {} - /** Unique identifier for the device state. */ - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) - private final int mIdentifier; + /** @hide */ + @IntDef(prefix = {"PROPERTY_"}, flag = true, value = { + PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED, + PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN, + PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN + }) + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) + public @interface PhysicalDeviceStateProperties {} + + /** @hide */ + @IntDef(prefix = {"PROPERTY_"}, flag = true, value = { + PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, + PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP, + PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, + PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST, + PROPERTY_APP_INACCESSIBLE, + PROPERTY_EMULATED_ONLY, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, + PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP, + PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE, + PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY, + PROPERTY_FEATURE_REAR_DISPLAY, + PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT + }) + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) + public @interface SystemDeviceStateProperties {} - /** String description of the device state. */ @NonNull - private final String mName; + private final DeviceState.Configuration mDeviceStateConfiguration; @DeviceStateFlags private final int mFlags; - private final Set<@DeviceStateProperties Integer> mProperties; + /** @hide */ + public DeviceState(@NonNull DeviceState.Configuration deviceStateConfiguration) { + Objects.requireNonNull(deviceStateConfiguration, "Device StateConfiguration is null"); + mDeviceStateConfiguration = deviceStateConfiguration; + mFlags = 0; + } + + /** @hide */ + public DeviceState( + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, + @NonNull String name, + @NonNull Set<@DeviceStateProperties Integer> properties) { + mDeviceStateConfiguration = new DeviceState.Configuration(identifier, name, properties, + Collections.emptySet()); + mFlags = 0; + } /** * @deprecated Deprecated in favor of {@link #DeviceState(int, String, Set)} * @hide */ // TODO(b/325124054): Make non-default and remove deprecated callback methods. - @TestApi @Deprecated public DeviceState( @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @DeviceStateFlags int flags) { - Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE_IDENTIFIER, - MAXIMUM_DEVICE_STATE_IDENTIFIER, - "identifier"); - mIdentifier = identifier; - mName = name; + mDeviceStateConfiguration = new DeviceState.Configuration(identifier, name, + Collections.emptySet(), Collections.emptySet()); mFlags = flags; - mProperties = Collections.emptySet(); - } - - /** @hide */ - @TestApi - public DeviceState( - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = - MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, - @NonNull String name, - @NonNull Set<@DeviceStateProperties Integer> properties) { - Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE_IDENTIFIER, - MAXIMUM_DEVICE_STATE_IDENTIFIER, - "identifier"); - - mIdentifier = identifier; - mName = name; - mProperties = Set.copyOf(properties); - mFlags = 0; } /** Returns the unique identifier for the device state. */ @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER) public int getIdentifier() { - return mIdentifier; + return mDeviceStateConfiguration.getIdentifier(); } /** Returns a string description of the device state. */ @NonNull public String getName() { - return mName; + return mDeviceStateConfiguration.getName(); } /** @@ -345,10 +365,13 @@ public final class DeviceState { @Override public String toString() { - return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' - + ", app_accessible=" + !hasProperty(PROPERTY_APP_INACCESSIBLE) + return "DeviceState{" + "identifier=" + mDeviceStateConfiguration.getIdentifier() + + ", name='" + mDeviceStateConfiguration.getName() + '\'' + + ", app_accessible=" + !mDeviceStateConfiguration.getSystemProperties().contains( + PROPERTY_APP_INACCESSIBLE) + ", cancel_when_requester_not_on_top=" - + hasProperty(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + + mDeviceStateConfiguration.getSystemProperties().contains( + PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + "}"; } @@ -357,14 +380,12 @@ public final class DeviceState { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DeviceState that = (DeviceState) o; - return mIdentifier == that.mIdentifier - && Objects.equals(mName, that.mName) - && Objects.equals(mProperties, that.mProperties); + return Objects.equals(mDeviceStateConfiguration, that.mDeviceStateConfiguration); } @Override public int hashCode() { - return Objects.hash(mIdentifier, mName, mProperties); + return Objects.hash(mDeviceStateConfiguration); } /** Checks if a specific flag is set @@ -381,7 +402,8 @@ public final class DeviceState { * Checks if a specific property is set on this state */ public boolean hasProperty(@DeviceStateProperties int propertyToCheckFor) { - return mProperties.contains(propertyToCheckFor); + return mDeviceStateConfiguration.mSystemProperties.contains(propertyToCheckFor) + || mDeviceStateConfiguration.mPhysicalProperties.contains(propertyToCheckFor); } /** @@ -389,10 +411,191 @@ public final class DeviceState { */ public boolean hasProperties(@NonNull @DeviceStateProperties int... properties) { for (int i = 0; i < properties.length; i++) { - if (mProperties.contains(properties[i])) { + if (!hasProperty(properties[i])) { return false; } } return true; } + + /** + * Returns the underlying {@link DeviceState.Configuration} object used to model the + * device state. + * @hide + */ + public Configuration getConfiguration() { + return mDeviceStateConfiguration; + } + + /** + * Detailed description of a {@link DeviceState} that includes separated sets of + * {@link DeviceStateProperties} for properties that correspond to the state of the system when + * the device is in this state, as well as physical properties that describe this state. + * + * Instantiation of this class should only be done by the system server, and clients of + * {@link DeviceStateManager} will receive {@link DeviceState} objects. + * + * @see DeviceStateManager + * @hide + */ + public static final class Configuration implements Parcelable { + /** Unique identifier for the device state. */ + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) + private final int mIdentifier; + + /** String description of the device state. */ + @NonNull + private final String mName; + + /** {@link ArraySet} of system properties that apply to this state. */ + @NonNull + private final ArraySet<@SystemDeviceStateProperties Integer> mSystemProperties; + + /** {@link ArraySet} of physical device properties that apply to this state. */ + @NonNull + private final ArraySet<@PhysicalDeviceStateProperties Integer> mPhysicalProperties; + + private Configuration(int identifier, @NonNull String name, + @NonNull Set<@SystemDeviceStateProperties Integer> systemProperties, + @NonNull Set<@PhysicalDeviceStateProperties Integer> physicalProperties) { + mIdentifier = identifier; + mName = name; + mSystemProperties = new ArraySet<@SystemDeviceStateProperties Integer>( + systemProperties); + mPhysicalProperties = new ArraySet<@PhysicalDeviceStateProperties Integer>( + physicalProperties); + } + + /** Returns the unique identifier for the device state. */ + public int getIdentifier() { + return mIdentifier; + } + + /** Returns a string description of the device state. */ + @NonNull + public String getName() { + return mName; + } + + /** Returns the {@link Set} of system properties that apply to this state. */ + @NonNull + public Set<@SystemDeviceStateProperties Integer> getSystemProperties() { + return mSystemProperties; + } + + /** Returns the {@link Set} of physical device properties that apply to this state. */ + @NonNull + public Set<@DeviceStateProperties Integer> getPhysicalProperties() { + return mPhysicalProperties; + } + + @Override + public String toString() { + return "DeviceState{" + "identifier=" + mIdentifier + + ", name='" + mName + '\'' + + ", app_accessible=" + mSystemProperties.contains(PROPERTY_APP_INACCESSIBLE) + + ", cancel_when_requester_not_on_top=" + + mSystemProperties.contains(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeviceState.Configuration that = (DeviceState.Configuration) o; + return mIdentifier == that.mIdentifier + && Objects.equals(mName, that.mName) + && Objects.equals(mSystemProperties, that.mSystemProperties) + && Objects.equals(mPhysicalProperties, that.mPhysicalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(mIdentifier, mName, mSystemProperties, mPhysicalProperties); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mIdentifier); + dest.writeString8(mName); + + dest.writeInt(mSystemProperties.size()); + for (int i = 0; i < mSystemProperties.size(); i++) { + dest.writeInt(mSystemProperties.valueAt(i)); + } + + dest.writeInt(mPhysicalProperties.size()); + for (int i = 0; i < mPhysicalProperties.size(); i++) { + dest.writeInt(mPhysicalProperties.valueAt(i)); + } + } + + @NonNull + public static final Creator<DeviceState.Configuration> CREATOR = new Creator<>() { + @Override + public DeviceState.Configuration createFromParcel(Parcel source) { + int identifier = source.readInt(); + String name = source.readString8(); + ArraySet<@DeviceStateProperties Integer> systemProperties = new ArraySet<>(); + for (int i = 0; i < source.readInt(); i++) { + systemProperties.add(source.readInt()); + } + ArraySet<@DeviceStateProperties Integer> physicalProperties = new ArraySet<>(); + for (int j = 0; j < source.readInt(); j++) { + physicalProperties.add(source.readInt()); + } + return new DeviceState.Configuration(identifier, name, systemProperties, + physicalProperties); + } + + @Override + public DeviceState.Configuration[] newArray(int size) { + return new DeviceState.Configuration[size]; + } + }; + + /** @hide */ + public static class Builder { + private final int mIdentifier; + private final String mName; + private Set<@SystemDeviceStateProperties Integer> mSystemProperties = + Collections.emptySet(); + private Set<@PhysicalDeviceStateProperties Integer> mPhysicalProperties = + Collections.emptySet(); + + public Builder(int identifier, String name) { + mIdentifier = identifier; + mName = name; + } + + /** Sets the system properties for this {@link DeviceState.Configuration.Builder} */ + public Builder setSystemProperties( + Set<@SystemDeviceStateProperties Integer> systemProperties) { + mSystemProperties = systemProperties; + return this; + } + + /** Sets the system properties for this {@link DeviceState.Configuration.Builder} */ + public Builder setPhysicalProperties( + Set<@PhysicalDeviceStateProperties Integer> physicalProperties) { + mPhysicalProperties = physicalProperties; + return this; + } + + /** + * Returns a new {@link DeviceState.Configuration} whose values match the values set on + * the builder. + */ + public DeviceState.Configuration build() { + return new DeviceState.Configuration(mIdentifier, mName, mSystemProperties, + mPhysicalProperties); + } + } + } } diff --git a/core/java/android/hardware/devicestate/DeviceStateInfo.java b/core/java/android/hardware/devicestate/DeviceStateInfo.java index bc6af37afc45..c319c893aaab 100644 --- a/core/java/android/hardware/devicestate/DeviceStateInfo.java +++ b/core/java/android/hardware/devicestate/DeviceStateInfo.java @@ -24,7 +24,8 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; @@ -56,19 +57,19 @@ public final class DeviceStateInfo implements Parcelable { * The list of states supported by the device. */ @NonNull - public final int[] supportedStates; + public final ArrayList<DeviceState> supportedStates; /** * The base (non-override) state of the device. The base state is the state of the device * ignoring any override requests made through a call to {@link DeviceStateManager#requestState( * DeviceStateRequest, Executor, DeviceStateRequest.Callback)}. */ - public final int baseState; + public final DeviceState baseState; /** * The state of the device. */ - public final int currentState; + public final DeviceState currentState; /** * Creates a new instance of {@link DeviceStateInfo}. @@ -76,8 +77,9 @@ public final class DeviceStateInfo implements Parcelable { * NOTE: Unlike {@link #DeviceStateInfo(DeviceStateInfo)}, this constructor does not copy the * supplied parameters. */ - public DeviceStateInfo(@NonNull int[] supportedStates, int baseState, int state) { - this.supportedStates = supportedStates; + public DeviceStateInfo(@NonNull List<DeviceState> supportedStates, DeviceState baseState, + DeviceState state) { + this.supportedStates = new ArrayList<>(supportedStates); this.baseState = baseState; this.currentState = state; } @@ -87,8 +89,7 @@ public final class DeviceStateInfo implements Parcelable { * the fields of the returned instance. */ public DeviceStateInfo(@NonNull DeviceStateInfo info) { - this(Arrays.copyOf(info.supportedStates, info.supportedStates.length), - info.baseState, info.currentState); + this(List.copyOf(info.supportedStates), info.baseState, info.currentState); } @Override @@ -96,15 +97,15 @@ public final class DeviceStateInfo implements Parcelable { if (this == other) return true; if (other == null || getClass() != other.getClass()) return false; DeviceStateInfo that = (DeviceStateInfo) other; - return baseState == that.baseState - && currentState == that.currentState - && Arrays.equals(supportedStates, that.supportedStates); + return baseState.equals(that.baseState) + && currentState.equals(that.currentState) + && Objects.equals(supportedStates, that.supportedStates); } @Override public int hashCode() { int result = Objects.hash(baseState, currentState); - result = 31 * result + Arrays.hashCode(supportedStates); + result = 31 * result + supportedStates.hashCode(); return result; } @@ -112,13 +113,13 @@ public final class DeviceStateInfo implements Parcelable { @ChangeFlags public int diff(@NonNull DeviceStateInfo other) { int diff = 0; - if (!Arrays.equals(supportedStates, other.supportedStates)) { + if (!supportedStates.equals(other.supportedStates)) { diff |= CHANGED_SUPPORTED_STATES; } - if (baseState != other.baseState) { + if (!baseState.equals(other.baseState)) { diff |= CHANGED_BASE_STATE; } - if (currentState != other.currentState) { + if (!currentState.equals(other.currentState)) { diff |= CHANGED_CURRENT_STATE; } return diff; @@ -126,13 +127,13 @@ public final class DeviceStateInfo implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(supportedStates.length); - for (int i = 0; i < supportedStates.length; i++) { - dest.writeInt(supportedStates[i]); + dest.writeInt(supportedStates.size()); + for (int i = 0; i < supportedStates.size(); i++) { + dest.writeTypedObject(supportedStates.get(i).getConfiguration(), flags); } - dest.writeInt(baseState); - dest.writeInt(currentState); + dest.writeTypedObject(baseState.getConfiguration(), flags); + dest.writeTypedObject(currentState.getConfiguration(), flags); } @Override @@ -140,16 +141,21 @@ public final class DeviceStateInfo implements Parcelable { return 0; } - public static final @NonNull Creator<DeviceStateInfo> CREATOR = new Creator<DeviceStateInfo>() { + public static final @NonNull Creator<DeviceStateInfo> CREATOR = new Creator<>() { @Override public DeviceStateInfo createFromParcel(Parcel source) { final int numberOfSupportedStates = source.readInt(); - final int[] supportedStates = new int[numberOfSupportedStates]; + final ArrayList<DeviceState> supportedStates = new ArrayList<>(numberOfSupportedStates); for (int i = 0; i < numberOfSupportedStates; i++) { - supportedStates[i] = source.readInt(); + DeviceState.Configuration configuration = source.readTypedObject( + DeviceState.Configuration.CREATOR); + supportedStates.add(i, new DeviceState(configuration)); } - final int baseState = source.readInt(); - final int currentState = source.readInt(); + + final DeviceState baseState = new DeviceState( + source.readTypedObject(DeviceState.Configuration.CREATOR)); + final DeviceState currentState = new DeviceState( + source.readTypedObject(DeviceState.Configuration.CREATOR)); return new DeviceStateInfo(supportedStates, baseState, currentState); } diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java index 8b4d43ed651f..a4c383343062 100644 --- a/core/java/android/hardware/devicestate/DeviceStateManager.java +++ b/core/java/android/hardware/devicestate/DeviceStateManager.java @@ -49,7 +49,7 @@ public final class DeviceStateManager { * * @hide */ - public static final int INVALID_DEVICE_STATE = -1; + public static final int INVALID_DEVICE_STATE_IDENTIFIER = -1; /** * The minimum allowed device state identifier. diff --git a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java index 6db5aee106a8..d6cc00d45ec4 100644 --- a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java +++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java @@ -19,7 +19,6 @@ package android.hardware.devicestate; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; -import android.app.ActivityThread; import android.content.Context; import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback; import android.os.Binder; @@ -33,13 +32,9 @@ import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; -import com.android.internal.util.ArrayUtils; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.Executor; /** @@ -55,18 +50,12 @@ public final class DeviceStateManagerGlobal { private static final String TAG = "DeviceStateManagerGlobal"; private static final boolean DEBUG = Build.IS_DEBUGGABLE; - // TODO(b/325124054): Remove when system server refactor is completed - private static int[] sFoldedDeviceStates = new int[0]; - /** * Returns an instance of {@link DeviceStateManagerGlobal}. May return {@code null} if a * connection with the device state service couldn't be established. */ @Nullable public static DeviceStateManagerGlobal getInstance() { - // TODO(b/325124054): Remove when system server refactor is completed - instantiateFoldedStateArray(); - synchronized (DeviceStateManagerGlobal.class) { if (sInstance == null) { IBinder b = ServiceManager.getService(Context.DEVICE_STATE_SERVICE); @@ -79,16 +68,6 @@ public final class DeviceStateManagerGlobal { } } - // TODO(b/325124054): Remove when system server refactor is completed - // TODO(b/325330654): Investigate if we need a Context passed in to DSMGlobal - private static void instantiateFoldedStateArray() { - Context context = ActivityThread.currentApplication(); - if (context != null) { - sFoldedDeviceStates = context.getResources().getIntArray( - com.android.internal.R.array.config_foldedDeviceStates); - } - } - private final Object mLock = new Object(); @NonNull private final IDeviceStateManager mDeviceStateManager; @@ -115,6 +94,7 @@ public final class DeviceStateManagerGlobal { * * @see DeviceStateManager#getSupportedStates() */ + // TODO(b/325124054): Remove unused methods when clients are migrated. public int[] getSupportedStates() { synchronized (mLock) { final DeviceStateInfo currentInfo; @@ -132,12 +112,12 @@ public final class DeviceStateManagerGlobal { } } - return Arrays.copyOf(currentInfo.supportedStates, currentInfo.supportedStates.length); + return getSupportedStateIdentifiersLocked(currentInfo.supportedStates); } } /** - * Returns the {@link List} of supported device states. + * Returns {@link List} of supported {@link DeviceState}s. * * @see DeviceStateManager#getSupportedDeviceStates() */ @@ -158,7 +138,7 @@ public final class DeviceStateManagerGlobal { } } - return createDeviceStateList(currentInfo.supportedStates); + return List.copyOf(currentInfo.supportedStates); } } @@ -285,13 +265,14 @@ public final class DeviceStateManagerGlobal { if (mLastReceivedInfo != null) { // Copy the array to prevent the callback from modifying the internal state. - final int[] supportedStates = Arrays.copyOf(mLastReceivedInfo.supportedStates, - mLastReceivedInfo.supportedStates.length); + final int[] supportedStates = getSupportedStateIdentifiersLocked( + mLastReceivedInfo.supportedStates); wrapper.notifySupportedStatesChanged(supportedStates); - wrapper.notifySupportedDeviceStatesChanged(createDeviceStateList(supportedStates)); - wrapper.notifyBaseStateChanged(mLastReceivedInfo.baseState); - wrapper.notifyStateChanged(mLastReceivedInfo.currentState); - wrapper.notifyDeviceStateChanged(createDeviceState(mLastReceivedInfo.currentState)); + wrapper.notifySupportedDeviceStatesChanged( + List.copyOf(mLastReceivedInfo.supportedStates)); + wrapper.notifyBaseStateChanged(mLastReceivedInfo.baseState.getIdentifier()); + wrapper.notifyStateChanged(mLastReceivedInfo.currentState.getIdentifier()); + wrapper.notifyDeviceStateChanged(mLastReceivedInfo.currentState); } } } @@ -349,6 +330,15 @@ public final class DeviceStateManagerGlobal { return -1; } + @GuardedBy("mLock") + private int[] getSupportedStateIdentifiersLocked(List<DeviceState> states) { + int[] identifiers = new int[states.size()]; + for (int i = 0; i < states.size(); i++) { + identifiers[i] = states.get(i).getIdentifier(); + } + return identifiers; + } + @Nullable private IBinder findRequestTokenLocked(@NonNull DeviceStateRequest request) { for (int i = 0; i < mRequests.size(); i++) { @@ -363,32 +353,31 @@ public final class DeviceStateManagerGlobal { private void handleDeviceStateInfoChanged(@NonNull DeviceStateInfo info) { ArrayList<DeviceStateCallbackWrapper> callbacks; DeviceStateInfo oldInfo; + int[] supportedStateIdentifiers; synchronized (mLock) { oldInfo = mLastReceivedInfo; mLastReceivedInfo = info; callbacks = new ArrayList<>(mCallbacks); + supportedStateIdentifiers = getSupportedStateIdentifiersLocked(info.supportedStates); } final int diff = oldInfo == null ? ~0 : info.diff(oldInfo); if ((diff & DeviceStateInfo.CHANGED_SUPPORTED_STATES) > 0) { for (int i = 0; i < callbacks.size(); i++) { - // Copy the array to prevent callbacks from modifying the internal state. - final int[] supportedStates = Arrays.copyOf(info.supportedStates, - info.supportedStates.length); - callbacks.get(i).notifySupportedStatesChanged(supportedStates); callbacks.get(i).notifySupportedDeviceStatesChanged( - createDeviceStateList(supportedStates)); + List.copyOf(info.supportedStates)); + callbacks.get(i).notifySupportedStatesChanged(supportedStateIdentifiers); } } if ((diff & DeviceStateInfo.CHANGED_BASE_STATE) > 0) { for (int i = 0; i < callbacks.size(); i++) { - callbacks.get(i).notifyBaseStateChanged(info.baseState); + callbacks.get(i).notifyBaseStateChanged(info.baseState.getIdentifier()); } } if ((diff & DeviceStateInfo.CHANGED_CURRENT_STATE) > 0) { for (int i = 0; i < callbacks.size(); i++) { - callbacks.get(i).notifyStateChanged(info.currentState); - callbacks.get(i).notifyDeviceStateChanged(createDeviceState(info.currentState)); + callbacks.get(i).notifyDeviceStateChanged(info.currentState); + callbacks.get(i).notifyStateChanged(info.currentState.getIdentifier()); } } } @@ -421,36 +410,6 @@ public final class DeviceStateManagerGlobal { } } - /** - * Creates a {@link DeviceState} object from a device state identifier, with the - * {@link DeviceState} property that corresponds to what display is primary. - * - */ - // TODO(b/325124054): Remove when system server refactor is completed - @NonNull - private DeviceState createDeviceState(int stateIdentifier) { - final Set<@DeviceState.DeviceStateProperties Integer> properties = new HashSet<>(); - if (ArrayUtils.contains(sFoldedDeviceStates, stateIdentifier)) { - properties.add(DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY); - } else { - properties.add(DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY); - } - return new DeviceState(stateIdentifier, "" /* name */, properties); - } - - /** - * Creates a list of {@link DeviceState} objects from an array of state identifiers. - */ - // TODO(b/325124054): Remove when system server refactor is completed - @NonNull - private List<DeviceState> createDeviceStateList(int[] supportedStates) { - List<DeviceState> deviceStateList = new ArrayList<>(); - for (int i = 0; i < supportedStates.length; i++) { - deviceStateList.add(createDeviceState(supportedStates[i])); - } - return deviceStateList; - } - private final class DeviceStateManagerCallback extends IDeviceStateManagerCallback.Stub { @Override public void onDeviceStateInfoChanged(DeviceStateInfo info) { diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig index 9f9aef8acc6a..3544a691cce4 100644 --- a/core/java/android/net/flags.aconfig +++ b/core/java/android/net/flags.aconfig @@ -19,6 +19,7 @@ flag { flag { name: "register_nsd_offload_engine" + is_exported: true namespace: "android_core_networking" description: "Flag for registerOffloadEngine API in NsdManager" bug: "294777050" diff --git a/core/java/android/net/thread/flags.aconfig b/core/java/android/net/thread/flags.aconfig index d679f9c3acb8..ef798ad46d2d 100644 --- a/core/java/android/net/thread/flags.aconfig +++ b/core/java/android/net/thread/flags.aconfig @@ -5,6 +5,7 @@ package: "com.android.net.thread.platform.flags" flag { name: "thread_user_restriction_enabled" + is_exported: true namespace: "thread_network" description: "Controls whether user restriction on thread networks is enabled" bug: "307679182" @@ -12,6 +13,7 @@ flag { flag { name: "thread_enabled_platform" + is_exported: true namespace: "thread_network" description: "Controls whether the Android Thread feature is enabled" bug: "301473012" diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig index 7afd72195fcb..97b773ee12ec 100644 --- a/core/java/android/net/vcn/flags.aconfig +++ b/core/java/android/net/vcn/flags.aconfig @@ -2,6 +2,7 @@ package: "android.net.vcn" flag { name: "safe_mode_config" + is_exported: true namespace: "vcn" description: "Feature flag for safe mode configurability" bug: "276358140" diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java index c0b490929c0a..bebb912bd069 100644 --- a/core/java/android/os/Trace.java +++ b/core/java/android/os/Trace.java @@ -164,6 +164,8 @@ public final class Trace { private static native void nativeInstant(long tag, String name); @FastNative private static native void nativeInstantForTrack(long tag, String trackName, String name); + @FastNative + private static native void nativeRegisterWithPerfetto(); private Trace() { } @@ -523,4 +525,15 @@ public final class Trace { nativeTraceCounter(TRACE_TAG_APP, counterName, counterValue); } } + + /** + * Initialize the perfetto SDK. This must be called before any tracing + * calls so that perfetto SDK can be used, otherwise libcutils would be + * used. + * + * @hide + */ + public static void registerWithPerfetto() { + nativeRegisterWithPerfetto(); + } } diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig index d9400accb4bd..943014caeb09 100644 --- a/core/java/android/os/flags.aconfig +++ b/core/java/android/os/flags.aconfig @@ -3,6 +3,7 @@ container: "system" flag { name: "android_os_build_vanilla_ice_cream" + is_exported: true namespace: "build" description: "Feature flag for adding the VANILLA_ICE_CREAM constant." bug: "264658905" @@ -10,6 +11,7 @@ flag { flag { name: "state_of_health_public" + is_exported: true namespace: "system_sw_battery" description: "Feature flag for making state_of_health a public api." bug: "288842045" @@ -132,3 +134,10 @@ flag { is_fixed_read_only: true bug: "324241334" } + +flag { + namespace: "system_performance" + name: "perfetto_sdk_tracing" + description: "Tracing using Perfetto SDK." + bug: "303199244" +} diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 5e7edda31c19..3c77c44fb3f0 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -2,6 +2,7 @@ package: "android.security" flag { name: "certificate_transparency_configuration" + is_exported: true namespace: "network_security" description: "Enable certificate transparency setting in the network security config" bug: "28746284" @@ -16,6 +17,7 @@ flag { flag { name: "mgf1_digest_setter_v2" + is_exported: true namespace: "hardware_backed_security" description: "Feature flag for mgf1 digest setter in key generation and import parameters." bug: "308378912" @@ -32,6 +34,7 @@ flag { flag { name: "keyinfo_unlocked_device_required" + is_exported: true namespace: "hardware_backed_security" description: "Add the API android.security.keystore.KeyInfo#isUnlockedDeviceRequired()" bug: "296475382" diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl index dd8b3deabc01..09e6b5de8a3c 100644 --- a/core/java/android/service/dreams/IDreamManager.aidl +++ b/core/java/android/service/dreams/IDreamManager.aidl @@ -38,6 +38,8 @@ interface IDreamManager { boolean isDreaming(); @UnsupportedAppUsage boolean isDreamingOrInPreview(); + @UnsupportedAppUsage + boolean canStartDreaming(boolean isScreenOn); void finishSelf(in IBinder token, boolean immediate); void startDozing(in IBinder token, int screenState, int screenBrightness); void stopDozing(in IBinder token); diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java index f9eba2948913..4ac78f593530 100644 --- a/core/java/android/view/InsetsSource.java +++ b/core/java/android/view/InsetsSource.java @@ -355,11 +355,17 @@ public class InsetsSource implements Parcelable { final Rect frame = getFrame(); if (mBoundingRects == null) { // No bounding rects set, make a single bounding rect that covers the intersection of - // the |frame| and the |relativeFrame|. + // the |frame| and the |relativeFrame|. Also make it relative to the window origin. return mTmpBoundingRect.setIntersect(frame, relativeFrame) - ? new Rect[]{ new Rect(mTmpBoundingRect) } + ? new Rect[]{ + new Rect( + mTmpBoundingRect.left - relativeFrame.left, + mTmpBoundingRect.top - relativeFrame.top, + mTmpBoundingRect.right - relativeFrame.left, + mTmpBoundingRect.bottom - relativeFrame.top + ) + } : NO_BOUNDING_RECTS; - } // Special treatment for captionBar inset type. During drag-resizing, the |frame| and diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f0bde9705c5a..a5ff48fd3ca6 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -7057,16 +7057,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Clears the request and callback previously set - * through {@link View#setCredentialManagerRequest}. + * through {@link View#setPendingCredentialRequest}. * Once this API is invoked, there will be no request fired to {@link CredentialManager} * on future view focus events. * - * @see #setCredentialManagerRequest + * @see #setPendingCredentialRequest */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) - public void clearCredentialManagerRequest() { + public void clearPendingCredentialRequest() { if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) { - Log.v(AUTOFILL_LOG_TAG, "clearCredentialManagerRequest called"); + Log.v(AUTOFILL_LOG_TAG, "clearPendingCredentialRequest called"); } mViewCredentialHandler = null; } @@ -7096,7 +7096,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * propagated for the given view */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) - public void setCredentialManagerRequest(@NonNull GetCredentialRequest request, + public void setPendingCredentialRequest(@NonNull GetCredentialRequest request, @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) { Preconditions.checkNotNull(request, "request must not be null"); Preconditions.checkNotNull(callback, "request must not be null"); @@ -8622,6 +8622,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @CallSuper protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction, @Nullable Rect previouslyFocusedRect) { + if (DBG) { + Log.d(VIEW_LOG_TAG, "onFocusChanged() entered. gainFocus: " + + gainFocus); + } if (gainFocus) { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); } else { @@ -8686,6 +8690,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (canNotifyAutofillEnterExitEvent()) { AutofillManager afm = getAutofillManager(); if (afm != null) { + if (DBG) { + Log.d(VIEW_LOG_TAG, this + " afm is not null"); + } if (enter) { // We have not been laid out yet, hence cannot evaluate // whether this view is visible to the user, we will do @@ -8697,6 +8704,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // animation beginning. On the time, the view is not visible // to the user. And then as the animation progresses, the view // becomes visible to the user. + if (DBG) { + Log.d(VIEW_LOG_TAG, + "notifyEnterOrExitForAutoFillIfNeeded:" + + " isLaidOut(): " + isLaidOut() + + " isVisibleToUser(): " + isVisibleToUser() + + " isFocused(): " + isFocused()); + } if (!isLaidOut() || !isVisibleToUser()) { mPrivateFlags3 |= PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; } else if (isVisibleToUser()) { @@ -9590,7 +9604,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, structure.setIsCredential(isCredential()); } if (getViewCredentialHandler() != null) { - structure.setCredentialManagerRequest( + structure.setPendingCredentialRequest( getViewCredentialHandler().getRequest(), getViewCredentialHandler().getCallback()); } @@ -9995,22 +10009,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void onGetCredentialResponse(GetCredentialResponse response) { - if (getCredentialManagerCallback() == null) { + if (getPendingCredentialCallback() == null) { Log.w(AUTOFILL_LOG_TAG, "onGetCredentialResponse called but no callback found"); return; } - getCredentialManagerCallback().onResult(response); + getPendingCredentialCallback().onResult(response); } /** * @hide */ public void onGetCredentialException(String errorType, String errorMsg) { - if (getCredentialManagerCallback() == null) { + if (getPendingCredentialCallback() == null) { Log.w(AUTOFILL_LOG_TAG, "onGetCredentialException called but no callback found"); return; } - getCredentialManagerCallback().onError(new GetCredentialException(errorType, errorMsg)); + getPendingCredentialCallback().onError(new GetCredentialException(errorType, errorMsg)); } /** @@ -10041,13 +10055,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * the active {@link android.service.autofill.AutofillService} on * the device. * - * <p>See {@link #setCredentialManagerRequest} for more info. + * <p>See {@link #setPendingCredentialRequest} for more info. * * @return The credential request associated with this View. */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) @Nullable - public final GetCredentialRequest getCredentialManagerRequest() { + public final GetCredentialRequest getPendingCredentialRequest() { if (mViewCredentialHandler == null) { return null; } @@ -10057,14 +10071,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Returns the callback that has previously been set up on this view through - * the {@link #setCredentialManagerRequest} API. + * the {@link #setPendingCredentialRequest} API. * If the return value is null, that means no callback, or request, has been set * on the view and no {@link CredentialManager} flow will be invoked * when this view is focused. Traditioanl autofill flows will still * work, and autofillable content will still be returned through the * {@link #autofill(AutofillValue)} )} API. * - * <p>See {@link #setCredentialManagerRequest} for more info. + * <p>See {@link #setPendingCredentialRequest} for more info. * * @return The callback associated with this view that will be invoked on a response from * {@link CredentialManager} . @@ -10072,7 +10086,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) @Nullable public final OutcomeReceiver<GetCredentialResponse, - GetCredentialException> getCredentialManagerCallback() { + GetCredentialException> getPendingCredentialCallback() { if (mViewCredentialHandler == null) { return null; } @@ -10920,15 +10934,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private boolean isAutofillable() { - if (getAutofillType() == AUTOFILL_TYPE_NONE) return false; + if (DBG) { + Log.d(VIEW_LOG_TAG, "isAutofillable() entered."); + } + if (getAutofillType() == AUTOFILL_TYPE_NONE) { + if (DBG) { + Log.d(VIEW_LOG_TAG, "getAutofillType() returns AUTOFILL_TYPE_NONE"); + } + return false; + } final AutofillManager afm = getAutofillManager(); if (afm == null) { + if (DBG) { + Log.d(VIEW_LOG_TAG, "AutofillManager is null"); + } return false; } // Check whether view is not part of an activity. If it's not, return false. if (getAutofillViewId() <= LAST_APP_AUTOFILL_ID) { + if (DBG) { + Log.d(VIEW_LOG_TAG, "getAutofillViewId()<=LAST_APP_AUTOFILL_ID"); + } return false; } @@ -10938,11 +10966,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((isImportantForAutofill() && afm.isTriggerFillRequestOnFilteredImportantViewsEnabled()) || (!isImportantForAutofill() && afm.isTriggerFillRequestOnUnimportantViewEnabled())) { + if (DBG) { + Log.d(VIEW_LOG_TAG, "isImportantForAutofill(): " + isImportantForAutofill() + + "afm.isAutofillable(): " + afm.isAutofillable(this)); + } return afm.isAutofillable(this) ? true : notifyAugmentedAutofillIfNeeded(afm); } // If the previous condition is not met, fall back to the previous way to trigger fill // request based on autofill importance instead. + if (DBG) { + Log.d(VIEW_LOG_TAG, "isImportantForAutofill(): " + isImportantForAutofill()); + } return isImportantForAutofill() ? true : notifyAugmentedAutofillIfNeeded(afm); } @@ -10957,6 +10992,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** @hide */ public boolean canNotifyAutofillEnterExitEvent() { + if (DBG) { + Log.d(VIEW_LOG_TAG, "canNotifyAutofillEnterExitEvent() entered. " + + " isAutofillable(): " + isAutofillable() + + " isAttachedToWindow(): " + isAttachedToWindow()); + } return isAutofillable() && isAttachedToWindow(); } @@ -11002,7 +11042,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()))); } if (getViewCredentialHandler() != null) { - structure.setCredentialManagerRequest( + structure.setPendingCredentialRequest( getViewCredentialHandler().getRequest(), getViewCredentialHandler().getCallback()); } @@ -33874,7 +33914,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * - otherwise, use the previous category value. */ private void updateInfrequentCount() { - long currentTimeMillis = AnimationUtils.currentAnimationTimeMillis(); + long currentTimeMillis = getDrawingTime(); long timeIntervalMillis = currentTimeMillis - mLastUpdateTimeMillis; mMinusTwoFrameIntervalMillis = mMinusOneFrameIntervalMillis; mMinusOneFrameIntervalMillis = timeIntervalMillis; diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java index 1efd37591ee4..6c852c3a2d3f 100644 --- a/core/java/android/view/ViewStructure.java +++ b/core/java/android/view/ViewStructure.java @@ -361,11 +361,11 @@ public abstract class ViewStructure { * {@link android.credentials.CredentialManager} request will be fired when this * node is focused. * <p> For details on how a request and callback can be set, see - * {@link ViewStructure#setCredentialManagerRequest(GetCredentialRequest, OutcomeReceiver)} + * {@link ViewStructure#setPendingCredentialRequest(GetCredentialRequest, OutcomeReceiver)} */ @Nullable @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) - public GetCredentialRequest getCredentialManagerRequest() { + public GetCredentialRequest getPendingCredentialRequest() { return null; } @@ -376,12 +376,12 @@ public abstract class ViewStructure { * {@link android.credentials.CredentialManager} request will be fired when this * node is focused. * <p> For details on how a request and callback can be set, see - * {@link ViewStructure#setCredentialManagerRequest(GetCredentialRequest, OutcomeReceiver)} + * {@link ViewStructure#setPendingCredentialRequest(GetCredentialRequest, OutcomeReceiver)} */ @Nullable @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) public OutcomeReceiver< - GetCredentialResponse, GetCredentialException> getCredentialManagerCallback() { + GetCredentialResponse, GetCredentialException> getPendingCredentialCallback() { return null; } @@ -555,12 +555,12 @@ public abstract class ViewStructure { * @param callback the callback where the response or exception, is returned */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) - public void setCredentialManagerRequest(@NonNull GetCredentialRequest request, + public void setPendingCredentialRequest(@NonNull GetCredentialRequest request, @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {} /** * Clears the credential request previously set through - * {@link ViewStructure#setCredentialManagerRequest(GetCredentialRequest, OutcomeReceiver)} + * {@link ViewStructure#setPendingCredentialRequest(GetCredentialRequest, OutcomeReceiver)} */ @FlaggedApi(FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) public void clearCredentialManagerRequest() {} diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 15b9b788bca9..3685bbabf4d3 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -1021,6 +1021,10 @@ public final class TransitionInfo implements Parcelable { sb.append(" component="); sb.append(mActivityComponent.flattenToShortString()); } + if (mTaskInfo != null) { + sb.append(" taskParent="); + sb.append(mTaskInfo.parentTaskId); + } sb.append('}'); return sb.toString(); } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 76e71380017c..a0dc94f22c31 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -93,6 +93,7 @@ cc_library_shared_for_libandroid_runtime { shared_libs: [ "libbase", "libcutils", + "libtracing_perfetto", "libharfbuzz_ng", "liblog", "libminikin", @@ -358,6 +359,7 @@ cc_library_shared_for_libandroid_runtime { "libimage_io", "libultrahdr", "libperfetto_c", + "libtracing_perfetto", ], export_shared_lib_headers: [ // our headers include libnativewindow's public headers diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp index ffacd9c8a95b..b579daf505e7 100644 --- a/core/jni/android_os_Trace.cpp +++ b/core/jni/android_os_Trace.cpp @@ -14,11 +14,11 @@ * limitations under the License. */ +#include <cutils/compiler.h> #include <jni.h> - -#include <cutils/trace.h> #include <log/log.h> #include <nativehelper/JNIHelp.h> +#include <tracing_perfetto.h> #include <array> @@ -59,33 +59,30 @@ inline static void withString(JNIEnv* env, jstring jstr, F callback) { static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass, jlong tag, jstring nameStr, jlong value) { - withString(env, nameStr, [tag, value](const char* str) { - atrace_int64(tag, str, value); - }); + withString(env, nameStr, + [tag, value](const char* str) { tracing_perfetto::traceCounter(tag, str, value); }); } static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass, jlong tag, jstring nameStr) { - withString(env, nameStr, [tag](const char* str) { - atrace_begin(tag, str); - }); + withString(env, nameStr, [tag](const char* str) { tracing_perfetto::traceBegin(tag, str); }); } static void android_os_Trace_nativeTraceEnd(JNIEnv*, jclass, jlong tag) { - atrace_end(tag); + tracing_perfetto::traceEnd(tag); } static void android_os_Trace_nativeAsyncTraceBegin(JNIEnv* env, jclass, jlong tag, jstring nameStr, jint cookie) { withString(env, nameStr, [tag, cookie](const char* str) { - atrace_async_begin(tag, str, cookie); + tracing_perfetto::traceAsyncBegin(tag, str, cookie); }); } static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass, jlong tag, jstring nameStr, jint cookie) { withString(env, nameStr, [tag, cookie](const char* str) { - atrace_async_end(tag, str, cookie); + tracing_perfetto::traceAsyncEnd(tag, str, cookie); }); } @@ -93,7 +90,7 @@ static void android_os_Trace_nativeAsyncTraceForTrackBegin(JNIEnv* env, jclass, jlong tag, jstring trackStr, jstring nameStr, jint cookie) { withString(env, trackStr, [env, tag, nameStr, cookie](const char* track) { withString(env, nameStr, [tag, track, cookie](const char* name) { - atrace_async_for_track_begin(tag, track, name, cookie); + tracing_perfetto::traceAsyncBeginForTrack(tag, name, track, cookie); }); }); } @@ -101,77 +98,66 @@ static void android_os_Trace_nativeAsyncTraceForTrackBegin(JNIEnv* env, jclass, static void android_os_Trace_nativeAsyncTraceForTrackEnd(JNIEnv* env, jclass, jlong tag, jstring trackStr, jint cookie) { withString(env, trackStr, [tag, cookie](const char* track) { - atrace_async_for_track_end(tag, track, cookie); + tracing_perfetto::traceAsyncEndForTrack(tag, track, cookie); }); } static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) { - atrace_update_tags(); + // no-op } static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) { - atrace_set_tracing_enabled(enabled); + // no-op } static void android_os_Trace_nativeInstant(JNIEnv* env, jclass, jlong tag, jstring nameStr) { - withString(env, nameStr, [tag](const char* str) { - atrace_instant(tag, str); - }); + withString(env, nameStr, [tag](const char* str) { tracing_perfetto::traceInstant(tag, str); }); } static void android_os_Trace_nativeInstantForTrack(JNIEnv* env, jclass, jlong tag, jstring trackStr, jstring nameStr) { withString(env, trackStr, [env, tag, nameStr](const char* track) { withString(env, nameStr, [tag, track](const char* name) { - atrace_instant_for_track(tag, track, name); + tracing_perfetto::traceInstantForTrack(tag, track, name); }); }); } +static jlong android_os_Trace_nativeGetEnabledTags(JNIEnv* env) { + return tracing_perfetto::getEnabledCategories(); +} + +static void android_os_Trace_nativeRegisterWithPerfetto(JNIEnv* env) { + tracing_perfetto::registerWithPerfetto(); +} + static const JNINativeMethod gTraceMethods[] = { - /* name, signature, funcPtr */ - { "nativeSetAppTracingAllowed", - "(Z)V", - (void*)android_os_Trace_nativeSetAppTracingAllowed }, - { "nativeSetTracingEnabled", - "(Z)V", - (void*)android_os_Trace_nativeSetTracingEnabled }, - - // ----------- @FastNative ---------------- - - { "nativeTraceCounter", - "(JLjava/lang/String;J)V", - (void*)android_os_Trace_nativeTraceCounter }, - { "nativeTraceBegin", - "(JLjava/lang/String;)V", - (void*)android_os_Trace_nativeTraceBegin }, - { "nativeTraceEnd", - "(J)V", - (void*)android_os_Trace_nativeTraceEnd }, - { "nativeAsyncTraceBegin", - "(JLjava/lang/String;I)V", - (void*)android_os_Trace_nativeAsyncTraceBegin }, - { "nativeAsyncTraceEnd", - "(JLjava/lang/String;I)V", - (void*)android_os_Trace_nativeAsyncTraceEnd }, - { "nativeAsyncTraceForTrackBegin", - "(JLjava/lang/String;Ljava/lang/String;I)V", - (void*)android_os_Trace_nativeAsyncTraceForTrackBegin }, - { "nativeAsyncTraceForTrackEnd", - "(JLjava/lang/String;I)V", - (void*)android_os_Trace_nativeAsyncTraceForTrackEnd }, - { "nativeInstant", - "(JLjava/lang/String;)V", - (void*)android_os_Trace_nativeInstant }, - { "nativeInstantForTrack", - "(JLjava/lang/String;Ljava/lang/String;)V", - (void*)android_os_Trace_nativeInstantForTrack }, - - // ----------- @CriticalNative ---------------- - { "nativeGetEnabledTags", - "()J", - (void*)atrace_get_enabled_tags }, + /* name, signature, funcPtr */ + {"nativeSetAppTracingAllowed", "(Z)V", (void*)android_os_Trace_nativeSetAppTracingAllowed}, + {"nativeSetTracingEnabled", "(Z)V", (void*)android_os_Trace_nativeSetTracingEnabled}, + + // ----------- @FastNative ---------------- + + {"nativeTraceCounter", "(JLjava/lang/String;J)V", + (void*)android_os_Trace_nativeTraceCounter}, + {"nativeTraceBegin", "(JLjava/lang/String;)V", (void*)android_os_Trace_nativeTraceBegin}, + {"nativeTraceEnd", "(J)V", (void*)android_os_Trace_nativeTraceEnd}, + {"nativeAsyncTraceBegin", "(JLjava/lang/String;I)V", + (void*)android_os_Trace_nativeAsyncTraceBegin}, + {"nativeAsyncTraceEnd", "(JLjava/lang/String;I)V", + (void*)android_os_Trace_nativeAsyncTraceEnd}, + {"nativeAsyncTraceForTrackBegin", "(JLjava/lang/String;Ljava/lang/String;I)V", + (void*)android_os_Trace_nativeAsyncTraceForTrackBegin}, + {"nativeAsyncTraceForTrackEnd", "(JLjava/lang/String;I)V", + (void*)android_os_Trace_nativeAsyncTraceForTrackEnd}, + {"nativeInstant", "(JLjava/lang/String;)V", (void*)android_os_Trace_nativeInstant}, + {"nativeInstantForTrack", "(JLjava/lang/String;Ljava/lang/String;)V", + (void*)android_os_Trace_nativeInstantForTrack}, + {"nativeRegisterWithPerfetto", "()V", (void*)android_os_Trace_nativeRegisterWithPerfetto}, + + // ----------- @CriticalNative ---------------- + {"nativeGetEnabledTags", "()J", (void*)android_os_Trace_nativeGetEnabledTags}, }; int register_android_os_Trace(JNIEnv* env) { diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 73877b8cf0c0..09d23fa82da1 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Jy kan boodskappe stuur en ontvang sonder ’n selfoon- of wi-fi-netwerk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index e513a07722ed..6de4a20252f0 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"ያለ ሞባይል ወይም የWi-Fi አውታረ መረብ መልዕክቶችን መላክ እና መቀበል ይችላሉ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"መልዕክቶች ይክፈቱ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"እንዴት እንደሚሠራ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 95fa5db05b64..3e98391416e9 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -2397,4 +2397,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"يمكنك إرسال الرسائل واستلامها بدون شبكة الجوّال أو شبكة Wi-Fi."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"فتح تطبيق \"الرسائل\""</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"طريقة العمل"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 9fb71492a79e..0e3773b06fdd 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"আপুনি ম’বাইল বা ৱাই-ফাই নেটৱৰ্কৰ জৰিয়তে পাঠ বাৰ্তা পঠিয়াব বা লাভ কৰিব পাৰে"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খোলক"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ই কেনেকৈ কাম কৰে"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 5c3c652bb629..98ec79861393 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Haqqında"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index bda2a5542088..04b5a3869ac7 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete da šaljete i primate poruke bez mobilne ili WiFi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 38b8e4354445..bb1b2d3973cc 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можаце адпраўляць і атрымліваць паведамленні без доступу да мабільнай сеткі або Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Адкрыць Паведамленні"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як гэта працуе"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 77933bae46f4..b03faf7072e4 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да изпращате и получавате съобщения без мобилна или Wi-Fi мрежа"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отваряне на Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Начин на работа"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index b7c7399afbb5..f637f5af8bf4 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"আপনি কোনও মেবাইল বা ওয়াই-ফাই নেটওয়ার্ক ছাড়াই মেসেজ পাঠাতে ও পেতে পারবেন"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খুলুন"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"এটি কীভাবে কাজ করে"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 90af6303b179..9700fe150d80 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1989,7 +1989,7 @@ <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitan slučaj"</string> <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Postavite zaključavanje ekrana"</string> <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Postavite zaključavanje ekrana"</string> - <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Da koristite privatni prostor, postavite zaklj. ekr. na ur."</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Za upotrebu privatn. prostora postavite zaklj. ekr. na uređ."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Nedostupno: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne ili WiFi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index f20d334f4a1f..e56b8bcf02b3 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Com funciona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d60389047e08..0c168e59eeb3 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Zprávy můžete odesílat a přijímat bez mobilní sítě nebo sítě Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to funguje"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index fc73fa71b82d..aa037c7983d2 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og modtage beskeder uden et mobil- eller Wi-Fi-netværk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 9faf515f9d44..9f1af2400d98 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"So funktionierts"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 983775e675cf..bc4d92914b26 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Μπορείτε να στέλνετε και να λαμβάνετε μηνύματα χωρίς δίκτυο κινητής τηλεφωνίας ή Wi-Fi."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Άνοιγμα Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Πώς λειτουργεί"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 7dd6a5c668df..969bbbfb5630 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 58c015b5ddd9..4148ad741982 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -2393,4 +2393,5 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> + <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string> </resources> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index fd0cdd520a8f..0a890b21f7a2 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 3dfadb2d3771..5ca52366355c 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 6c6f1c98fbaa..edba90125e3f 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -2393,4 +2393,5 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string> + <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index d7af663c8b98..65e53dbd9dac 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1987,9 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"¿Reanudar apps de trabajo?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reanudar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergencia"</string> - <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Configura bloqueo de pantalla"</string> - <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Conf. un bloqueo de pantalla"</string> - <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar esp. privado, configura un bloqueo de pantalla"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Configurar bloqueo de pantalla"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Configurar bloqueo de pantalla"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar tu espacio privado, configura un bloqueo de pantalla"</string> <string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string> @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes incluso si no tienes conexión a una red móvil o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensajes"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 02e29c0c0e5a..a0e4a512cc6a 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 2fe8731d9cda..d6553abb8bef 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Tööpõhimõtted"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index c28191a6d36c..bdf946e8074e 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Mezuak bidal eta jaso ditzakezu sare mugikorrik edo wifi-sarerik gabe"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 7155bf4241e6..827ddaab9e4d 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"میتوانید بدون شبکه تلفن همراه یا Wi-Fi پیام ارسال و دریافت کنید"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیامها»"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"روش کار"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 11d5604bae58..dca0e26e2615 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Voit lähettää ja vastaanottaa viestejä ilman mobiili‑ tai Wi-Fi-verkkoa"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index bec2f1fdcbe3..dc030bbac03c 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index d76b1ef70716..31754e40c1d5 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 6b7507a65081..1b99b4b89510 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona?"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 9f4919dfadde..57c09da6a8ce 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"તમે મોબાઇલ અથવા વાઇ-ફાઇ નેટવર્ક વિના મેસેજ મોકલી અને પ્રાપ્ત કરી શકો છો"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ખોલો"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"તેની કામ કરવાની રીત"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 6e91d3a2de8d..6bba6b00765c 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"मोबाइल या वाई-फ़ाई नेटवर्क के बिना भी मैसेज भेजे और पाए जा सकते हैं"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ऐप्लिकेशन खोलें"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यह सेटिंग कैसे काम करती है"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 4682f8477df9..75ca762ddf03 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne mreže ili Wi-Fi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index bde17d0e3052..c825bd728ae4 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hogyan működik?"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 8caacd3709c2..1745f27219a1 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Դուք կարող եք ուղարկել և ստանալ հաղորդագրություններ՝ առանց բջջային կամ Wi-Fi կապի"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ինչպես է դա աշխատում"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 2020a75dd578..af1ec297802a 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara kerjanya"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index f25a4b430ae7..d921828ffe2b 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Þú getur sent og móttekið skilaboð án tengingar við farsímakerfi eða Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 06fa36f60e0b..86640f8e23b0 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Puoi inviare e ricevere messaggi senza una rete mobile o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 1a609b9aa717..d0ad38c33d60 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"אפשר לשלוח ולקבל הודעות ללא רשת סלולרית או רשת Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"לפתיחת Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"איך זה עובד"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 688450e412fb..f8990841849d 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -2393,4 +2393,5 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"モバイル ネットワークや Wi-Fi ネットワークを使わずにメッセージを送受信できます"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"メッセージ アプリを開く"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"仕組み"</string> + <string name="unarchival_session_app_label" msgid="6811856981546348205">"保留中..."</string> </resources> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index a1e489a0dc62..e4e60428541b 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები მობილური ან Wi-Fi ქსელის გარეშე"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"მუშაობის პრინციპი"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 0bef068286e1..e9d00c787285 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Мобильдік не Wi-Fi желісіне қосылмастан хабар жібере аласыз және ала аласыз."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages қолданбасын ашу"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 1f805bfd83d5..118e6e62ceeb 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"អ្នកអាចផ្ញើ និងទទួលសារដោយមិនប្រើបណ្តាញទូរសព្ទចល័ត ឬ Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"បើកកម្មវិធី Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"របៀបដែលវាដំណើរការ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index c3fab520a924..4331819039a0 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"ನೀವು ಮೊಬೈಲ್ ಅಥವಾ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಇಲ್ಲದೆಯೇ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಮತ್ತು ಸ್ವೀಕರಿಸಬಹುದು"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ಅನ್ನು ತೆರೆಯಿರಿ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 9b7556ab607b..8975b4327361 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"모바일 또는 Wi-Fi 네트워크 없이 메시지를 주고 받을 수 있습니다"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"메시지 열기"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"작동 방식"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 71c128d013ef..c8b5981671ba 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Сиз мобилдик же Wi-Fi тармагы жок эле билдирүүлөрдү жөнөтүп, ала аласыз"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Жазышуулар колдонмосун ачуу"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ал кантип иштейт"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 8c19e7b785b3..06a572df4080 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"ທ່ານສາມາດສົ່ງ ແລະ ຮັບຂໍ້ຄວາມໂດຍບໍ່ຕ້ອງໃຊ້ເຄືອຂ່າຍມືຖື ຫຼື Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"ເປີດ Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ມັນເຮັດວຽກແນວໃດ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index bf227d04961e..98bcca9bf9db 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Galite siųsti ir gauti pranešimus be mobiliojo ryšio ar „Wi-Fi“ tinklo"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index a575e2a527bb..6ed95d34f4d7 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Varat sūtīt un saņemt ziņojumus bez mobilā vai Wi-Fi tīkla."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 0ff49ed82943..3a60709fac15 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Може да испраќате и примате пораки без мобилна или Wi-Fi мрежа"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отворете ја Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Дознајте како функционира"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index a23bcfab4dae..55633dc442b8 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ഇത് പ്രവർത്തിക്കുന്നത് എങ്ങനെയാണ്"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index c7f85246cb8f..a9e1c1493044 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Та мобайл эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах боломжтой"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Энэ хэрхэн ажилладаг вэ?"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 0c625c7399af..c20bdb050be3 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"तुम्ही मोबाइल किंवा वाय-फाय नेटवर्कशिवाय मेसेज पाठवू आणि मिळवू शकता"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages उघडा"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ते कसे काम करते"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 9c81b7900403..9048ffc89cea 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda boleh menghantar dan menerima mesej tanpa rangkaian mudah alih atau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara ciri ini berfungsi"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 2d603bc4abe5..32aed951539b 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များကို ပို့နိုင်၊ လက်ခံနိုင်သည်"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"အလုပ်လုပ်ပုံ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 2ea9d4031b71..41e217d3dd01 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og motta meldinger uten mobil- eller wifi-nettverk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index b7996f7938ee..6f139cd0f3a0 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"तपाईं मोबाइल वा Wi-Fi नेटवर्कविनै म्यासेज पठाउन र प्राप्त गर्न सक्नुहुन्छ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages खोल्नुहोस्"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यसले काम गर्ने तरिका"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 8b60b530677f..b17d7a8acca0 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe het werkt"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index b3e62aaf8d9b..ade7c82648a4 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"ଏକ ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ବିନା ଆପଣ ମେସେଜ ପଠାଇପାରିବେ ଏବଂ ପାଇପାରିବେ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ଖୋଲନ୍ତୁ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ଏହା କିପରି କାମ କରେ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 283813d17e9d..439190b76a93 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -2393,4 +2393,5 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"ਤੁਸੀਂ ਮੋਬਾਈਲ ਜਾਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ਐਪ ਖੋਲ੍ਹੋ"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string> + <string name="unarchival_session_app_label" msgid="6811856981546348205">"ਵਿਚਾਰ-ਅਧੀਨ..."</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 5e0e67020e63..61814b7969bd 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Możesz wymieniać wiadomości bez dostępu do sieci komórkowej lub Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 3ccb86a918cc..cf1a200b91e8 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 00d368da768e..9f6b733b92a7 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Pode enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a app Mensagens"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 3ccb86a918cc..cf1a200b91e8 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 049ef0ce0bd9..38b6e53bdcab 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Poți să trimiți și să primești mesaje fără o rețea mobilă sau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cum funcționează"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 8abfb65ce224..866f316d8ab0 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можете отправлять и получать сообщения без доступа к мобильной сети или Wi-Fi."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Узнать принцип работы"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 5078ee0f2d1d..3668de1ea039 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"ඔබට ජංගම හෝ Wi-Fi ජාලයක් නොමැතිව පණිවිඩ යැවීමට සහ ලැබීමට හැක"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages විවෘත කරන්න"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"එය ක්රියා කරන ආකාරය"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index a10cc4860f70..1c642f62396d 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ako to funguje"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 70eb803b1511..0e72e0cd595b 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Sporočila SMS lahko pošiljate in prejemate brez mobilnega omrežja ali omrežja Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 61d815de10e7..caa34099d882 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Mund të dërgosh dhe të marrësh mesazhe pa një rrjet celular apo rrjet Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Hap \"Mesazhet\""</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Si funksionon"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index f0c8a209ebd7..75439d7c2fec 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -2394,4 +2394,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да шаљете и примате поруке без мобилне или WiFi мреже"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отвори Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Принцип рада"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 79cdce4cf39b..be777f098df2 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan skicka och ta emot meddelanden utan mobil- eller wifi-nätverk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 4111f3a12b12..65c63212c1fd 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Unaweza kutuma na kupokea ujumbe bila mtandao wa simu au Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 3d339239a1f5..b3d16d76c40d 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"மொபைல்/வைஃபை நெட்வொர்க் இல்லாமல் நீங்கள் மெசேஜ்களை அனுப்பலாம் பெறலாம்"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ஆப்ஸைத் திறக்கவும்"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"இது செயல்படும் விதம்"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 5887cd34646a..c8778a423023 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"మీరు మొబైల్ లేదా Wi-Fi నెట్వర్క్ లేకుండా మెసేజ్లను పంపవచ్చు, స్వీకరించవచ్చు"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messagesను తెరవండి"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ఇది ఎలా పని చేస్తుంది"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 51ff5ae7e662..8a056893adb3 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"คุณรับส่งข้อความผ่านดาวเทียมได้โดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"วิธีการทำงาน"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 43ce6bcd28d3..3b3797a58ce1 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Puwede kang magpadala at tumanggap ng mga mensahe nang walang mobile o Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 1df9b8d4d56a..70ea4149cea6 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil veya kablosuz ağa bağlı olmadan mesaj alıp gönderebilirsiniz"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 903261c18058..9c7c8efe332b 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -2395,4 +2395,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Ви можете надсилати й отримувати повідомлення, не використовуючи Wi-Fi або мобільну мережу"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Відкрийте Повідомлення"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як це працює"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index bed6cf872a45..e60299f0dbfd 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"آپ موبائل یا Wi-Fi نیٹ ورک کے بغیر پیغامات بھیج اور موصول کر سکتے ہیں"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"پیغامات ایپ کو کھولیں"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"اس کے کام کرنے کا طریقہ"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 131689883154..58e576b732bd 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil yoki Wi-Fi tarmoqsiz xabarlarni yuborishingiz va qabul qilishingiz mumkin"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 4587a625cb13..a8d8188c7015 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Bạn có thể gửi và nhận tin nhắn mà không cần có mạng di động hoặc mạng Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cách hoạt động"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index c58c0dee0a05..b0f052ee53ec 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"运作方式"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index b72569a90909..0bf9079bd7f2 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"你可在沒有流動/Wi-Fi 網絡的情況下收發訊息"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 3a7de66134ec..c15262d6ff7b 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index c9dd914de07a..91050bf5ba1e 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -2393,4 +2393,6 @@ <string name="satellite_notification_summary" msgid="5207364139430767162">"Ungathumela futhi wamukele imilayezo ngaphandle kwenethiwekhi yeselula noma ye-Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string> <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string> + <!-- no translation found for unarchival_session_app_label (6811856981546348205) --> + <skip /> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a0cb70518866..f59c0993c34f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3132,6 +3132,10 @@ --> <bool name="config_enableWifiDisplay">false</bool> + <!-- Whether the default HDR conversion mode should be passthrough instead of system. + --> + <bool name="config_enableDefaultHdrConversionPassthrough">false</bool> + <!-- When true, local displays that do not contain any of their own content will automatically mirror the content of the default display. --> <bool name="config_localDisplaysMirrorContent">true</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 4b716543c726..c603fa78b08e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -348,6 +348,7 @@ <java-symbol type="bool" name="config_enableScreenshotChord" /> <java-symbol type="bool" name="config_fold_lock_behavior" /> <java-symbol type="bool" name="config_enableWifiDisplay" /> + <java-symbol type="bool" name="config_enableDefaultHdrConversionPassthrough" /> <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" /> <java-symbol type="bool" name="config_useDevInputEventForAudioJack" /> <java-symbol type="bool" name="config_safe_media_volume_enabled" /> diff --git a/core/tests/coretests/src/android/app/assist/AssistStructureTest.java b/core/tests/coretests/src/android/app/assist/AssistStructureTest.java index abeb08caf23d..1f2788c4b11b 100644 --- a/core/tests/coretests/src/android/app/assist/AssistStructureTest.java +++ b/core/tests/coretests/src/android/app/assist/AssistStructureTest.java @@ -266,8 +266,8 @@ public class AssistStructureTest { assertThat(view.getViewRootImpl()).isNotNull(); ViewNodeBuilder viewStructure = new ViewNodeBuilder(); viewStructure.setAutofillId(view.getAutofillId()); - viewStructure.setCredentialManagerRequest(view.getCredentialManagerRequest(), - view.getCredentialManagerCallback()); + viewStructure.setPendingCredentialRequest(view.getPendingCredentialRequest(), + view.getPendingCredentialCallback()); view.onProvideAutofillStructure(viewStructure, /* flags= */ 0); ViewNodeParcelable viewNodeParcelable = new ViewNodeParcelable(viewStructure.getViewNode()); @@ -289,17 +289,20 @@ public class AssistStructureTest { assertThat(view.getViewRootImpl()).isNotNull(); ViewNodeBuilder viewStructure = new ViewNodeBuilder(); - viewStructure.setCredentialManagerRequest(view.getCredentialManagerRequest(), - view.getCredentialManagerCallback()); + if (view.getPendingCredentialRequest() != null + && view.getPendingCredentialCallback() != null) { + viewStructure.setPendingCredentialRequest(view.getPendingCredentialRequest(), + view.getPendingCredentialCallback()); + } - assertEquals(viewStructure.getCredentialManagerRequest(), GET_CREDENTIAL_REQUEST); - assertEquals(viewStructure.getCredentialManagerCallback(), + assertEquals(viewStructure.getPendingCredentialRequest(), GET_CREDENTIAL_REQUEST); + assertEquals(viewStructure.getPendingCredentialCallback(), GET_CREDENTIAL_REQUEST_CALLBACK); viewStructure.clearCredentialManagerRequest(); - assertNull(viewStructure.getCredentialManagerRequest()); - assertNull(viewStructure.getCredentialManagerCallback()); + assertNull(viewStructure.getPendingCredentialRequest()); + assertNull(viewStructure.getPendingCredentialCallback()); } @Test @@ -386,14 +389,14 @@ public class AssistStructureTest { EditText view = new EditText(mContext); view.setText("Big Hint in Little View"); view.setAutofillHints(BIG_STRING); - view.setCredentialManagerRequest(GET_CREDENTIAL_REQUEST, GET_CREDENTIAL_REQUEST_CALLBACK); + view.setPendingCredentialRequest(GET_CREDENTIAL_REQUEST, GET_CREDENTIAL_REQUEST_CALLBACK); return view; } private EditText newCredentialView() { EditText view = new EditText(mContext); view.setText("Credential Request"); - view.setCredentialManagerRequest(GET_CREDENTIAL_REQUEST, GET_CREDENTIAL_REQUEST_CALLBACK); + view.setPendingCredentialRequest(GET_CREDENTIAL_REQUEST, GET_CREDENTIAL_REQUEST_CALLBACK); return view; } @@ -421,8 +424,8 @@ public class AssistStructureTest { assertThat(view.getAutofillId()).isNotNull(); assertThat(view.getText().toString()).isEqualTo("Big Hint in Little View"); - assertThat(view.getCredentialManagerRequest()).isEqualTo(GET_CREDENTIAL_REQUEST); - assertThat(view.getCredentialManagerCallback()).isEqualTo(GET_CREDENTIAL_REQUEST_CALLBACK); + assertThat(view.getPendingCredentialRequest()).isEqualTo(GET_CREDENTIAL_REQUEST); + assertThat(view.getPendingCredentialCallback()).isEqualTo(GET_CREDENTIAL_REQUEST_CALLBACK); } /** diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java index e118c98dd4da..2905a5aa8c65 100644 --- a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java +++ b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java @@ -31,6 +31,7 @@ import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.test.AndroidTestCase; import android.util.Log; +import android.util.Printer; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; @@ -46,12 +47,15 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Vector; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Phaser; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @RunWith(AndroidJUnit4.class) @SmallTest @@ -403,4 +407,138 @@ public class SQLiteDatabaseTest { } assertFalse(allowed); } + + /** Dumpsys information about a single database. */ + + /** + * Collect and parse dumpsys output. This is not a full parser. It is only enough to support + * the unit tests. + */ + private static class Dumpsys { + // Regular expressions for parsing the output. Reportedly, regular expressions are + // expensive, so these are created only if a dumpsys object is created. + private static final Object sLock = new Object(); + static Pattern mPool; + static Pattern mConnection; + static Pattern mEntry; + static Pattern mSingleWord; + static Pattern mNone; + + // The raw strings read from dumpsys. Once loaded, this list never changes. + final ArrayList<String> mRaw = new ArrayList<>(); + + // Parsed dumpsys. This contains only the bits that are being tested. + static class Connection { + ArrayList<String> mRecent = new ArrayList<>(); + ArrayList<String> mLong = new ArrayList<>(); + } + static class Database { + String mPath; + ArrayList<Connection> mConnection = new ArrayList<>(); + } + ArrayList<Database> mDatabase; + ArrayList<String> mConcurrent; + + Dumpsys() { + SQLiteDebug.dump( + new Printer() { public void println(String x) { mRaw.add(x); } }, + new String[0]); + parse(); + } + + /** Parse the raw text. Return true if no errors were detected. */ + boolean parse() { + initialize(); + + // Reset the parsed information. This method may be called repeatedly. + mDatabase = new ArrayList<>(); + mConcurrent = new ArrayList<>(); + + Database current = null; + Connection connection = null; + Matcher matcher; + for (int i = 0; i < mRaw.size(); i++) { + final String line = mRaw.get(i); + matcher = mPool.matcher(line); + if (matcher.lookingAt()) { + current = new Database(); + mDatabase.add(current); + current.mPath = matcher.group(1); + continue; + } + matcher = mConnection.matcher(line); + if (matcher.lookingAt()) { + connection = new Connection(); + current.mConnection.add(connection); + continue; + } + + if (line.contains("Most recently executed operations")) { + i += readTable(connection.mRecent, i, mEntry); + continue; + } + + if (line.contains("Operations exceeding 2000ms")) { + i += readTable(connection.mLong, i, mEntry); + continue; + } + if (line.contains("Concurrently opened database files")) { + i += readTable(mConcurrent, i, mSingleWord); + continue; + } + } + return true; + } + + /** + * Read a series of lines following a header. Return the number of lines read. The input + * line number is the number of the header. + */ + private int readTable(List<String> s, int header, Pattern p) { + // Special case: if the first line is "<none>" then there are no more lines to the + // table. + if (lookingAt(header+1, mNone)) return 1; + + int i; + for (i = header + 1; i < mRaw.size() && lookingAt(i, p); i++) { + s.add(mRaw.get(i).trim()); + } + return i - header; + } + + /** Return true if the n'th raw line matches the pattern. */ + boolean lookingAt(int n, Pattern p) { + return p.matcher(mRaw.get(n)).lookingAt(); + } + + /** Compile the regular expressions the first time. */ + private static void initialize() { + synchronized (sLock) { + if (mPool != null) return; + mPool = Pattern.compile("Connection pool for (\\S+):"); + mConnection = Pattern.compile("\\s+Connection #(\\d+):"); + mEntry = Pattern.compile("\\s+(\\d+): "); + mSingleWord = Pattern.compile(" (\\S+)$"); + mNone = Pattern.compile("\\s+<none>$"); + } + } + } + + @Test + public void testDumpsys() throws Exception { + Dumpsys dumpsys = new Dumpsys(); + + assertEquals(1, dumpsys.mDatabase.size()); + // Note: cannot test mConcurrent because that attribute is not hermitic with respect to + // the tests. + + Dumpsys.Database db = dumpsys.mDatabase.get(0); + + // Work with normalized paths. + String wantPath = mDatabaseFile.toPath().toRealPath().toString(); + String realPath = new File(db.mPath).toPath().toRealPath().toString(); + assertEquals(wantPath, realPath); + + assertEquals(1, db.mConnection.size()); + } } diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java index 936f4d7d5152..61e05dac2371 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java @@ -291,6 +291,17 @@ public class InsetsSourceTest { } @Test + public void testCalculateBoundingRects_noBoundingRectsAndFrameNotAtOrigin_createsSingleRect() { + mSource.setFrame(new Rect(100, 100, 1200, 200)); + mSource.setBoundingRects(null); + + final Rect[] rects = mSource.calculateBoundingRects(new Rect(100, 100, 1100, 1100), false); + + assertEquals(1, rects.length); + assertEquals(new Rect(0, 0, 1000, 100), rects[0]); + } + + @Test public void testCalculateBoundingRects_noBoundingRectsAndLargerFrame_singleRectFitsRelFrame() { mSource.setFrame(new Rect(0, 0, 1000, 100)); mSource.setBoundingRects(null); diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateInfoTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateInfoTest.java index dcef0a7c316d..76772b7a528b 100644 --- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateInfoTest.java +++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateInfoTest.java @@ -20,16 +20,20 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import android.os.Parcel; import androidx.test.filters.SmallTest; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.List; + /** * Unit tests for {@link DeviceStateInfo}. * <p/> @@ -38,11 +42,20 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) @SmallTest public final class DeviceStateInfoTest { + + private static final DeviceState DEVICE_STATE_0 = new DeviceState( + new DeviceState.Configuration.Builder(0, "STATE_0").build()); + private static final DeviceState DEVICE_STATE_1 = new DeviceState( + new DeviceState.Configuration.Builder(1, "STATE_1").build()); + private static final DeviceState DEVICE_STATE_2 = new DeviceState( + new DeviceState.Configuration.Builder(2, "STATE_2").build()); + @Test public void create() { - final int[] supportedStates = new int[] { 0, 1, 2 }; - final int baseState = 0; - final int currentState = 2; + final List<DeviceState> supportedStates = List.of(DEVICE_STATE_0, DEVICE_STATE_1, + DEVICE_STATE_2); + final DeviceState baseState = DEVICE_STATE_0; + final DeviceState currentState = DEVICE_STATE_2; final DeviceStateInfo info = new DeviceStateInfo(supportedStates, baseState, currentState); assertNotNull(info.supportedStates); @@ -53,27 +66,30 @@ public final class DeviceStateInfoTest { @Test public void equals() { - final int[] supportedStates = new int[] { 0, 1, 2 }; - final int baseState = 0; - final int currentState = 2; + final List<DeviceState> supportedStates = List.of(DEVICE_STATE_0, DEVICE_STATE_1, + DEVICE_STATE_2); + final DeviceState baseState = DEVICE_STATE_0; + final DeviceState currentState = DEVICE_STATE_2; final DeviceStateInfo info = new DeviceStateInfo(supportedStates, baseState, currentState); - assertTrue(info.equals(info)); + Assert.assertEquals(info, info); final DeviceStateInfo sameInfo = new DeviceStateInfo(supportedStates, baseState, currentState); - assertTrue(info.equals(sameInfo)); + Assert.assertEquals(info, sameInfo); - final DeviceStateInfo differentInfo = new DeviceStateInfo(new int[]{ 0, 2}, baseState, + final DeviceStateInfo differentInfo = new DeviceStateInfo( + List.of(DEVICE_STATE_0, DEVICE_STATE_2), baseState, currentState); - assertFalse(info.equals(differentInfo)); + assertNotEquals(info, differentInfo); } @Test public void diff_sameObject() { - final int[] supportedStates = new int[] { 0, 1, 2 }; - final int baseState = 0; - final int currentState = 2; + final List<DeviceState> supportedStates = List.of(DEVICE_STATE_0, DEVICE_STATE_1, + DEVICE_STATE_2); + final DeviceState baseState = DEVICE_STATE_0; + final DeviceState currentState = DEVICE_STATE_2; final DeviceStateInfo info = new DeviceStateInfo(supportedStates, baseState, currentState); assertEquals(0, info.diff(info)); @@ -81,8 +97,10 @@ public final class DeviceStateInfoTest { @Test public void diff_differentSupportedStates() { - final DeviceStateInfo info = new DeviceStateInfo(new int[] { 1 }, 0, 0); - final DeviceStateInfo otherInfo = new DeviceStateInfo(new int[] { 2 }, 0, 0); + final DeviceStateInfo info = new DeviceStateInfo(List.of(DEVICE_STATE_1), DEVICE_STATE_0, + DEVICE_STATE_0); + final DeviceStateInfo otherInfo = new DeviceStateInfo(List.of(DEVICE_STATE_2), + DEVICE_STATE_0, DEVICE_STATE_0); final int diff = info.diff(otherInfo); assertTrue((diff & DeviceStateInfo.CHANGED_SUPPORTED_STATES) > 0); assertFalse((diff & DeviceStateInfo.CHANGED_BASE_STATE) > 0); @@ -91,8 +109,10 @@ public final class DeviceStateInfoTest { @Test public void diff_differentNonOverrideState() { - final DeviceStateInfo info = new DeviceStateInfo(new int[] { 1 }, 1, 0); - final DeviceStateInfo otherInfo = new DeviceStateInfo(new int[] { 1 }, 2, 0); + final DeviceStateInfo info = new DeviceStateInfo(List.of(DEVICE_STATE_1), DEVICE_STATE_1, + DEVICE_STATE_0); + final DeviceStateInfo otherInfo = new DeviceStateInfo(List.of(DEVICE_STATE_1), + DEVICE_STATE_2, DEVICE_STATE_0); final int diff = info.diff(otherInfo); assertFalse((diff & DeviceStateInfo.CHANGED_SUPPORTED_STATES) > 0); assertTrue((diff & DeviceStateInfo.CHANGED_BASE_STATE) > 0); @@ -101,8 +121,10 @@ public final class DeviceStateInfoTest { @Test public void diff_differentState() { - final DeviceStateInfo info = new DeviceStateInfo(new int[] { 1 }, 0, 1); - final DeviceStateInfo otherInfo = new DeviceStateInfo(new int[] { 1 }, 0, 2); + final DeviceStateInfo info = new DeviceStateInfo(List.of(DEVICE_STATE_1), DEVICE_STATE_0, + DEVICE_STATE_1); + final DeviceStateInfo otherInfo = new DeviceStateInfo(List.of(DEVICE_STATE_1), + DEVICE_STATE_0, DEVICE_STATE_2); final int diff = info.diff(otherInfo); assertFalse((diff & DeviceStateInfo.CHANGED_SUPPORTED_STATES) > 0); assertFalse((diff & DeviceStateInfo.CHANGED_BASE_STATE) > 0); @@ -111,9 +133,10 @@ public final class DeviceStateInfoTest { @Test public void writeToParcel() { - final int[] supportedStates = new int[] { 0, 1, 2 }; - final int nonOverrideState = 0; - final int state = 2; + final List<DeviceState> supportedStates = List.of(DEVICE_STATE_0, DEVICE_STATE_1, + DEVICE_STATE_2); + final DeviceState nonOverrideState = DEVICE_STATE_0; + final DeviceState state = DEVICE_STATE_2; final DeviceStateInfo originalInfo = new DeviceStateInfo(supportedStates, nonOverrideState, state); diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java index 03c38cc137ad..ee238c0a5533 100644 --- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java +++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java @@ -41,6 +41,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -51,8 +52,10 @@ import java.util.Set; @RunWith(JUnit4.class) @SmallTest public final class DeviceStateManagerGlobalTest { - private static final int DEFAULT_DEVICE_STATE = 0; - private static final int OTHER_DEVICE_STATE = 1; + private static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(0 /* identifier */, "" /* name */).build()); + private static final DeviceState OTHER_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(1 /* identifier */, "" /* name */).build()); private TestDeviceStateManagerService mService; private DeviceStateManagerGlobal mDeviceStateManagerGlobal; @@ -76,41 +79,37 @@ public final class DeviceStateManagerGlobalTest { ConcurrentUtils.DIRECT_EXECUTOR); // Verify initial callbacks - verify(callback1).onSupportedStatesChanged(eq(mService.getSupportedStates())); - verify(callback1).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback1).onStateChanged(eq(mService.getMergedState())); - verify(callback2).onSupportedStatesChanged(eq(mService.getSupportedStates())); - verify(callback2).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback2).onStateChanged(eq(mService.getMergedState())); + verify(callback1).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates())); + verify(callback1).onDeviceStateChanged(eq(mService.getMergedState())); + verify(callback2).onDeviceStateChanged(eq(mService.getMergedState())); reset(callback1); reset(callback2); // Change the supported states and verify callback - mService.setSupportedStates(new int[]{ DEFAULT_DEVICE_STATE }); - verify(callback1).onSupportedStatesChanged(eq(mService.getSupportedStates())); - verify(callback2).onSupportedStatesChanged(eq(mService.getSupportedStates())); - mService.setSupportedStates(new int[]{ DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE }); + mService.setSupportedStates(List.of(DEFAULT_DEVICE_STATE)); + verify(callback1).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates())); + verify(callback2).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates())); + mService.setSupportedStates(List.of(DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE)); reset(callback1); reset(callback2); // Change the base state and verify callback mService.setBaseState(OTHER_DEVICE_STATE); - verify(callback1).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback1).onStateChanged(eq(mService.getMergedState())); - verify(callback2).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback2).onStateChanged(eq(mService.getMergedState())); + verify(callback1).onDeviceStateChanged(eq(mService.getMergedState())); + verify(callback2).onDeviceStateChanged(eq(mService.getMergedState())); reset(callback1); reset(callback2); // Change the requested state and verify callback - DeviceStateRequest request = DeviceStateRequest.newBuilder(DEFAULT_DEVICE_STATE).build(); + DeviceStateRequest request = DeviceStateRequest.newBuilder( + DEFAULT_DEVICE_STATE.getIdentifier()).build(); mDeviceStateManagerGlobal.requestState(request, null /* executor */, null /* callback */); - verify(callback1).onStateChanged(eq(mService.getMergedState())); - verify(callback2).onStateChanged(eq(mService.getMergedState())); + verify(callback1).onDeviceStateChanged(eq(mService.getMergedState())); + verify(callback2).onDeviceStateChanged(eq(mService.getMergedState())); } @Test @@ -121,14 +120,13 @@ public final class DeviceStateManagerGlobalTest { ConcurrentUtils.DIRECT_EXECUTOR); // Verify initial callbacks - verify(callback).onSupportedStatesChanged(eq(mService.getSupportedStates())); - verify(callback).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback).onStateChanged(eq(mService.getMergedState())); + verify(callback).onSupportedStatesChanged(eq(mService.getSupportedDeviceStates())); + verify(callback).onDeviceStateChanged(eq(mService.getMergedState())); reset(callback); mDeviceStateManagerGlobal.unregisterDeviceStateCallback(callback); - mService.setSupportedStates(new int[]{OTHER_DEVICE_STATE}); + mService.setSupportedStates(List.of(OTHER_DEVICE_STATE)); mService.setBaseState(OTHER_DEVICE_STATE); verifyZeroInteractions(callback); } @@ -139,18 +137,19 @@ public final class DeviceStateManagerGlobalTest { mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR); - verify(callback).onStateChanged(eq(mService.getBaseState())); + verify(callback).onDeviceStateChanged(eq(mService.getBaseState())); reset(callback); - DeviceStateRequest request = DeviceStateRequest.newBuilder(OTHER_DEVICE_STATE).build(); + DeviceStateRequest request = DeviceStateRequest.newBuilder( + OTHER_DEVICE_STATE.getIdentifier()).build(); mDeviceStateManagerGlobal.requestState(request, null /* executor */, null /* callback */); - verify(callback).onStateChanged(eq(OTHER_DEVICE_STATE)); + verify(callback).onDeviceStateChanged(eq(OTHER_DEVICE_STATE)); reset(callback); mDeviceStateManagerGlobal.cancelStateRequest(); - verify(callback).onStateChanged(eq(mService.getBaseState())); + verify(callback).onDeviceStateChanged(eq(mService.getBaseState())); } @Test @@ -159,22 +158,20 @@ public final class DeviceStateManagerGlobalTest { mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR); - verify(callback).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback).onStateChanged(eq(mService.getBaseState())); + verify(callback).onDeviceStateChanged(eq(mService.getBaseState())); reset(callback); - DeviceStateRequest request = DeviceStateRequest.newBuilder(OTHER_DEVICE_STATE).build(); + DeviceStateRequest request = DeviceStateRequest.newBuilder( + OTHER_DEVICE_STATE.getIdentifier()).build(); mDeviceStateManagerGlobal.requestBaseStateOverride(request, null /* executor */, null /* callback */); - verify(callback).onBaseStateChanged(eq(OTHER_DEVICE_STATE)); - verify(callback).onStateChanged(eq(OTHER_DEVICE_STATE)); + verify(callback).onDeviceStateChanged(eq(OTHER_DEVICE_STATE)); reset(callback); mDeviceStateManagerGlobal.cancelBaseStateOverride(); - verify(callback).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback).onStateChanged(eq(mService.getBaseState())); + verify(callback).onDeviceStateChanged(eq(mService.getBaseState())); } @Test @@ -183,44 +180,43 @@ public final class DeviceStateManagerGlobalTest { mDeviceStateManagerGlobal.registerDeviceStateCallback(callback, ConcurrentUtils.DIRECT_EXECUTOR); - verify(callback).onBaseStateChanged(eq(mService.getBaseState())); - verify(callback).onStateChanged(eq(mService.getBaseState())); + verify(callback).onDeviceStateChanged(eq(mService.getBaseState())); reset(callback); - DeviceStateRequest request = DeviceStateRequest.newBuilder(OTHER_DEVICE_STATE).build(); + DeviceStateRequest request = DeviceStateRequest.newBuilder( + OTHER_DEVICE_STATE.getIdentifier()).build(); mDeviceStateManagerGlobal.requestBaseStateOverride(request, null /* executor */, null /* callback */); - verify(callback).onBaseStateChanged(eq(OTHER_DEVICE_STATE)); - verify(callback).onStateChanged(eq(OTHER_DEVICE_STATE)); + verify(callback).onDeviceStateChanged(eq(OTHER_DEVICE_STATE)); assertEquals(OTHER_DEVICE_STATE, mService.getBaseState()); reset(callback); DeviceStateRequest secondRequest = DeviceStateRequest.newBuilder( - DEFAULT_DEVICE_STATE).build(); + DEFAULT_DEVICE_STATE.getIdentifier()).build(); mDeviceStateManagerGlobal.requestState(secondRequest, null, null); assertEquals(OTHER_DEVICE_STATE, mService.getBaseState()); - verify(callback).onStateChanged(eq(DEFAULT_DEVICE_STATE)); + verify(callback).onDeviceStateChanged(eq(DEFAULT_DEVICE_STATE)); reset(callback); mDeviceStateManagerGlobal.cancelStateRequest(); - verify(callback).onStateChanged(OTHER_DEVICE_STATE); + verify(callback).onDeviceStateChanged(OTHER_DEVICE_STATE); reset(callback); mDeviceStateManagerGlobal.cancelBaseStateOverride(); - verify(callback).onBaseStateChanged(DEFAULT_DEVICE_STATE); - verify(callback).onStateChanged(DEFAULT_DEVICE_STATE); + verify(callback).onDeviceStateChanged(DEFAULT_DEVICE_STATE); } @Test public void verifyDeviceStateRequestCallbacksCalled() { DeviceStateRequest.Callback callback = mock(TestDeviceStateRequestCallback.class); - DeviceStateRequest request = DeviceStateRequest.newBuilder(OTHER_DEVICE_STATE).build(); + DeviceStateRequest request = DeviceStateRequest.newBuilder( + OTHER_DEVICE_STATE.getIdentifier()).build(); mDeviceStateManagerGlobal.requestState(request, ConcurrentUtils.DIRECT_EXECUTOR /* executor */, callback /* callback */); @@ -257,12 +253,14 @@ public final class DeviceStateManagerGlobalTest { } } - private int[] mSupportedStates = new int[] { DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE }; - private int mBaseState = DEFAULT_DEVICE_STATE; + private List<DeviceState> mSupportedDeviceStates = List.of(DEFAULT_DEVICE_STATE, + OTHER_DEVICE_STATE); + + private DeviceState mBaseState = DEFAULT_DEVICE_STATE; private Request mRequest; private Request mBaseStateRequest; - private Set<IDeviceStateManagerCallback> mCallbacks = new HashSet<>(); + private final Set<IDeviceStateManagerCallback> mCallbacks = new HashSet<>(); TestDeviceStateManagerService(FakePermissionEnforcer enforcer) { super(enforcer); @@ -270,10 +268,15 @@ public final class DeviceStateManagerGlobalTest { private DeviceStateInfo getInfo() { final int mergedBaseState = mBaseStateRequest == null - ? mBaseState : mBaseStateRequest.state; + ? mBaseState.getIdentifier() : mBaseStateRequest.state; final int mergedState = mRequest == null ? mergedBaseState : mRequest.state; - return new DeviceStateInfo(mSupportedStates, mergedBaseState, mergedState); + + final DeviceState baseState = new DeviceState( + new DeviceState.Configuration.Builder(mergedBaseState, "" /* name */).build()); + final DeviceState state = new DeviceState( + new DeviceState.Configuration.Builder(mergedState, "" /* name */).build()); + return new DeviceStateInfo(mSupportedDeviceStates, baseState, state); } private void notifyDeviceStateInfoChanged() { @@ -392,25 +395,25 @@ public final class DeviceStateManagerGlobalTest { onStateRequestOverlayDismissed_enforcePermission(); } - public void setSupportedStates(int[] states) { - mSupportedStates = states; + public void setSupportedStates(List<DeviceState> states) { + mSupportedDeviceStates = states; notifyDeviceStateInfoChanged(); } - public int[] getSupportedStates() { - return mSupportedStates; + public List<DeviceState> getSupportedDeviceStates() { + return mSupportedDeviceStates; } - public void setBaseState(int state) { + public void setBaseState(DeviceState state) { mBaseState = state; notifyDeviceStateInfoChanged(); } - public int getBaseState() { + public DeviceState getBaseState() { return getInfo().baseState; } - public int getMergedState() { + public DeviceState getMergedState() { return getInfo().currentState; } } diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java index c2877217a529..68de21f76dc8 100644 --- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java +++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java @@ -16,19 +16,27 @@ package android.hardware.devicestate; -import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS; import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertThrows; +import static org.testng.Assert.assertTrue; +import android.os.Parcel; import android.platform.test.annotations.Presubmit; +import junit.framework.Assert; + import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + /** * Unit tests for {@link android.hardware.devicestate.DeviceState}. * <p/> @@ -39,33 +47,50 @@ import org.junit.runners.JUnit4; public final class DeviceStateTest { @Test public void testConstruct() { - final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE_IDENTIFIER /* identifier */, - "TEST_CLOSED" /* name */, DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS /* flags */); + DeviceState.Configuration config = new DeviceState.Configuration.Builder( + MINIMUM_DEVICE_STATE_IDENTIFIER, "TEST_CLOSED") + .setSystemProperties( + new HashSet<>(List.of(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS))) + .build(); + final DeviceState state = new DeviceState(config); assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE_IDENTIFIER); assertEquals(state.getName(), "TEST_CLOSED"); - assertEquals(state.getFlags(), DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS); + assertTrue(state.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)); } @Test - public void testConstruct_nullName() { - final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE_IDENTIFIER /* identifier */, - null /* name */, 0/* flags */); - assertEquals(state.getIdentifier(), MAXIMUM_DEVICE_STATE_IDENTIFIER); - assertNull(state.getName()); - assertEquals(state.getFlags(), 0); - } + public void testHasProperties() { + DeviceState.Configuration config = new DeviceState.Configuration.Builder( + MINIMUM_DEVICE_STATE_IDENTIFIER, "TEST") + .setSystemProperties(new HashSet<>(List.of(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST))) + .build(); - @Test - public void testConstruct_tooLargeIdentifier() { - assertThrows(IllegalArgumentException.class, - () -> new DeviceState(MAXIMUM_DEVICE_STATE_IDENTIFIER + 1 /* identifier */, - null /* name */, 0 /* flags */)); + final DeviceState state = new DeviceState(config); + + assertTrue(state.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)); + assertTrue(state.hasProperty(PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST)); + assertTrue(state.hasProperties(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST)); } @Test - public void testConstruct_tooSmallIdentifier() { - assertThrows(IllegalArgumentException.class, - () -> new DeviceState(MINIMUM_DEVICE_STATE_IDENTIFIER - 1 /* identifier */, - null /* name */, 0 /* flags */)); + public void writeToParcel() { + final DeviceState originalState = new DeviceState( + new DeviceState.Configuration.Builder(0, "TEST_STATE") + .setSystemProperties(Set.of(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST)) + .setPhysicalProperties( + Set.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED)) + .build()); + + final Parcel parcel = Parcel.obtain(); + originalState.getConfiguration().writeToParcel(parcel, 0 /* flags */); + parcel.setDataPosition(0); + + final DeviceState.Configuration stateConfiguration = + DeviceState.Configuration.CREATOR.createFromParcel(parcel); + + Assert.assertEquals(originalState, new DeviceState(stateConfiguration)); } } diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java index a7acaf924c15..a2a0f4936888 100644 --- a/graphics/java/android/graphics/BaseCanvas.java +++ b/graphics/java/android/graphics/BaseCanvas.java @@ -333,6 +333,11 @@ public abstract class BaseCanvas { nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance()); } + public void drawRegion(@NonNull Region region, @NonNull Paint paint) { + throwIfHasHwFeaturesInSwMode(paint); + nDrawRegion(mNativeCanvasWrapper, region.mNativeRegion, paint.getNativeInstance()); + } + public void drawPoint(float x, float y, @NonNull Paint paint) { throwIfHasHwFeaturesInSwMode(paint); nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance()); diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java index 4e88b0efd3e5..5b1fa7b15e6d 100644 --- a/graphics/java/android/graphics/BaseRecordingCanvas.java +++ b/graphics/java/android/graphics/BaseRecordingCanvas.java @@ -290,6 +290,11 @@ public class BaseRecordingCanvas extends Canvas { } @Override + public void drawRegion(@NonNull Region region, @NonNull Paint paint) { + nDrawRegion(mNativeCanvasWrapper, region.mNativeRegion, paint.getNativeInstance()); + } + + @Override public final void drawPicture(@NonNull Picture picture) { picture.endRecording(); int restoreCount = save(); diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index f9ac02a0055a..e03a1daf7202 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1931,6 +1931,17 @@ public class Canvas extends BaseCanvas { } /** + * Draws the given region using the given paint. + * + * @param region The region to be drawn + * @param paint The paint used to draw the region + */ + @FlaggedApi(Flags.FLAG_DRAW_REGION) + public void drawRegion(@NonNull Region region, @NonNull Paint paint) { + super.drawRegion(region, paint); + } + + /** * Helper for drawPoints() for drawing a single point. */ public void drawPoint(float x, float y, @NonNull Paint paint) { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java index 88fd461debbe..fa35b632a6b3 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java @@ -16,7 +16,7 @@ package androidx.window.common; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_USE_BASE_STATE; @@ -69,14 +69,14 @@ public final class DeviceStateManagerFoldingFeatureProducer * example is activated via public API and can be active in both the "open" and "half folded" * device states. */ - private int mCurrentDeviceState = INVALID_DEVICE_STATE; + private int mCurrentDeviceState = INVALID_DEVICE_STATE_IDENTIFIER; /** * Base device state received via * {@link DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int)}. * "Base" in this context means the "physical" state of the device. */ - private int mCurrentBaseDeviceState = INVALID_DEVICE_STATE; + private int mCurrentBaseDeviceState = INVALID_DEVICE_STATE_IDENTIFIER; @NonNull private final RawFoldingFeatureProducer mRawFoldSupplier; @@ -177,7 +177,7 @@ public final class DeviceStateManagerFoldingFeatureProducer if (hasListeners()) { mRawFoldSupplier.addDataChangedCallback(this::notifyFoldingFeatureChange); } else { - mCurrentDeviceState = INVALID_DEVICE_STATE; + mCurrentDeviceState = INVALID_DEVICE_STATE_IDENTIFIER; mRawFoldSupplier.removeDataChangedCallback(this::notifyFoldingFeatureChange); } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java index b315f94b5d00..d31bf2a662a3 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java @@ -16,7 +16,7 @@ package androidx.window.extensions.area; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import android.app.Activity; import android.content.Context; @@ -79,7 +79,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, private int mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_INACTIVE; @GuardedBy("mLock") - private int mCurrentDeviceState = INVALID_DEVICE_STATE; + private int mCurrentDeviceState = INVALID_DEVICE_STATE_IDENTIFIER; @GuardedBy("mLock") private int[] mCurrentSupportedDeviceStates; @@ -143,7 +143,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, mRearDisplayStatusListeners.add(consumer); // If current device state is still invalid, the initial value has not been provided. - if (mCurrentDeviceState == INVALID_DEVICE_STATE) { + if (mCurrentDeviceState == INVALID_DEVICE_STATE_IDENTIFIER) { return; } consumer.accept(getCurrentRearDisplayModeStatus()); @@ -308,7 +308,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, mRearDisplayPresentationStatusListeners.add(consumer); // If current device state is still invalid, the initial value has not been provided - if (mCurrentDeviceState == INVALID_DEVICE_STATE) { + if (mCurrentDeviceState == INVALID_DEVICE_STATE_IDENTIFIER) { return; } @WindowAreaStatus int currentStatus = getCurrentRearDisplayPresentationModeStatus(); @@ -467,7 +467,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, @GuardedBy("mLock") private int getCurrentRearDisplayModeStatus() { - if (mRearDisplayState == INVALID_DEVICE_STATE) { + if (mRearDisplayState == INVALID_DEVICE_STATE_IDENTIFIER) { return WindowAreaComponent.STATUS_UNSUPPORTED; } @@ -495,7 +495,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, @GuardedBy("mLock") private void updateRearDisplayStatusListeners(@WindowAreaStatus int windowAreaStatus) { - if (mRearDisplayState == INVALID_DEVICE_STATE) { + if (mRearDisplayState == INVALID_DEVICE_STATE_IDENTIFIER) { return; } synchronized (mLock) { @@ -507,7 +507,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, @GuardedBy("mLock") private int getCurrentRearDisplayPresentationModeStatus() { - if (mConcurrentDisplayState == INVALID_DEVICE_STATE) { + if (mConcurrentDisplayState == INVALID_DEVICE_STATE_IDENTIFIER) { return WindowAreaComponent.STATUS_UNSUPPORTED; } @@ -530,7 +530,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, @GuardedBy("mLock") private void updateRearDisplayPresentationStatusListeners( @WindowAreaStatus int windowAreaStatus) { - if (mConcurrentDisplayState == INVALID_DEVICE_STATE) { + if (mConcurrentDisplayState == INVALID_DEVICE_STATE_IDENTIFIER) { return; } RearDisplayPresentationStatus consumerValue = new RearDisplayPresentationStatus( diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index a883e087cb3b..b54f9cf2f15d 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -109,7 +109,7 @@ <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'application"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string> <string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string> - <string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string> + <string name="split_screen_text" msgid="1396336058129570886">"Écran divisé"</string> <string name="more_button_text" msgid="3655388105592893530">"Plus"</string> <string name="float_button_text" msgid="9221657008391364581">"Flottant"</string> <string name="select_text" msgid="5139083974039906583">"Sélectionner"</string> diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml index a541c590575f..c68b0be47228 100644 --- a/libs/WindowManager/Shell/res/values/config.xml +++ b/libs/WindowManager/Shell/res/values/config.xml @@ -148,4 +148,7 @@ <!-- Whether pointer pilfer is required to start back animation. --> <bool name="config_backAnimationRequiresPointerPilfer">true</bool> + + <!-- Whether desktop mode is supported on the current device --> + <bool name="config_isDesktopModeSupported">false</bool> </resources> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 474430eb44ab..23bdd08e6b24 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -2474,11 +2474,12 @@ public class BubbleStackView extends FrameLayout // Let the expanded animation controller know that it shouldn't animate child adds/reorders // since we're about to animate collapsed. mExpandedAnimationController.notifyPreparingToCollapse(); - + final PointF collapsePosition = mStackAnimationController + .getStackPositionAlongNearestHorizontalEdge(); updateOverflowDotVisibility(false /* expanding */); final Runnable collapseBackToStack = () -> mExpandedAnimationController.collapseBackToStack( - mStackAnimationController.getStackPositionAlongNearestHorizontalEdge(), + collapsePosition, /* fadeBubblesDuringCollapse= */ mRemovingLastBubbleWhileExpanded, () -> { mBubbleContainer.setActiveController(mStackAnimationController); @@ -2501,7 +2502,8 @@ public class BubbleStackView extends FrameLayout } mExpandedViewAnimationController.reset(); }; - mExpandedViewAnimationController.animateCollapse(collapseBackToStack, after); + mExpandedViewAnimationController.animateCollapse(collapseBackToStack, after, + collapsePosition); if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { // When the animation completes, we should no longer be showing the content. // This won't actually update content visibility immediately, if we are currently diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java index 8a33780bc8d5..41755293f382 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java @@ -15,6 +15,8 @@ */ package com.android.wm.shell.bubbles.animation; +import android.graphics.PointF; + import com.android.wm.shell.bubbles.BubbleExpandedView; /** @@ -55,8 +57,9 @@ public interface ExpandedViewAnimationController { * @param startStackCollapse runnable that is triggered when bubbles can start moving back to * their collapsed location * @param after runnable to run after animation is complete + * @param collapsePosition the position on screen the stack will collapse to */ - void animateCollapse(Runnable startStackCollapse, Runnable after); + void animateCollapse(Runnable startStackCollapse, Runnable after, PointF collapsePosition); /** * Animate the view back to fully expanded state. @@ -69,6 +72,22 @@ public interface ExpandedViewAnimationController { void animateForImeVisibilityChange(boolean visible); /** + * Whether this controller should also animate the expansion for the bubble + */ + boolean shouldAnimateExpansion(); + + /** + * Animate the expansion of the bubble. + * + * @param startDelayMillis how long to delay starting the expansion animation + * @param after runnable to run after the animation is complete + * @param collapsePosition the position on screen the stack will collapse to (and expand from) + * @param bubblePosition the position of the bubble on screen that the view is associated with + */ + void animateExpansion(long startDelayMillis, Runnable after, PointF collapsePosition, + PointF bubblePosition); + + /** * Reset the view to fully expanded state */ void reset(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java index e43609fe8ff0..aa4129a14dbc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java @@ -28,6 +28,7 @@ import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; +import android.graphics.PointF; import android.view.HapticFeedbackConstants; import android.view.ViewConfiguration; @@ -187,9 +188,11 @@ public class ExpandedViewAnimationControllerImpl implements ExpandedViewAnimatio } @Override - public void animateCollapse(Runnable startStackCollapse, Runnable after) { - ProtoLog.d(WM_SHELL_BUBBLES, "expandedView animate collapse swipeVel=%f minFlingVel=%d", - mSwipeUpVelocity, mMinFlingVelocity); + public void animateCollapse(Runnable startStackCollapse, Runnable after, + PointF collapsePosition) { + ProtoLog.d(WM_SHELL_BUBBLES, "expandedView animate collapse swipeVel=%f minFlingVel=%d" + + " collapsePosition=%f,%f", mSwipeUpVelocity, mMinFlingVelocity, + collapsePosition.x, collapsePosition.y); if (mExpandedView != null) { // Mark it as animating immediately to avoid updates to the view before animation starts mExpandedView.setAnimating(true); @@ -274,6 +277,17 @@ public class ExpandedViewAnimationControllerImpl implements ExpandedViewAnimatio } @Override + public boolean shouldAnimateExpansion() { + return false; + } + + @Override + public void animateExpansion(long startDelayMillis, Runnable after, PointF collapsePosition, + PointF bubblePosition) { + // TODO - animate + } + + @Override public void reset() { ProtoLog.d(WM_SHELL_BUBBLES, "reset expandedView collapsed state"); if (mExpandedView == null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java index 4c0281dcc517..e261d92bda5c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java @@ -16,6 +16,8 @@ package com.android.wm.shell.common; +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL; + import android.annotation.BinderThread; import android.annotation.NonNull; import android.os.RemoteException; @@ -26,6 +28,7 @@ import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; import android.window.WindowOrganizer; +import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.transition.LegacyTransitions; import java.util.ArrayList; @@ -204,6 +207,7 @@ public final class SyncTransactionQueue { @Override public void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t) { + ProtoLog.v(WM_SHELL, "SyncTransactionQueue.onTransactionReady(): syncId=%d", id); mMainExecutor.execute(() -> { synchronized (mQueue) { if (mId != id) { @@ -223,6 +227,8 @@ public final class SyncTransactionQueue { Slog.e(TAG, "Error sending callback to legacy transition: " + mId, e); } } else { + ProtoLog.v(WM_SHELL, + "SyncTransactionQueue.onTransactionReady(): syncId=%d apply", id); t.apply(); t.close(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java index 7b8486870a40..494d89307514 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java @@ -16,13 +16,13 @@ package com.android.wm.shell.desktopmode; -import static android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE; - import android.annotation.NonNull; -import android.app.ActivityManager.RunningTaskInfo; +import android.content.Context; import android.os.SystemProperties; +import com.android.internal.annotations.VisibleForTesting; import com.android.window.flags.Flags; +import com.android.wm.shell.R; /** * Constants for desktop mode feature @@ -70,8 +70,11 @@ public class DesktopModeStatus { private static final boolean USE_ROUNDED_CORNERS = SystemProperties.getBoolean( "persist.wm.debug.desktop_use_rounded_corners", true); - private static final boolean ENFORCE_DISPLAY_RESTRICTIONS = SystemProperties.getBoolean( - "persist.wm.debug.desktop_mode_enforce_display_restrictions", true); + /** + * Flag to indicate whether to restrict desktop mode to supported devices. + */ + private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean( + "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); /** * Return {@code true} if desktop windowing is enabled @@ -113,19 +116,25 @@ public class DesktopModeStatus { } /** - * Return whether the display size restrictions should be enforced. + * Return {@code true} if desktop mode should be restricted to supported devices. + */ + @VisibleForTesting + public static boolean enforceDeviceRestrictions() { + return ENFORCE_DEVICE_RESTRICTIONS; + } + + /** + * Return {@code true} if the current device supports desktop mode. */ - public static boolean enforceDisplayRestrictions() { - return ENFORCE_DISPLAY_RESTRICTIONS; + @VisibleForTesting + public static boolean isDesktopModeSupported(@NonNull Context context) { + return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported); } /** - * Return {@code true} if the display associated with the task is at least of size - * {@link android.content.res.Configuration#SCREENLAYOUT_SIZE_XLARGE} or has been overridden to - * ignore the size constraint. + * Return {@code true} if desktop mode can be entered on the current device. */ - public static boolean meetsMinimumDisplayRequirements(@NonNull RunningTaskInfo taskInfo) { - return !enforceDisplayRestrictions() - || taskInfo.configuration.isLayoutSizeAtLeast(SCREENLAYOUT_SIZE_XLARGE); + public static boolean canEnterDesktopMode(@NonNull Context context) { + return !enforceDeviceRestrictions() || isDesktopModeSupported(context); } } 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 c2c944211552..95237c38f309 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 @@ -306,7 +306,7 @@ class DesktopTasksController( task: RunningTaskInfo, wct: WindowContainerTransaction = WindowContainerTransaction() ) { - if (!DesktopModeStatus.meetsMinimumDisplayRequirements(task)) { + if (!DesktopModeStatus.canEnterDesktopMode(context)) { KtProtoLog.w( WM_SHELL_DESKTOP_MODE, "DesktopTasksController: Cannot enter desktop, " + "display does not meet minimum size requirements") diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java index e73a85003881..4c69cc3cc61d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java @@ -32,13 +32,16 @@ import android.view.SurfaceControl; import androidx.annotation.BinderThread; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; +import com.android.wm.shell.R; 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.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.pip.IPip; import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; @@ -57,15 +60,40 @@ public class PipController implements ConfigurationChangeListener, DisplayController.OnDisplaysChangedListener, RemoteCallable<PipController> { private static final String TAG = PipController.class.getSimpleName(); - private Context mContext; - private ShellController mShellController; - private DisplayController mDisplayController; - private DisplayInsetsController mDisplayInsetsController; - private PipBoundsState mPipBoundsState; - private PipBoundsAlgorithm mPipBoundsAlgorithm; - private PipDisplayLayoutState mPipDisplayLayoutState; - private PipScheduler mPipScheduler; - private ShellExecutor mMainExecutor; + private final Context mContext; + private final ShellController mShellController; + private final DisplayController mDisplayController; + private final DisplayInsetsController mDisplayInsetsController; + private final PipBoundsState mPipBoundsState; + private final PipBoundsAlgorithm mPipBoundsAlgorithm; + private final PipDisplayLayoutState mPipDisplayLayoutState; + private final PipScheduler mPipScheduler; + private final ShellExecutor mMainExecutor; + + // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents. + private PipAnimationListener mPipRecentsAnimationListener; + + @VisibleForTesting + interface PipAnimationListener { + /** + * Notifies the listener that the Pip animation is started. + */ + void onPipAnimationStarted(); + + /** + * Notifies the listener about PiP resource dimensions changed. + * Listener can expect an immediate callback the first time they attach. + * + * @param cornerRadius the pixel value of the corner radius, zero means it's disabled. + * @param shadowRadius the pixel value of the shadow radius, zero means it's disabled. + */ + void onPipResourceDimensionsChanged(int cornerRadius, int shadowRadius); + + /** + * Notifies the listener that user leaves PiP by tapping on the expand button. + */ + void onExpandPip(); + } private PipController(Context context, ShellInit shellInit, @@ -92,14 +120,27 @@ public class PipController implements ConfigurationChangeListener, } } - @Override - public Context getContext() { - return mContext; - } - - @Override - public ShellExecutor getRemoteCallExecutor() { - return mMainExecutor; + /** + * Instantiates {@link PipController}, returns {@code null} if the feature not supported. + */ + public static PipController create(Context context, + ShellInit shellInit, + ShellController shellController, + DisplayController displayController, + DisplayInsetsController displayInsetsController, + PipBoundsState pipBoundsState, + PipBoundsAlgorithm pipBoundsAlgorithm, + PipDisplayLayoutState pipDisplayLayoutState, + PipScheduler pipScheduler, + ShellExecutor mainExecutor) { + if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { + ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "%s: Device doesn't support Pip feature", TAG); + return null; + } + return new PipController(context, shellInit, shellController, displayController, + displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, + pipScheduler, mainExecutor); } private void onInit() { @@ -109,7 +150,6 @@ public class PipController implements ConfigurationChangeListener, DisplayLayout layout = new DisplayLayout(mContext, mContext.getDisplay()); mPipDisplayLayoutState.setDisplayLayout(layout); - mShellController.addConfigurationChangeListener(this); mDisplayController.addDisplayWindowListener(this); mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(), new DisplayInsetsController.OnInsetsChangedListener() { @@ -123,45 +163,50 @@ public class PipController implements ConfigurationChangeListener, // Allow other outside processes to bind to PiP controller using the key below. mShellController.addExternalInterface(KEY_EXTRA_SHELL_PIP, this::createExternalInterface, this); - } - - /** - * Instantiates {@link PipController}, returns {@code null} if the feature not supported. - */ - public static PipController create(Context context, - ShellInit shellInit, - ShellController shellController, - DisplayController displayController, - DisplayInsetsController displayInsetsController, - PipBoundsState pipBoundsState, - PipBoundsAlgorithm pipBoundsAlgorithm, - PipDisplayLayoutState pipDisplayLayoutState, - PipScheduler pipScheduler, - ShellExecutor mainExecutor) { - if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) { - ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, - "%s: Device doesn't support Pip feature", TAG); - return null; - } - return new PipController(context, shellInit, shellController, displayController, - displayInsetsController, pipBoundsState, pipBoundsAlgorithm, pipDisplayLayoutState, - pipScheduler, mainExecutor); + mShellController.addConfigurationChangeListener(this); } private ExternalInterfaceBinder createExternalInterface() { return new IPipImpl(this); } + // + // RemoteCallable implementations + // + + @Override + public Context getContext() { + return mContext; + } + + @Override + public ShellExecutor getRemoteCallExecutor() { + return mMainExecutor; + } + + // + // ConfigurationChangeListener implementations + // + @Override public void onConfigurationChanged(Configuration newConfiguration) { mPipDisplayLayoutState.onConfigurationChanged(); } @Override + public void onDensityOrFontScaleChanged() { + onPipResourceDimensionsChanged(); + } + + @Override public void onThemeChanged() { onDisplayChanged(new DisplayLayout(mContext, mContext.getDisplay())); } + // + // DisplayController.OnDisplaysChangedListener implementations + // + @Override public void onDisplayAdded(int displayId) { if (displayId != mPipDisplayLayoutState.getDisplayId()) { @@ -182,6 +227,10 @@ public class PipController implements ConfigurationChangeListener, mPipDisplayLayoutState.setDisplayLayout(layout); } + // + // IPip Binder stub helpers + // + private Rect getSwipePipToHomeBounds(ComponentName componentName, ActivityInfo activityInfo, PictureInPictureParams pictureInPictureParams, int launcherRotation, Rect hotseatKeepClearArea) { @@ -197,18 +246,56 @@ public class PipController implements ConfigurationChangeListener, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "onSwipePipToHomeAnimationStart: %s", componentName); mPipScheduler.setInSwipePipToHomeTransition(true); + mPipRecentsAnimationListener.onPipAnimationStarted(); // TODO: cache the overlay if provided for reparenting later. } + // + // IPipAnimationListener Binder proxy helpers + // + + private void setPipRecentsAnimationListener(PipAnimationListener pipAnimationListener) { + mPipRecentsAnimationListener = pipAnimationListener; + onPipResourceDimensionsChanged(); + } + + private void onPipResourceDimensionsChanged() { + if (mPipRecentsAnimationListener != null) { + mPipRecentsAnimationListener.onPipResourceDimensionsChanged( + mContext.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius), + mContext.getResources().getDimensionPixelSize(R.dimen.pip_shadow_radius)); + } + } + /** * The interface for calls from outside the host process. */ @BinderThread private static class IPipImpl extends IPip.Stub implements ExternalInterfaceBinder { private PipController mController; + private final SingleInstanceRemoteListener<PipController, IPipAnimationListener> mListener; + private final PipAnimationListener mPipAnimationListener = new PipAnimationListener() { + @Override + public void onPipAnimationStarted() { + mListener.call(l -> l.onPipAnimationStarted()); + } + + @Override + public void onPipResourceDimensionsChanged(int cornerRadius, int shadowRadius) { + mListener.call(l -> l.onPipResourceDimensionsChanged(cornerRadius, shadowRadius)); + } + + @Override + public void onExpandPip() { + mListener.call(l -> l.onExpandPip()); + } + }; IPipImpl(PipController controller) { mController = controller; + mListener = new SingleInstanceRemoteListener<>(mController, + (cntrl) -> cntrl.setPipRecentsAnimationListener(mPipAnimationListener), + (cntrl) -> cntrl.setPipRecentsAnimationListener(null)); } /** @@ -217,6 +304,7 @@ public class PipController implements ConfigurationChangeListener, @Override public void invalidate() { mController = null; + mListener.unregister(); } @Override @@ -257,7 +345,14 @@ public class PipController implements ConfigurationChangeListener, @Override public void setPipAnimationListener(IPipAnimationListener listener) { - // TODO: set a proper animation listener to update the Launcher state as needed. + executeRemoteCallWithTaskPermission(mController, "setPipAnimationListener", + (controller) -> { + if (listener != null) { + mListener.register(listener); + } else { + mListener.unregister(); + } + }); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index 895c793007a5..6665013aa68d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -172,7 +172,7 @@ public class PipScheduler { } void setInSwipePipToHomeTransition(boolean inSwipePipToHome) { - mInSwipePipToHomeTransition = true; + mInSwipePipToHomeTransition = inSwipePipToHome; } boolean isInSwipePipToHomeTransition() { 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 dfb04758c851..d15da4a43db4 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 @@ -226,7 +226,26 @@ public class PipTransition extends PipTransitionController { // cache the PiP task token and leash mPipScheduler.setPipTaskToken(mPipTaskToken); + SurfaceControl pipLeash = pipChange.getLeash(); + + PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams; + Rect srcRectHint = params.getSourceRectHint(); + Rect destinationBounds = pipChange.getEndAbsBounds(); + if (PipBoundsAlgorithm.isSourceRectHintValidForEnterPip(srcRectHint, destinationBounds)) { + float scale = (float) destinationBounds.width() / srcRectHint.width(); + startTransaction.setWindowCrop(pipLeash, srcRectHint); + startTransaction.setPosition(pipLeash, + destinationBounds.left - srcRectHint.left * scale, + destinationBounds.top - srcRectHint.top * scale); + + // Reset the scale in case we are in the multi-activity case. + // TO_FRONT transition already scales down the task in single-activity case, but + // in multi-activity case, reparenting yields new reset scales coming from pinned task. + startTransaction.setScale(pipLeash, scale, scale); + } else { + // TODO(b/325481148): handle the case with invalid srcRectHint (using overlay). + } startTransaction.apply(); finishCallback.onTransitionFinished(null); return true; @@ -303,6 +322,7 @@ public class PipTransition extends PipTransitionController { WindowContainerTransaction wct = new WindowContainerTransaction(); wct.movePipActivityToPinnedRootTask(pipTask.token, entryBounds); + wct.deferConfigToTransitionEnd(pipTask.token); return wct; } 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 b5ea1b1b43ea..235456c0f716 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 @@ -418,6 +418,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "[%d] RecentsController.start", mInstanceId); if (mListener == null || mTransition == null) { + Slog.e(TAG, "Missing listener or transition, hasListener=" + (mListener != null) + + " hasTransition=" + (mTransition != null)); cleanUp(); return false; } @@ -531,21 +533,31 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { // Put into the "below" layer space. t.setLayer(change.getLeash(), layer); mOpeningTasks.add(new TaskState(change, null /* leash */)); + } else { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, + " unhandled root taskId=%d", taskInfo.taskId); } } else if (TransitionUtil.isDividerBar(change)) { final RemoteAnimationTarget target = TransitionUtil.newTarget(change, belowLayers - i, info, t, mLeashMap); // Add this as a app and we will separate them on launcher side by window type. apps.add(target); + } else { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, + " unhandled change taskId=%d", + taskInfo != null ? taskInfo.taskId : -1); } } + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, + "Applying transaction=%d", t.getId()); t.apply(); Bundle b = new Bundle(1 /*capacity*/); b.putParcelable(KEY_EXTRA_SPLIT_BOUNDS, mRecentTasksController.getSplitBoundsForTaskId(closingSplitTaskId)); try { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, - "[%d] RecentsController.start: calling onAnimationStart", mInstanceId); + "[%d] RecentsController.start: calling onAnimationStart with %d apps", + mInstanceId, apps.size()); mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]), wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]), diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index e2be1533118a..1ce87ef73fd7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -22,6 +22,7 @@ import static android.window.StartingWindowRemovalInfo.DEFER_MODE_NORMAL; import static android.window.StartingWindowRemovalInfo.DEFER_MODE_ROTATION; import android.annotation.CallSuper; +import android.annotation.NonNull; import android.app.TaskInfo; import android.app.WindowConfiguration; import android.content.Context; @@ -306,7 +307,7 @@ public class StartingSurfaceDrawer { @CallSuper protected void removeImmediately() { mRemoveExecutor.removeCallbacks(mScheduledRunnable); - mRecordManager.onRecordRemoved(mTaskId); + mRecordManager.onRecordRemoved(this, mTaskId); } } @@ -327,6 +328,11 @@ public class StartingSurfaceDrawer { } void addRecord(int taskId, StartingWindowRecord record) { + final StartingWindowRecord original = mStartingWindowRecords.get(taskId); + if (original != null) { + mTmpRemovalInfo.taskId = taskId; + original.removeIfPossible(mTmpRemovalInfo, true /* immediately */); + } mStartingWindowRecords.put(taskId, record); } @@ -346,8 +352,11 @@ public class StartingSurfaceDrawer { removeWindow(mTmpRemovalInfo, true/* immediately */); } - void onRecordRemoved(int taskId) { - mStartingWindowRecords.remove(taskId); + void onRecordRemoved(@NonNull StartingWindowRecord record, int taskId) { + final StartingWindowRecord currentRecord = mStartingWindowRecords.get(taskId); + if (currentRecord == record) { + mStartingWindowRecords.remove(taskId); + } } StartingWindowRecord getRecord(int taskId) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java index 61e11e877b90..89b0e25b306b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java @@ -16,6 +16,8 @@ package com.android.wm.shell.transition; +import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS; + import android.annotation.NonNull; import android.os.RemoteException; import android.view.IRemoteAnimationFinishedCallback; @@ -26,6 +28,8 @@ import android.view.SurfaceControl; import android.view.WindowManager; import android.window.IWindowContainerTransactionCallback; +import com.android.internal.protolog.common.ProtoLog; + /** * Utilities and interfaces for transition-like usage on top of the legacy app-transition and * synctransaction tools. @@ -87,9 +91,11 @@ public class LegacyTransitions { @Override public void onTransactionReady(int id, SurfaceControl.Transaction t) throws RemoteException { + ProtoLog.v(WM_SHELL_TRANSITIONS, + "LegacyTransitions.onTransactionReady(): syncId=%d", id); mSyncId = id; mTransaction = t; - checkApply(); + checkApply(true /* log */); } } @@ -103,20 +109,29 @@ public class LegacyTransitions { mWallpapers = wallpapers; mNonApps = nonApps; mFinishCallback = finishedCallback; - checkApply(); + checkApply(false /* log */); } @Override public void onAnimationCancelled() throws RemoteException { mCancelled = true; mApps = mWallpapers = mNonApps = null; - checkApply(); + checkApply(false /* log */); } } - private void checkApply() throws RemoteException { - if (mSyncId < 0 || (mFinishCallback == null && !mCancelled)) return; + private void checkApply(boolean log) throws RemoteException { + if (mSyncId < 0 || (mFinishCallback == null && !mCancelled)) { + if (log) { + ProtoLog.v(WM_SHELL_TRANSITIONS, "\tSkipping hasFinishedCb=%b canceled=%b", + mFinishCallback != null, mCancelled); + } + return; + } + if (log) { + ProtoLog.v(WM_SHELL_TRANSITIONS, "\tapply"); + } mLegacyTransition.onAnimationStart(mTransit, mApps, mWallpapers, mNonApps, mFinishCallback, mTransaction); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index b8a0f6703b97..ccd0b2df8cf1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -1409,6 +1409,8 @@ public class Transitions implements RemoteCallable<Transitions>, public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo, SurfaceControl.Transaction t, SurfaceControl.Transaction finishT) throws RemoteException { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady(transaction=%d)", + t.getId()); mMainExecutor.execute(() -> Transitions.this.onTransitionReady( iBinder, transitionInfo, t, finishT)); } 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 bf22193566ed..98ff0eed9c11 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 @@ -866,6 +866,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { return; } if (mTransitionDragActive) { + // Do not create an indicator at all if we're not past transition height. + if (ev.getRawY() < mContext.getResources().getDimensionPixelSize(com.android + .wm.shell.R.dimen.desktop_mode_fullscreen_from_desktop_height) + && mMoveToDesktopAnimator == null) { + return; + } final DesktopModeVisualIndicator.IndicatorType indicatorType = mDesktopTasksController.updateVisualIndicator( relevantDecor.mTaskInfo, @@ -1052,7 +1058,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { && taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD && !taskInfo.configuration.windowConfiguration.isAlwaysOnTop() - && DesktopModeStatus.meetsMinimumDisplayRequirements(taskInfo); + && DesktopModeStatus.canEnterDesktopMode(mContext); } private void createWindowDecoration( 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 92b187f90d65..0136751d8c9a 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 @@ -23,8 +23,6 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED -import android.content.res.Configuration.SCREENLAYOUT_SIZE_NORMAL -import android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE import android.os.Binder import android.testing.AndroidTestingRunner import android.view.Display.DEFAULT_DISPLAY @@ -38,6 +36,7 @@ import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER import androidx.test.filters.SmallTest +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.ExtendedMockito.never import com.android.dx.mockito.inline.extended.StaticMockitoSession @@ -89,6 +88,7 @@ import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever +import org.mockito.quality.Strictness @SmallTest @RunWith(AndroidTestingRunner::class) @@ -126,7 +126,8 @@ class DesktopTasksControllerTest : ShellTestCase() { @Before fun setUp() { - mockitoSession = mockitoSession().spyStatic(DesktopModeStatus::class.java).startMocking() + mockitoSession = mockitoSession().strictness(Strictness.LENIENT) + .spyStatic(DesktopModeStatus::class.java).startMocking() whenever(DesktopModeStatus.isEnabled()).thenReturn(true) shellInit = Mockito.spy(ShellInit(testExecutor)) @@ -335,25 +336,25 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test - fun moveToDesktop_screenSizeBelowXLarge_doesNothing() { + fun moveToDesktop_deviceNotSupported_doesNothing() { val task = setUpFullscreenTask() - // Update screen layout to be below minimum size - task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL + // Simulate non compatible device + doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } controller.moveToDesktop(task) verifyWCTNotExecuted() } @Test - fun moveToDesktop_screenSizeBelowXLarge_displayRestrictionsOverridden_taskIsMovedToDesktop() { + fun moveToDesktop_deviceNotSupported_deviceRestrictionsOverridden_taskIsMovedToDesktop() { val task = setUpFullscreenTask() - // Update screen layout to be below minimum size - task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL + // Simulate non compatible device + doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } - // Simulate enforce display restrictions system property overridden to false - whenever(DesktopModeStatus.enforceDisplayRestrictions()).thenReturn(false) + // Simulate enforce device restrictions system property overridden to false + whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(false) controller.moveToDesktop(task) @@ -363,7 +364,7 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test - fun moveToDesktop_screenSizeXLarge_taskIsMovedToDesktop() { + fun moveToDesktop_deviceSupported_taskIsMovedToDesktop() { val task = setUpFullscreenTask() controller.moveToDesktop(task) @@ -874,7 +875,8 @@ class DesktopTasksControllerTest : ShellTestCase() { private fun setUpFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo { val task = createFullscreenTask(displayId) - task.configuration.screenLayout = SCREENLAYOUT_SIZE_XLARGE + doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } + whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true) whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) runningTasks.add(task) return task @@ -882,7 +884,8 @@ class DesktopTasksControllerTest : ShellTestCase() { private fun setUpSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo { val task = createSplitScreenTask(displayId) - task.configuration.screenLayout = SCREENLAYOUT_SIZE_XLARGE + doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } + whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true) whenever(splitScreenController.isTaskInSplitScreen(task.taskId)).thenReturn(true) whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) runningTasks.add(task) 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 83519bbf624a..6940739d68b2 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 @@ -23,8 +23,6 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.content.Context -import android.content.res.Configuration.SCREENLAYOUT_SIZE_NORMAL -import android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE import android.graphics.Rect import android.hardware.display.DisplayManager import android.hardware.display.VirtualDisplay @@ -47,6 +45,7 @@ import android.view.WindowInsets.Type.navigationBars import android.view.WindowInsets.Type.statusBars import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession +import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.window.flags.Flags import com.android.wm.shell.RootTaskDisplayAreaOrganizer @@ -367,30 +366,41 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() { @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) - fun testWindowDecor_screenSizeBelowXLarge_decorNotCreated() { - val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true) - // Update screen layout to be below minimum size - task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL + fun testWindowDecor_desktopModeUnsupportedOnDevice_decorNotCreated() { + val mockitoSession: StaticMockitoSession = mockitoSession() + .strictness(Strictness.LENIENT) + .spyStatic(DesktopModeStatus::class.java) + .startMocking() + try { + // Simulate default enforce device restrictions system property + whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true) - onTaskOpening(task) - verify(mockDesktopModeWindowDecorFactory, never()) - .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any()) + val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true) + // Simulate device that doesn't support desktop mode + doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } + + onTaskOpening(task) + verify(mockDesktopModeWindowDecorFactory, never()) + .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any()) + } finally { + mockitoSession.finishMocking() + } } @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) - fun testWindowDecor_screenSizeBelowXLarge_displayRestrictionsOverridden_decorCreated() { + fun testWindowDecor_desktopModeUnsupportedOnDevice_deviceRestrictionsOverridden_decorCreated() { val mockitoSession: StaticMockitoSession = mockitoSession() .strictness(Strictness.LENIENT) .spyStatic(DesktopModeStatus::class.java) .startMocking() try { - // Simulate enforce display restrictions system property overridden to false - whenever(DesktopModeStatus.enforceDisplayRestrictions()).thenReturn(false) + // Simulate enforce device restrictions system property overridden to false + whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(false) + // Simulate device that doesn't support desktop mode + doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true) - // Update screen layout to be below minimum size - task.configuration.screenLayout = SCREENLAYOUT_SIZE_NORMAL setUpMockDecorationsForTasks(task) onTaskOpening(task) @@ -403,14 +413,25 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() { @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE) - fun testWindowDecor_screenSizeXLarge_decorCreated() { - val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true) - task.configuration.screenLayout = SCREENLAYOUT_SIZE_XLARGE - setUpMockDecorationsForTasks(task) + fun testWindowDecor_deviceSupportsDesktopMode_decorCreated() { + val mockitoSession: StaticMockitoSession = mockitoSession() + .strictness(Strictness.LENIENT) + .spyStatic(DesktopModeStatus::class.java) + .startMocking() + try { + // Simulate default enforce device restrictions system property + whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true) - onTaskOpening(task) - verify(mockDesktopModeWindowDecorFactory) - .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any()) + val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true) + doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) } + setUpMockDecorationsForTasks(task) + + onTaskOpening(task) + verify(mockDesktopModeWindowDecorFactory) + .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any()) + } finally { + mockitoSession.finishMocking() + } } private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) { diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index 3d7e559bebe0..76a0a6499d33 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -76,3 +76,10 @@ flag { description: "Automatically animate all changes in HDR headroom" bug: "314810174" } + +flag { + name: "draw_region" + namespace: "core_graphics" + description: "Add canvas#drawRegion API" + bug: "318612129" +} diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 1d0330185b1c..abf64d099935 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -411,7 +411,8 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy // If the previous frame was dropped we don't need to hold onto it, so // just keep using the previous frame's structure instead - if (const auto reason = wasSkipped(mCurrentFrameInfo)) { + const auto reason = wasSkipped(mCurrentFrameInfo); + if (reason.has_value()) { // Use the oldest skipped frame in case we skip more than a single frame if (!mSkippedFrameInfo) { switch (*reason) { diff --git a/location/api/system-current.txt b/location/api/system-current.txt index 2e7a541ecb60..254d74aa235c 100644 --- a/location/api/system-current.txt +++ b/location/api/system-current.txt @@ -616,8 +616,8 @@ package android.location.provider { @FlaggedApi(Flags.FLAG_NEW_GEOCODER) public abstract class GeocodeProviderBase { ctor public GeocodeProviderBase(@NonNull android.content.Context, @NonNull String); method @NonNull public final android.os.IBinder getBinder(); - method public abstract void onForwardGeocode(@NonNull android.location.provider.ForwardGeocodeRequest, @NonNull android.os.OutcomeReceiver<java.util.List<android.location.Address>,java.lang.Exception>); - method public abstract void onReverseGeocode(@NonNull android.location.provider.ReverseGeocodeRequest, @NonNull android.os.OutcomeReceiver<java.util.List<android.location.Address>,java.lang.Exception>); + method public abstract void onForwardGeocode(@NonNull android.location.provider.ForwardGeocodeRequest, @NonNull android.os.OutcomeReceiver<java.util.List<android.location.Address>,java.lang.Throwable>); + method public abstract void onReverseGeocode(@NonNull android.location.provider.ReverseGeocodeRequest, @NonNull android.os.OutcomeReceiver<java.util.List<android.location.Address>,java.lang.Throwable>); field public static final String ACTION_GEOCODE_PROVIDER = "com.android.location.service.GeocodeProvider"; } diff --git a/location/java/android/location/provider/GeocodeProviderBase.java b/location/java/android/location/provider/GeocodeProviderBase.java index e2c48b9c3515..71644d07be57 100644 --- a/location/java/android/location/provider/GeocodeProviderBase.java +++ b/location/java/android/location/provider/GeocodeProviderBase.java @@ -104,14 +104,14 @@ public abstract class GeocodeProviderBase { */ public abstract void onForwardGeocode( @NonNull ForwardGeocodeRequest request, - @NonNull OutcomeReceiver<List<Address>, Exception> callback); + @NonNull OutcomeReceiver<List<Address>, Throwable> callback); /** * Requests reverse geocoding of the given arguments. The given callback must be invoked once. */ public abstract void onReverseGeocode( @NonNull ReverseGeocodeRequest request, - @NonNull OutcomeReceiver<List<Address>, Exception> callback); + @NonNull OutcomeReceiver<List<Address>, Throwable> callback); private class Service extends IGeocodeProvider.Stub { @Override @@ -145,7 +145,7 @@ public abstract class GeocodeProviderBase { } } - private static class SingleUseCallback implements OutcomeReceiver<List<Address>, Exception> { + private static class SingleUseCallback implements OutcomeReceiver<List<Address>, Throwable> { private final AtomicReference<IGeocodeCallback> mCallback; @@ -154,7 +154,7 @@ public abstract class GeocodeProviderBase { } @Override - public void onError(Exception e) { + public void onError(Throwable e) { try { Objects.requireNonNull(mCallback.getAndSet(null)).onError(e.toString()); } catch (RemoteException r) { diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index 72aaa3554ddb..55c8ed5debf8 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -37,6 +37,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.ParcelFileDescriptor; +import android.os.Trace; import android.view.Surface; import dalvik.system.VMRuntime; @@ -925,6 +926,7 @@ public class ImageReader implements AutoCloseable { if (ir == null) { return; } + Trace.beginSection("android.media.ImageReader#postEventFromNative"); final Executor executor; final OnImageAvailableListener listener; @@ -948,6 +950,7 @@ public class ImageReader implements AutoCloseable { } }); } + Trace.endSection(); } /** diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 9548525d68d1..f5dc6ead374a 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -2345,6 +2345,15 @@ final public class MediaCodec { throw new IllegalArgumentException("Can't use crypto and descrambler together!"); } + // at the moment no codecs support detachable surface + if (android.media.codec.Flags.nullOutputSurface()) { + // Detached surface flag is only meaningful if surface is null. Otherwise, it is + // ignored. + if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) { + throw new IllegalArgumentException("Codec does not support detached surface"); + } + } + String[] keys = null; Object[] values = null; @@ -2419,7 +2428,8 @@ final public class MediaCodec { * output. * * @throws IllegalStateException if the codec was not - * configured in surface mode. + * configured in surface mode or if the codec does not support + * detaching the output surface. * @see CONFIGURE_FLAG_DETACHED_SURFACE */ @FlaggedApi(FLAG_NULL_OUTPUT_SURFACE) @@ -2429,6 +2439,7 @@ final public class MediaCodec { } // note: we still have a surface in detached mode, so keep mHasSurface // we also technically allow calling detachOutputSurface multiple times in a row + throw new IllegalStateException("codec does not support detaching output surface"); // native_detachSurface(); } @@ -4750,6 +4761,9 @@ final public class MediaCodec { } void setBufferInfo(MediaCodec.BufferInfo info) { + // since any of setBufferInfo(s) should translate to getBufferInfos, + // mBufferInfos needs to be reset for every setBufferInfo(s) + mBufferInfos.clear(); mPresentationTimeUs = info.presentationTimeUs; mFlags = info.flags; } diff --git a/media/java/android/media/tv/ad/TvAdManager.java b/media/java/android/media/tv/ad/TvAdManager.java index 76664a66ad53..ddcb25b15ccc 100644 --- a/media/java/android/media/tv/ad/TvAdManager.java +++ b/media/java/android/media/tv/ad/TvAdManager.java @@ -61,7 +61,6 @@ import java.util.concurrent.Executor; @FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) @SystemService(Context.TV_AD_SERVICE) public final class TvAdManager { - // TODO: implement more methods and unhide APIs. private static final String TAG = "TvAdManager"; /** diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 382e65dd4ba1..371e3d2deda5 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -16,11 +16,13 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "ImageReader_JNI" +#define ATRACE_TAG ATRACE_TAG_CAMERA #include "android_media_Utils.h" #include <cutils/atomic.h> #include <utils/Log.h> #include <utils/misc.h> #include <utils/List.h> +#include <utils/Trace.h> #include <utils/String8.h> #include <cstdio> @@ -223,6 +225,7 @@ JNIImageReaderContext::~JNIImageReaderContext() { void JNIImageReaderContext::onFrameAvailable(const BufferItem& /*item*/) { + ATRACE_CALL(); ALOGV("%s: frame available", __FUNCTION__); bool needsDetach = false; JNIEnv* env = getJNIEnv(&needsDetach); diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig index 0a2619c8a19a..ba084c0901c4 100644 --- a/nfc/java/android/nfc/flags.aconfig +++ b/nfc/java/android/nfc/flags.aconfig @@ -2,6 +2,7 @@ package: "android.nfc" flag { name: "enable_nfc_mainline" + is_exported: true namespace: "nfc" description: "Flag for NFC mainline changes" bug: "292140387" @@ -9,6 +10,7 @@ flag { flag { name: "enable_nfc_reader_option" + is_exported: true namespace: "nfc" description: "Flag for NFC reader option API changes" bug: "291187960" @@ -16,6 +18,7 @@ flag { flag { name: "enable_nfc_user_restriction" + is_exported: true namespace: "nfc" description: "Flag for NFC user restriction" bug: "291187960" @@ -23,6 +26,7 @@ flag { flag { name: "nfc_observe_mode" + is_exported: true namespace: "nfc" description: "Enable NFC Observe Mode" bug: "294217286" @@ -30,6 +34,7 @@ flag { flag { name: "nfc_read_polling_loop" + is_exported: true namespace: "nfc" description: "Enable NFC Polling Loop Notifications" bug: "294217286" @@ -65,6 +70,7 @@ flag { flag { name: "enable_nfc_set_discovery_tech" + is_exported: true namespace: "nfc" description: "Flag for NFC set discovery tech API" bug: "300351519" @@ -72,6 +78,7 @@ flag { flag { name: "nfc_vendor_cmd" + is_exported: true namespace: "nfc" description: "Enable NFC vendor command support" bug: "289879306" diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java index 4500a220523d..5dcfd3b0237d 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/DataBoostWebServiceFlow.java @@ -40,7 +40,7 @@ public class DataBoostWebServiceFlow { * * This can be called using the JavaScript below: * <script type="text/javascript"> - * function getRequestedCapability(duration) { + * function getRequestedCapability() { * DataBoostWebServiceFlow.getRequestedCapability(); * } * </script> @@ -57,6 +57,25 @@ public class DataBoostWebServiceFlow { * * This can be called using the JavaScript below: * <script type="text/javascript"> + * function notifyPurchaseSuccessful(duration_ms_long = 0) { + * DataBoostWebServiceFlow.notifyPurchaseSuccessful(duration_ms_long); + * } + * </script> + * + * @param duration The duration for which the premium capability is purchased in milliseconds. + * NOTE: The duration parameter is not used. + */ + @JavascriptInterface + public void notifyPurchaseSuccessful(long duration) { + mActivity.onPurchaseSuccessful(); + } + + /** + * Interface method allowing the carrier website to notify the slice purchase application of + * a successful premium capability purchase. + * + * This can be called using the JavaScript below: + * <script type="text/javascript"> * function notifyPurchaseSuccessful() { * DataBoostWebServiceFlow.notifyPurchaseSuccessful(); * } diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml index b9ed4a2564de..5d9295b4d6c8 100644 --- a/packages/CredentialManager/res/values-af/strings.xml +++ b/packages/CredentialManager/res/values-af/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Wagwoorde sal steeds saam met toegangsleutels beskikbaar wees terwyl ons na ’n wagwoordlose toekoms beweeg."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Kies waar om jou <xliff:g id="CREATETYPES">%1$s</xliff:g> te stoor"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Kies ’n wagwoordbestuurder om jou inligting te stoor en volgende keer vinniger aan te meld"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Wil jy toegangsleutel skep om by <xliff:g id="APPNAME">%1$s</xliff:g> aan te meld?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Wil jy wagwoord stoor om by <xliff:g id="APPNAME">%1$s</xliff:g> aan te meld?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Stoor aanmeldinligting vir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"toegangsleutel"</string> <string name="password" msgid="6738570945182936667">"wagwoord"</string> diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml index e1ded6ac39a7..2e8021d1d660 100644 --- a/packages/CredentialManager/res/values-am/strings.xml +++ b/packages/CredentialManager/res/values-am/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ወደ የይለፍ ቃል የሌለው ወደፊት ስንሄድ የይለፍ ቃላት ከይለፍ ቁልፎች ጎን ለጎን ይገኛሉ።"</string> <string name="choose_provider_title" msgid="8870795677024868108">"የእርስዎን <xliff:g id="CREATETYPES">%1$s</xliff:g> የት እንደሚያስቀምጡ ይምረጡ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"መረጃዎን ለማስቀመጥ እና በቀጣይ ጊዜ በፍጥነት በመለያ ለመግባት የሚስጥር ቁልፍ አስተዳዳሪን ይምረጡ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"ወደ <xliff:g id="APPNAME">%1$s</xliff:g> ለመግባት የይለፍ ቁልፍ ይፈጠር?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"ወደ <xliff:g id="APPNAME">%1$s</xliff:g> ለመግባት የይለፍ ቃል ይቀመጥ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"ለ<xliff:g id="APPNAME">%1$s</xliff:g> የመግቢያ መረጃ ይቀመጥ?"</string> <string name="passkey" msgid="632353688396759522">"የይለፍ ቁልፍ"</string> <string name="password" msgid="6738570945182936667">"የይለፍ ቃል"</string> diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml index be55469be98d..a2d328c13675 100644 --- a/packages/CredentialManager/res/values-ar/strings.xml +++ b/packages/CredentialManager/res/values-ar/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"بينما ننطلق نحو مستقبل بدون كلمات مرور، ستظل كلمات المرور متوفّرة إلى جانب مفاتيح المرور."</string> <string name="choose_provider_title" msgid="8870795677024868108">"اختيار المكان الذي تريد حفظ <xliff:g id="CREATETYPES">%1$s</xliff:g> فيه"</string> <string name="choose_provider_body" msgid="4967074531845147434">"اختَر مدير كلمات مرور لحفظ معلوماتك وتسجيل الدخول بشكل أسرع في المرة القادمة."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"هل تريد إنشاء مفتاح مرور لتسجيل الدخول إلى تطبيق <xliff:g id="APPNAME">%1$s</xliff:g>؟"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"هل تريد حفظ كلمة المرور لتسجيل الدخول إلى تطبيق <xliff:g id="APPNAME">%1$s</xliff:g>؟"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"هل تريد حفظ معلومات تسجيل الدخول لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\"؟"</string> <string name="passkey" msgid="632353688396759522">"مفتاح المرور"</string> <string name="password" msgid="6738570945182936667">"كلمة المرور"</string> diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml index 6b02ea71dedc..3efcea8d91b3 100644 --- a/packages/CredentialManager/res/values-as/strings.xml +++ b/packages/CredentialManager/res/values-as/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"আমি পাছৱৰ্ডবিহীন ভৱিষ্যতৰ দিশে আগবঢ়াৰ লগে লগে পাছকীৰ লগতে পাছৱৰ্ডসমূহো উপলব্ধ হ’ব।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"আপোনাৰ <xliff:g id="CREATETYPES">%1$s</xliff:g> ক’ত ছেভ কৰিব লাগে সেয়া বাছনি কৰক"</string> <string name="choose_provider_body" msgid="4967074531845147434">"আপোনাৰ তথ্য ছেভ কৰি পৰৱৰ্তী সময়ত দ্ৰুতভাৱে ছাইন ইন কৰিবলৈ এটা পাছৱৰ্ড পৰিচালক বাছনি কৰক"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ পাছকী সৃষ্টি কৰিবনে?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ পাছৱৰ্ড ছেভ কৰিবনে?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ বাবে ছাইন ইনৰ তথ্য ছেভ কৰিবনে?"</string> <string name="passkey" msgid="632353688396759522">"পাছকী"</string> <string name="password" msgid="6738570945182936667">"পাছৱৰ্ড"</string> diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml index caef7270860e..627e2c0979dc 100644 --- a/packages/CredentialManager/res/values-az/strings.xml +++ b/packages/CredentialManager/res/values-az/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də açarlar ilə yanaşı əlçatan olacaq."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> elementinin saxlanacağı yeri seçin"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Məlumatlarınızı yadda saxlamaq və növbəti dəfə daha sürətli daxil olmaq üçün parol meneceri seçin"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqinə daxil olmaq üçün giriş açarı yaradılsın?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqinə daxil olmaq üçün parol yadda saxlansın?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş məlumatları yadda saxlansın?"</string> <string name="passkey" msgid="632353688396759522">"açar"</string> <string name="password" msgid="6738570945182936667">"parol"</string> diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml index 0248a08e2a7b..c4111e44052a 100644 --- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo ka budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne kodove."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gde ćete sačuvati: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Izaberite menadžera lozinki da biste sačuvali podatke i brže se prijavili sledeći put"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Želite da napravite pristupni ključ da biste se prijavili u <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Želite da sačuvate lozinku da biste se prijavili u <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Želite da sačuvate podatke za prijavljivanje za: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni kôd"</string> <string name="password" msgid="6738570945182936667">"lozinka"</string> diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml index cc841d19adbd..f970d16a773b 100644 --- a/packages/CredentialManager/res/values-be/strings.xml +++ b/packages/CredentialManager/res/values-be/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Хоць мы ўжо рухаемся ў бок будучыні без выкарыстання пароляў, яны па-ранейшаму застануцца даступнымі нароўні з ключамі доступу."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Выберыце, куды захаваць <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Выберыце менеджар пароляў, каб захаваць свае даныя і забяспечыць хуткі ўваход у наступныя разы"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Стварыць ключ доступу для ўваходу ў праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Захаваць пароль для ўваходу ў праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Захаваць інфармацыю пра спосаб уваходу ў праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступу"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml index e7027c1d45da..e3758ea3b7bf 100644 --- a/packages/CredentialManager/res/values-bg/strings.xml +++ b/packages/CredentialManager/res/values-bg/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с ключовете за достъп по пътя ни към бъдеще без пароли."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Изберете къде да запазите своите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изберете мениджър на пароли, в който да се запазят данните ви, така че следващия път да влезете по-бързо в профила си"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Искате ли да създадете ключ за достъп, с който да влизате в(ъв) <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Искате ли да запазите паролата, за да влизате в(ъв) <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Да се запазят ли данните за вход за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"код за достъп"</string> <string name="password" msgid="6738570945182936667">"парола"</string> diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml index 49eb68c8216a..b6f9a88434f2 100644 --- a/packages/CredentialManager/res/values-bn/strings.xml +++ b/packages/CredentialManager/res/values-bn/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"আমরা পাসওয়ার্ডবিহীন ভবিষ্যতের দিকে এগিয়ে গেলেও, এখনও \'পাসকী\'-এর পাশাপাশি পাসওয়ার্ড ব্যবহার করা যাবে।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"আপনার <xliff:g id="CREATETYPES">%1$s</xliff:g> কোথায় সেভ করবেন তা বেছে নিন"</string> <string name="choose_provider_body" msgid="4967074531845147434">"আপনার তথ্য সেভ করতে একটি Password Manager বেছে নিন এবং পরের বার আরও দ্রুত সাইন-ইন করুন"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করার জন্য পাসকী তৈরি করবেন?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করার জন্য পাসওয়ার্ড সেভ করবেন?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>-এর জন্য সাইন-ইন সংক্রান্ত তথ্য সেভ করবেন?"</string> <string name="passkey" msgid="632353688396759522">"পাসকী"</string> <string name="password" msgid="6738570945182936667">"পাসওয়ার্ড"</string> diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml index afa4882a292e..6c00ac08d693 100644 --- a/packages/CredentialManager/res/values-bs/strings.xml +++ b/packages/CredentialManager/res/values-bs/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo prema budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne ključeve."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje će se pohranjivati <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja lozinki da sačuvate svoje informacije i brže se prijavite sljedeći put"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Kreirati pristupni ključ da se prijavite u aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Sačuvati lozinku da se prijavite u aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Sačuvati informacije o prijavi za aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string> <string name="password" msgid="6738570945182936667">"lozinka"</string> diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml index c937c09cd442..0d0850fdf151 100644 --- a/packages/CredentialManager/res/values-ca/strings.xml +++ b/packages/CredentialManager/res/values-ca/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Tot i que avancem cap a un futur sense contrasenyes, continuaran estant disponibles juntament amb les claus d\'accés."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Tria on vols desar les <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contrasenyes per desar la teva informació i iniciar la sessió més ràpidament la pròxima vegada"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Vols crear una clau d\'accés per iniciar la sessió a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Vols desar la contrasenya per iniciar la sessió a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vols desar la informació d\'inici de sessió per a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"clau d\'accés"</string> <string name="password" msgid="6738570945182936667">"contrasenya"</string> diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml index 06a81b02f7da..d21afe70cea7 100644 --- a/packages/CredentialManager/res/values-cs/strings.xml +++ b/packages/CredentialManager/res/values-cs/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Ačkoliv směřujeme k budoucnosti bez hesel, vedle přístupových klíčů budou stále k dispozici i hesla."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Určete, kam ukládat <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vyberte správce hesel k uložení svých údajů, abyste se příště mohli přihlásit rychleji"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Vytvořit přístupový klíč k přihlašování do aplikace <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Uložit heslo k přihlašování do aplikace <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Uložit přihlašovací údaje pro aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"přístupový klíč"</string> <string name="password" msgid="6738570945182936667">"heslo"</string> diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml index 207c33c7a6be..c868a4b9d69b 100644 --- a/packages/CredentialManager/res/values-da/strings.xml +++ b/packages/CredentialManager/res/values-da/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Selvom vi nærmer os en fremtid, hvor adgangskoder er mindre fremtrædende, kan de stadig bruges i samspil med adgangsnøgler."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Vælg, hvor du vil gemme dine <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vælg en adgangskodeadministrator for at gemme dine oplysninger, så du kan logge ind hurtigere næste gang"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Vil du oprette en adgangsnøgle for at logge ind på <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Vil du gemme adgangskoden for at logge ind på <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vil du gemme loginoplysningerne til <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"adgangsnøgle"</string> <string name="password" msgid="6738570945182936667">"adgangskode"</string> diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml index 38fa3e9a4faa..4fba522f5950 100644 --- a/packages/CredentialManager/res/values-de/strings.xml +++ b/packages/CredentialManager/res/values-de/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Auch wenn wir uns auf eine passwortlose Zukunft zubewegen, werden neben Passkeys weiter Passwörter verfügbar sein."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Wähle aus, wo deine <xliff:g id="CREATETYPES">%1$s</xliff:g> gespeichert werden sollen"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Du kannst einen Passwortmanager auswählen, um deine Anmeldedaten zu speichern, damit du dich nächstes Mal schneller anmelden kannst"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Passkey zur Anmeldung in <xliff:g id="APPNAME">%1$s</xliff:g> erstellen?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Passwort zur Anmeldung in <xliff:g id="APPNAME">%1$s</xliff:g> speichern?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Anmeldedaten für <xliff:g id="APPNAME">%1$s</xliff:g> speichern?"</string> <string name="passkey" msgid="632353688396759522">"Passkey"</string> <string name="password" msgid="6738570945182936667">"Passwort"</string> diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml index 509cfe6d34f3..ad6a4242b162 100644 --- a/packages/CredentialManager/res/values-el/strings.xml +++ b/packages/CredentialManager/res/values-el/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Καθώς κινούμαστε προς ένα μέλλον χωρίς κωδικούς πρόσβασης, οι κωδικοί πρόσβασης θα εξακολουθούν να είναι διαθέσιμοι μαζί με τα κλειδιά πρόσβασης."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Επιλέξτε πού θα αποθηκεύονται τα <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Επιλέξτε ένα πρόγραμμα διαχείρισης κωδικών πρόσβασης για να αποθηκεύσετε τα στοιχεία σας και να συνδεθείτε πιο γρήγορα την επόμενη φορά."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Δημιουργία κλειδιού πρόσβασης για σύνδεση στην εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Αποθήκευση κωδικού πρόσβασης για σύνδεση στην εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Αποθήκευση στοιχείων σύνδεσης για <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> <string name="passkey" msgid="632353688396759522">"κλειδί πρόσβασης"</string> <string name="password" msgid="6738570945182936667">"κωδικός πρόσβασης"</string> diff --git a/packages/CredentialManager/res/values-en-rAU/strings.xml b/packages/CredentialManager/res/values-en-rAU/strings.xml index cd63b41bc331..6aa1b5e16719 100644 --- a/packages/CredentialManager/res/values-en-rAU/strings.xml +++ b/packages/CredentialManager/res/values-en-rAU/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Create passkey to sign in to <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Save password to sign in to <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-en-rGB/strings.xml b/packages/CredentialManager/res/values-en-rGB/strings.xml index cd63b41bc331..6aa1b5e16719 100644 --- a/packages/CredentialManager/res/values-en-rGB/strings.xml +++ b/packages/CredentialManager/res/values-en-rGB/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Create passkey to sign in to <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Save password to sign in to <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-en-rIN/strings.xml b/packages/CredentialManager/res/values-en-rIN/strings.xml index cd63b41bc331..6aa1b5e16719 100644 --- a/packages/CredentialManager/res/values-en-rIN/strings.xml +++ b/packages/CredentialManager/res/values-en-rIN/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Create passkey to sign in to <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Save password to sign in to <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml index 29fb64db2ed2..6bab1aec0b74 100644 --- a/packages/CredentialManager/res/values-es-rUS/strings.xml +++ b/packages/CredentialManager/res/values-es-rUS/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"A medida que avanzamos hacia un futuro sin contraseñas, estas seguirán estando disponibles junto a las llaves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un administrador de contraseñas para guardar tu información y acceder más rápido la próxima vez"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"¿Quieres crear una llave de acceso para acceder a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"¿Quieres guardar la contraseña para acceder a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"¿Quieres guardar la información de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"llave de acceso"</string> <string name="password" msgid="6738570945182936667">"contraseña"</string> diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml index 077ea99ab0df..a727f4583431 100644 --- a/packages/CredentialManager/res/values-es/strings.xml +++ b/packages/CredentialManager/res/values-es/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Aunque nos dirigimos hacia un mundo sin contraseñas, estas seguirán estando disponibles junto con las llaves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contraseñas para guardar tu información e iniciar sesión más rápido la próxima vez"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"¿Crear llave de acceso para iniciar sesión en <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"¿Guardar contraseña para iniciar sesión en <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"¿Guardar la información de inicio de sesión de <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"llave de acceso"</string> <string name="password" msgid="6738570945182936667">"contraseña"</string> diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml index 6de564b9ed99..272761221063 100644 --- a/packages/CredentialManager/res/values-et/strings.xml +++ b/packages/CredentialManager/res/values-et/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Liikudes paroolivaba tuleviku poole, jäävad paroolid pääsuvõtmete kõrval siiski kättesaadavaks."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Valige, kuhu soovite oma <xliff:g id="CREATETYPES">%1$s</xliff:g> salvestada"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Valige paroolihaldur, et salvestada oma teave ja järgmisel korral kiiremini sisse logida"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Kas luua rakendusse <xliff:g id="APPNAME">%1$s</xliff:g> sisselogimiseks pääsuvõti?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Kas salvestada rakendusse <xliff:g id="APPNAME">%1$s</xliff:g> sisselogimiseks parool?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Kas salvestada rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> jaoks sisselogimisandmed?"</string> <string name="passkey" msgid="632353688396759522">"pääsuvõti"</string> <string name="password" msgid="6738570945182936667">"parool"</string> diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml index 018968cf6d70..f0debcc356ed 100644 --- a/packages/CredentialManager/res/values-eu/strings.xml +++ b/packages/CredentialManager/res/values-eu/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Pasahitzik gabeko etorkizun baterantz goazen arren, pasahitzek sarbide-gakoen bizikide izaten jarraituko dute."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Aukeratu non gorde <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Hautatu informazioa gordetzeko pasahitz-kudeatzaile bat eta hasi saioa bizkorrago hurrengoan"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioan saioa hasteko sarbide-gako bat sortu nahi duzu?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioan saioa hasteko pasahitza gorde nahi duzu?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioko saioa hasteko informazioa gorde nahi duzu?"</string> <string name="passkey" msgid="632353688396759522">"sarbide-gakoa"</string> <string name="password" msgid="6738570945182936667">"pasahitza"</string> diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml index 55a79d86a3f8..a88b3531c9bf 100644 --- a/packages/CredentialManager/res/values-fa/strings.xml +++ b/packages/CredentialManager/res/values-fa/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"درحالیکه بهسوی آیندهای بیگذرواژه حرکت میکنیم، گذرواژهها همچنان در کنار گذرکلیدها دردسترس خواهند بود"</string> <string name="choose_provider_title" msgid="8870795677024868108">"جایی را برای ذخیره کردن <xliff:g id="CREATETYPES">%1$s</xliff:g> انتخاب کنید"</string> <string name="choose_provider_body" msgid="4967074531845147434">"مدیر گذرواژهای انتخاب کنید تا اطلاعاتتان را ذخیره کنید و دفعه بعد سریعتر به سیستم وارد شوید"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"برای ورود به سیستم <xliff:g id="APPNAME">%1$s</xliff:g>، گذرکلید ایجاد شود؟"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"برای ورود به سیستم <xliff:g id="APPNAME">%1$s</xliff:g>، گذرواژه ذخیره شود؟"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"اطلاعات ورود به سیستم <xliff:g id="APPNAME">%1$s</xliff:g> ذخیره شود؟"</string> <string name="passkey" msgid="632353688396759522">"گذرکلید"</string> <string name="password" msgid="6738570945182936667">"گذرواژه"</string> diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml index 9f95720a22b4..82af70f5689a 100644 --- a/packages/CredentialManager/res/values-fi/strings.xml +++ b/packages/CredentialManager/res/values-fi/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kehitys kulkee kohti salasanatonta tulevaisuutta, mutta salasanat ovat edelleen käytettävissä avainkoodien ohella."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Valitse, minne <xliff:g id="CREATETYPES">%1$s</xliff:g> tallennetaan"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Valitse salasanojen ylläpitotyökalu, niin voit tallentaa tietosi ja kirjautua ensi kerralla nopeammin sisään"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Luodaanko avainkoodi sisäänkirjautumista (<xliff:g id="APPNAME">%1$s</xliff:g>) varten?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Tallennetaanko salasana sisäänkirjautumista (<xliff:g id="APPNAME">%1$s</xliff:g>) varten?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Tallennetaanko kirjautumistiedot (<xliff:g id="APPNAME">%1$s</xliff:g>)?"</string> <string name="passkey" msgid="632353688396759522">"avainkoodi"</string> <string name="password" msgid="6738570945182936667">"salasana"</string> diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml index 481fac9b1da6..61f2204e233a 100644 --- a/packages/CredentialManager/res/values-fr-rCA/strings.xml +++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos renseignements et vous connecter plus rapidement la prochaine fois"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Créer une clé d\'accès pour se connecter à <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Enregistrer un mot de passe pour se connecter à <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Enregistrer les renseignements de connexion pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string> <string name="password" msgid="6738570945182936667">"mot de passe"</string> diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml index 37df7fb1e83d..15715f3e8622 100644 --- a/packages/CredentialManager/res/values-fr/strings.xml +++ b/packages/CredentialManager/res/values-fr/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Nous nous dirigeons vers un futur sans mots de passe, mais ceux-ci resteront disponibles en plus des clés d\'accès."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choisissez où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos informations et vous connecter plus rapidement la prochaine fois"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Créer une clé d\'accès pour se connecter à <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Enregistrer un mot de passe pour se connecter à <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Enregistrer les informations de connexion pour <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string> <string name="password" msgid="6738570945182936667">"mot de passe"</string> diff --git a/packages/CredentialManager/res/values-gl/strings.xml b/packages/CredentialManager/res/values-gl/strings.xml index 8770465aecd6..1ca0774f97ee 100644 --- a/packages/CredentialManager/res/values-gl/strings.xml +++ b/packages/CredentialManager/res/values-gl/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Durante este percorrido cara a un futuro sen contrasinais, estes seguirán estando dispoñibles a canda as claves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolle onde queres gardar: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un xestor de contrasinais para gardar a túa información e iniciar sesión máis rápido a próxima vez"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Queres crear unha clave de acceso para iniciar sesión en <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Queres gardar o contrasinal para iniciar sesión en <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Queres gardar a información de inicio de sesión de <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"clave de acceso"</string> <string name="password" msgid="6738570945182936667">"contrasinal"</string> diff --git a/packages/CredentialManager/res/values-gu/strings.xml b/packages/CredentialManager/res/values-gu/strings.xml index efc88c13a3eb..7d8df9af144c 100644 --- a/packages/CredentialManager/res/values-gu/strings.xml +++ b/packages/CredentialManager/res/values-gu/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"આપણે પાસવર્ડ રહિત ભવિષ્ય તરફ આગળ વધી રહ્યાં છીએ, છતાં પાસકીની સાથોસાથ હજી પણ પાસવર્ડ ઉપલબ્ધ રહેશે."</string> <string name="choose_provider_title" msgid="8870795677024868108">"તમારી <xliff:g id="CREATETYPES">%1$s</xliff:g> ક્યાં સાચવવી તે પસંદ કરો"</string> <string name="choose_provider_body" msgid="4967074531845147434">"તમારી માહિતી સાચવવા માટે પાસવર્ડ મેનેજર પસંદ કરો અને આગલી વખતે વધુ ઝડપથી સાઇન ઇન કરો"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે પાસકી બનાવીએ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g>માં પાસવર્ડ સાચવવા માટે પાસકી બનાવીએ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> માટે સાઇન-ઇન કરવાની માહિતી સાચવીએ?"</string> <string name="passkey" msgid="632353688396759522">"પાસકી"</string> <string name="password" msgid="6738570945182936667">"પાસવર્ડ"</string> diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml index 661a4a227916..b644864dc5d6 100644 --- a/packages/CredentialManager/res/values-hi/strings.xml +++ b/packages/CredentialManager/res/values-hi/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"आने वाले समय में बिना पासवर्ड वाली टेक्नोलॉजी यानी पासकी का इस्तेमाल बढ़ेगा, हालांकि इसके साथ-साथ पासवर्ड भी इस्तेमाल किए जा सकेंगे."</string> <string name="choose_provider_title" msgid="8870795677024868108">"चुनें कि अपनी <xliff:g id="CREATETYPES">%1$s</xliff:g> कहां सेव करनी हैं"</string> <string name="choose_provider_body" msgid="4967074531845147434">"अपनी जानकारी सेव करने के लिए, पासवर्ड मैनेजर चुनें और अगली बार ज़्यादा तेज़ी से साइन इन करें"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> में साइन इन करने के लिए पासकी बनानी है?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> में साइन इन करने के लिए पासवर्ड सेव करना है?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> के लिए साइन-इन की जानकारी सेव करनी है?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml index eceb1b54c247..86d52d53350d 100644 --- a/packages/CredentialManager/res/values-hr/strings.xml +++ b/packages/CredentialManager/res/values-hr/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako idemo u smjeru budućnosti bez zaporki, one će i dalje biti dostupne uz pristupne ključeve."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje će se spremati <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja zaporki kako biste spremili svoje informacije i drugi se put brže prijavili"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Želite li izraditi pristupni ključ za prijavu u aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Želite li spremiti zaporku za prijavu u aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Spremiti informacije o prijavi za <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string> <string name="password" msgid="6738570945182936667">"zaporka"</string> diff --git a/packages/CredentialManager/res/values-hu/strings.xml b/packages/CredentialManager/res/values-hu/strings.xml index 3415eea3f06c..539feb44e32b 100644 --- a/packages/CredentialManager/res/values-hu/strings.xml +++ b/packages/CredentialManager/res/values-hu/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Miközben a jelszó nélküli jövő felé haladunk, a jelszavak továbbra is rendelkezésre állnak majd az azonosítókulcsok mellett."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Válassza ki, hogy hova szeretné menteni <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Válasszon jelszókezelőt, hogy menthesse az adatait, és gyorsabban jelentkezhessen be a következő alkalommal."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Létrehoz azonosítókulcsot a következőbe való bejelentkezéshez: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Menti a jelszót a következőbe való bejelentkezéshez: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Menti a bejelentkezési adatokat a következőhöz: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"azonosítókulcs"</string> <string name="password" msgid="6738570945182936667">"jelszó"</string> diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml index af803b4e7594..5f06a7a14ad5 100644 --- a/packages/CredentialManager/res/values-hy/strings.xml +++ b/packages/CredentialManager/res/values-hy/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Թեև մենք առանց գաղտնաբառերի ապագայի ճանապարհին ենք, դրանք դեռ հասանելի կլինեն անցաբառերի հետ մեկտեղ։"</string> <string name="choose_provider_title" msgid="8870795677024868108">"Նշեք, թե որտեղ եք ուզում պահել ձեր <xliff:g id="CREATETYPES">%1$s</xliff:g>ը"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Ընտրեք գաղտնաբառերի կառավարիչ՝ ձեր տեղեկությունները պահելու և հաջորդ անգամ ավելի արագ մուտք գործելու համար"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Ստեղծե՞լ անցաբառ՝ <xliff:g id="APPNAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Պահե՞լ գաղտնաբառը՝ <xliff:g id="APPNAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Պահե՞լ «<xliff:g id="APPNAME">%1$s</xliff:g>» հավելվածի մուտքի տվյալները"</string> <string name="passkey" msgid="632353688396759522">"անցաբառ"</string> <string name="password" msgid="6738570945182936667">"գաղտնաբառ"</string> diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml index 180c869a8430..ad8aeec4d59e 100644 --- a/packages/CredentialManager/res/values-in/strings.xml +++ b/packages/CredentialManager/res/values-in/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Sandi akan tetap tersedia bersama kunci sandi seiring perjalanan menuju era di mana sandi tidak diperlukan lagi."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat penyimpanan <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pilih pengelola sandi untuk menyimpan info Anda dan login lebih cepat lain kali"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Buat kunci sandi untuk login ke <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Simpan sandi untuk login ke <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Simpan info login untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"kunci sandi"</string> <string name="password" msgid="6738570945182936667">"sandi"</string> diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml index 332d15e4f888..bc6bdfc0aab8 100644 --- a/packages/CredentialManager/res/values-is/strings.xml +++ b/packages/CredentialManager/res/values-is/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Við stefnum að framtíð án aðgangsorða en aðgangsorð verða áfram í boði samhliða aðgangslyklum."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Veldu hvar þú vilt vista <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Veldu aðgangsorðastjórnun til að vista upplýsingarnar og vera fljótari að skrá þig inn næst"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Búa til aðgangslykil til að skrá þig inn á <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Vista aðgangsorð til að skrá þig inn á <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Viltu vista innskráningarupplýsingar fyrir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"aðgangslykill"</string> <string name="password" msgid="6738570945182936667">"aðgangsorð"</string> diff --git a/packages/CredentialManager/res/values-it/strings.xml b/packages/CredentialManager/res/values-it/strings.xml index 5c8333693033..2b0d83cce897 100644 --- a/packages/CredentialManager/res/values-it/strings.xml +++ b/packages/CredentialManager/res/values-it/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Il futuro sarà senza password, ma per ora saranno ancora disponibili insieme alle passkey."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Scegli dove salvare le <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Seleziona un gestore delle password per salvare i tuoi dati e accedere più velocemente la prossima volta"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Creare passkey per accedere all\'app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Salvare password per accedere all\'app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vuoi salvare i dati di accesso di <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml index 55fb9f2912b2..ee9dd5dd4f4e 100644 --- a/packages/CredentialManager/res/values-iw/strings.xml +++ b/packages/CredentialManager/res/values-iw/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"אנחנו מתקדמים לעבר עתיד ללא סיסמאות, אבל עדיין אפשר יהיה להשתמש בסיסמאות וגם במפתחות גישה."</string> <string name="choose_provider_title" msgid="8870795677024868108">"בחירת המקום לשמירה של <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"אפשר לבחור באחד משירותי ניהול הסיסמאות כדי לשמור את הפרטים ולהיכנס לחשבון מהר יותר בפעם הבאה"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"ליצור מפתח גישה כדי להיכנס לחשבון ב-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"לשמור את הסיסמה כדי להיכנס לחשבון ב-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"לשמור את פרטי הכניסה של <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"מפתח גישה"</string> <string name="password" msgid="6738570945182936667">"סיסמה"</string> diff --git a/packages/CredentialManager/res/values-ja/strings.xml b/packages/CredentialManager/res/values-ja/strings.xml index 1ffc7dbe931c..b60638b3973d 100644 --- a/packages/CredentialManager/res/values-ja/strings.xml +++ b/packages/CredentialManager/res/values-ja/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"将来的にパスワードレスに移行するにあたり、パスワードもパスキーと並行して引き続きご利用いただけます。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>の保存先を選択"</string> <string name="choose_provider_body" msgid="4967074531845147434">"パスワード マネージャーを選択して情報を保存しておくと、次回からすばやくログインできます"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> にログインするためにパスキーを作成しますか?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> にログインするためにパスワードを保存しますか?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> のログイン情報を保存しますか?"</string> <string name="passkey" msgid="632353688396759522">"パスキー"</string> <string name="password" msgid="6738570945182936667">"パスワード"</string> diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml index fdf079715181..c089f4a33788 100644 --- a/packages/CredentialManager/res/values-ka/strings.xml +++ b/packages/CredentialManager/res/values-ka/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"უპაროლო მომავალში პაროლები კვლავ ხელმისაწვდომი იქნება, წვდომის გასაღებებთან ერთად."</string> <string name="choose_provider_title" msgid="8870795677024868108">"აირჩიეთ სად შეინახოთ თქვენი <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"აირჩიეთ პაროლების მმართველი თქვენი ინფორმაციის შესანახად, რომ მომავალში უფრო სწრაფად შეხვიდეთ."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"შესასვლელად წვდომის გასაღების შექმნა: <xliff:g id="APPNAME">%1$s</xliff:g>"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"შესასვლელი პაროლის შენახვა: <xliff:g id="APPNAME">%1$s</xliff:g>"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"შეინახავთ <xliff:g id="APPNAME">%1$s</xliff:g> აპში შესვლის ინფორმაციას?"</string> <string name="passkey" msgid="632353688396759522">"წვდომის გასაღები"</string> <string name="password" msgid="6738570945182936667">"პაროლი"</string> diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml index 1c1b186f88d8..2200b1890450 100644 --- a/packages/CredentialManager/res/values-kk/strings.xml +++ b/packages/CredentialManager/res/values-kk/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Құпия сөзсіз болашақ жақын болғанына қарамастан, келешекте құпия сөздерді кіру кілттерімен қатар қолдана беруге болады."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> қайда сақталатынын таңдаңыз"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Мәліметіңізді сақтап, келесіде жылдам кіру үшін құпия сөз менеджерін таңдаңыз."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасына кіру үшін кіру кілті жасалсын ба?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасына кіру үшін құпия сөз сақталсын ба?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру мәліметін сақтау керек пе?"</string> <string name="passkey" msgid="632353688396759522">"Кіру кілті"</string> <string name="password" msgid="6738570945182936667">"құпия сөз"</string> diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml index 084087986f55..d0faaeca6fd4 100644 --- a/packages/CredentialManager/res/values-km/strings.xml +++ b/packages/CredentialManager/res/values-km/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"នៅពេលដែលយើងឈានទៅរកអនាគតដែលគ្មានពាក្យសម្ងាត់ ពាក្យសម្ងាត់នៅតែអាចប្រើបានរួមជាមួយកូដសម្ងាត់។"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ជ្រើសរើសកន្លែងដែលត្រូវរក្សាទុក<xliff:g id="CREATETYPES">%1$s</xliff:g>របស់អ្នក"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ជ្រើសរើសកម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ ដើម្បីរក្សាទុកព័ត៌មានរបស់អ្នក និងចូលគណនីបានកាន់តែរហ័សនៅពេលលើកក្រោយ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"បង្កើតកូដសម្ងាត់ ដើម្បីចូលគណនី <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"រក្សាទុកពាក្យសម្ងាត់ ដើម្បីចូលគណនី <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"រក្សាទុកព័ត៌មានអំពីការចូលគណនីសម្រាប់ <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> <string name="passkey" msgid="632353688396759522">"កូដសម្ងាត់"</string> <string name="password" msgid="6738570945182936667">"ពាក្យសម្ងាត់"</string> diff --git a/packages/CredentialManager/res/values-kn/strings.xml b/packages/CredentialManager/res/values-kn/strings.xml index 84549d1af0bc..59e3b5c14e28 100644 --- a/packages/CredentialManager/res/values-kn/strings.xml +++ b/packages/CredentialManager/res/values-kn/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ನಾವು ಪಾಸ್ವರ್ಡ್ ರಹಿತ ತಂತ್ರಜ್ಞಾನದ ಕಡೆಗೆ ಸಾಗುತ್ತಿರುವಾಗ, ಪಾಸ್ಕೀಗಳ ಜೊತೆಗೆ ಪಾಸ್ವರ್ಡ್ಗಳು ಇನ್ನೂ ಲಭ್ಯವಿರುತ್ತವೆ."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ನಿಮ್ಮ <xliff:g id="CREATETYPES">%1$s</xliff:g> ಎಲ್ಲಿ ಸೇವ್ ಆಗಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ನಿಮ್ಮ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸಲು ಪಾಸ್ವರ್ಡ್ ನಿರ್ವಾಹಕವನ್ನು ಆಯ್ಕೆಮಾಡಿ ಹಾಗೂ ಮುಂದಿನ ಬಾರಿ ವೇಗವಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಪಾಸ್ಕೀ ರಚಿಸುವುದೇ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ಸೇವ್ ಮಾಡುವುದೇ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> ಗಾಗಿ ಸೈನ್-ಇನ್ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸುವುದೇ?"</string> <string name="passkey" msgid="632353688396759522">"ಪಾಸ್ಕೀ"</string> <string name="password" msgid="6738570945182936667">"ಪಾಸ್ವರ್ಡ್"</string> diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml index 0c970dd3cae4..fd48d1849502 100644 --- a/packages/CredentialManager/res/values-ko/strings.xml +++ b/packages/CredentialManager/res/values-ko/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"비밀번호 없는 미래로 나아가는 과정에서 비밀번호는 여전히 패스키와 함께 사용될 것입니다."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> 저장 위치 선택"</string> <string name="choose_provider_body" msgid="4967074531845147434">"정보를 저장해서 다음에 더 빠르게 로그인하려면 비밀번호 관리자를 선택하세요."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"패스키를 생성하여 <xliff:g id="APPNAME">%1$s</xliff:g>에 로그인하시겠습니까?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"비밀번호를 저장하여 <xliff:g id="APPNAME">%1$s</xliff:g>에 로그인하시겠습니까?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>의 로그인 정보를 저장하시겠습니까?"</string> <string name="passkey" msgid="632353688396759522">"패스키"</string> <string name="password" msgid="6738570945182936667">"비밀번호"</string> diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml index 3937ff5afc31..6a0146257a31 100644 --- a/packages/CredentialManager/res/values-ky/strings.xml +++ b/packages/CredentialManager/res/values-ky/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Сырсөзсүз келечекти көздөй баратсак да, аларды киргизүүчү ачкычтар менен бирге колдоно берүүгө болот."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> кайда сакталарын тандаңыз"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Маалыматыңызды сактоо жана кийинки жолу тезирээк кирүү үчүн сырсөздөрдү башкаргычты тандаңыз"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосуна кирүү үчүн киргизүүчү ачкычты түзөсүзбү?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосуна кирүү үчүн сырсөздү сактайсызбы?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> үчүн кирүү маалыматы сакталсынбы?"</string> <string name="passkey" msgid="632353688396759522">"киргизүүчү ачкыч"</string> <string name="password" msgid="6738570945182936667">"сырсөз"</string> diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml index 79a31e8b1e8b..e71c60f96785 100644 --- a/packages/CredentialManager/res/values-lo/strings.xml +++ b/packages/CredentialManager/res/values-lo/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ໃນຂະນະທີ່ພວກເຮົາກ້າວໄປສູ່ອະນາຄົດທີ່ບໍ່ຕ້ອງໃຊ້ລະຫັດຜ່ານ, ລະຫັດຜ່ານຈະຍັງຄົງໃຊ້ໄດ້ຄວບຄູ່ໄປກັບກະແຈຜ່ານ."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ເລືອກບ່ອນທີ່ຈະບັນທຶກ <xliff:g id="CREATETYPES">%1$s</xliff:g> ຂອງທ່ານ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ເລືອກຕົວຈັດການລະຫັດຜ່ານເພື່ອບັນທຶກຂໍ້ມູນຂອງທ່ານ ແລະ ເຂົ້າສູ່ລະບົບໄວຂຶ້ນໃນເທື່ອຕໍ່ໄປ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"ສ້າງກະແຈຜ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"ບັນທຶກລະຫັດຜ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"ບັນທຶກຂໍ້ມູນການເຂົ້າສູ່ລະບົບສຳລັບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> <string name="passkey" msgid="632353688396759522">"ກະແຈຜ່ານ"</string> <string name="password" msgid="6738570945182936667">"ລະຫັດຜ່ານ"</string> diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml index e6bcd0685dca..55c5cd21d5cb 100644 --- a/packages/CredentialManager/res/values-lt/strings.xml +++ b/packages/CredentialManager/res/values-lt/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su prieigos raktais."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pasirinkite, kur išsaugoti „<xliff:g id="CREATETYPES">%1$s</xliff:g>“"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pasirinkite slaptažodžių tvarkyklę, kurią naudodami galėsite išsaugoti informaciją ir kitą kartą prisijungti greičiau"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Sukurti prieigos raktą, skirtą prisijungti prie „<xliff:g id="APPNAME">%1$s</xliff:g>“?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Sukurti slaptažodį, skirtą prisijungti prie „<xliff:g id="APPNAME">%1$s</xliff:g>“?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Išsaugoti prisijungimo prie „<xliff:g id="APPNAME">%1$s</xliff:g>“ informaciją?"</string> <string name="passkey" msgid="632353688396759522">"„passkey“"</string> <string name="password" msgid="6738570945182936667">"slaptažodis"</string> diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml index a62bf28223e8..2c0f8e1564b8 100644 --- a/packages/CredentialManager/res/values-lv/strings.xml +++ b/packages/CredentialManager/res/values-lv/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Lai arī pamazām notiek pāreja uz darbu bez parolēm, tās joprojām būs pieejamas līdzās piekļuves atslēgām."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Izvēlieties, kur saglabāt savas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Lai saglabātu informāciju un nākamreiz varētu pierakstīties ātrāk, atlasiet paroļu pārvaldnieku."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Vai izveidot piekļuves atslēgu, lai pierakstītos lietotnē <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Vai saglabāt paroli, lai pierakstītos lietotnē <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vai saglabāt pierakstīšanās informāciju lietotnei <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"piekļuves atslēga"</string> <string name="password" msgid="6738570945182936667">"parole"</string> diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml index b5d59969c7a4..6f8f76bd928c 100644 --- a/packages/CredentialManager/res/values-mk/strings.xml +++ b/packages/CredentialManager/res/values-mk/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Како што се движиме кон иднина без лозинки, лозинките сепак ќе бидат достапни покрај криптографските клучеви."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Изберете каде да ги зачувате вашите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изберете управник со лозинки за да ги зачувате вашите податоци и да се најавите побрзо следниот пат"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Да се создаде криптографски клуч за најавување на <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Да се зачува лозинката за најавување на <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Да се зачуваат податоците за најавување за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"криптографски клуч"</string> <string name="password" msgid="6738570945182936667">"лозинка"</string> diff --git a/packages/CredentialManager/res/values-ml/strings.xml b/packages/CredentialManager/res/values-ml/strings.xml index fcbd12b20cb0..ab32bc980068 100644 --- a/packages/CredentialManager/res/values-ml/strings.xml +++ b/packages/CredentialManager/res/values-ml/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"നമ്മൾ പാസ്വേഡ് രഹിത ഭാവിയിലേക്ക് ചുവടുവെച്ചുകൊണ്ടിരിക്കുകയാണ് എങ്കിലും, പാസ്കീകൾക്കൊപ്പം പാസ്വേഡുകൾ തുടർന്നും ലഭ്യമായിരിക്കും."</string> <string name="choose_provider_title" msgid="8870795677024868108">"നിങ്ങളുടെ <xliff:g id="CREATETYPES">%1$s</xliff:g> എവിടെയാണ് സംരക്ഷിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക"</string> <string name="choose_provider_body" msgid="4967074531845147434">"നിങ്ങളുടെ വിവരങ്ങൾ സംരക്ഷിക്കാനും അടുത്ത തവണ വേഗത്തിൽ സൈൻ ഇൻ ചെയ്യാനും ഒരു പാസ്വേഡ് മാനേജർ തിരഞ്ഞെടുക്കുക"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ പാസ്കീ സൃഷ്ടിക്കണോ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ പാസ്വേഡ് സംരക്ഷിക്കണോ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിനായി സൈൻ ഇൻ വിവരങ്ങൾ സംരക്ഷിക്കണോ?"</string> <string name="passkey" msgid="632353688396759522">"പാസ്കീ"</string> <string name="password" msgid="6738570945182936667">"പാസ്വേഡ്"</string> diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml index b0d4ca6bea2d..a704ea0efa32 100644 --- a/packages/CredentialManager/res/values-mn/strings.xml +++ b/packages/CredentialManager/res/values-mn/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь нэвтрэх түлхүүрийн хамтаар боломжтой хэвээр байх болно."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>-г хаана хадгалахаа сонгоно уу"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Мэдээллээ хадгалж, дараагийн удаа илүү хурдан нэвтрэхийн тулд нууц үгний менежерийг сонгоно уу"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g>-д нэвтрэхийн тулд нэвтрэх түлхүүр үүсгэх үү?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g>-д нэвтрэхийн тулд нууц үгийг хадгалах уу?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>-н нэвтрэх мэдээллийг хадгалах уу?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"нууц үг"</string> diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml index 5747afd88996..d3e14dde7ce3 100644 --- a/packages/CredentialManager/res/values-mr/strings.xml +++ b/packages/CredentialManager/res/values-mr/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"पासवर्ड न वापरणाऱ्या भविष्यात पुढे जाताना, पासवर्ड तरीही पासकीच्या बरोबरीने उपलब्ध असतील."</string> <string name="choose_provider_title" msgid="8870795677024868108">"तुमची <xliff:g id="CREATETYPES">%1$s</xliff:g> कुठे सेव्ह करायची ते निवडा"</string> <string name="choose_provider_body" msgid="4967074531845147434">"तुमची माहिती सेव्ह करण्यासाठी आणि पुढच्या वेळी जलद साइन इन करण्याकरिता Password Manager निवडा"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी पासकी तयार करायची आहे का?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी पासवर्ड सेव्ह करायचा आहे का?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> साठी साइन-इन माहिती सेव्ह करायची का?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> diff --git a/packages/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml index a6bc11d615f7..a491177b57ea 100644 --- a/packages/CredentialManager/res/values-ms/strings.xml +++ b/packages/CredentialManager/res/values-ms/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Meskipun masa depan kita nanti tidak memerlukan kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat untuk menyimpan <xliff:g id="CREATETYPES">%1$s</xliff:g> anda"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pilih Password Manager untuk menyimpan maklumat anda dan log masuk lebih pantas pada kali seterusnya"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Buat kunci laluan untuk log masuk ke <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Simpan kata laluan untuk log masuk ke <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Simpan maklumat log masuk untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"kunci laluan"</string> <string name="password" msgid="6738570945182936667">"kata laluan"</string> diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml index 55eed78176b4..b427a58ce8ac 100644 --- a/packages/CredentialManager/res/values-my/strings.xml +++ b/packages/CredentialManager/res/values-my/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"စကားဝှက်မသုံးခြင်း အနာဂတ်ဆီသို့ ရှေ့ဆက်ရာတွင် လျှို့ဝှက်ကီးများနှင့်အတူ စကားဝှက်များကို ဆက်လက်အသုံးပြုနိုင်ပါမည်။"</string> <string name="choose_provider_title" msgid="8870795677024868108">"သင်၏ <xliff:g id="CREATETYPES">%1$s</xliff:g> သိမ်းရန်နေရာ ရွေးခြင်း"</string> <string name="choose_provider_body" msgid="4967074531845147434">"သင့်အချက်အလက်သိမ်းပြီး နောက်တစ်ကြိမ်၌ ပိုမိုမြန်ဆန်စွာ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်မန်နေဂျာကို ရွေးပါ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> သို့ လက်မှတ်ထိုးဝင်ရန် လျှို့ဝှက်ကီး ပြုလုပ်မလား။"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> သို့ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်ကို သိမ်းမလား။"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> အတွက် လက်မှတ်ထိုးဝင်သည့်အချက်အလက်ကို သိမ်းမလား။"</string> <string name="passkey" msgid="632353688396759522">"လျှို့ဝှက်ကီး"</string> <string name="password" msgid="6738570945182936667">"စကားဝှက်"</string> diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml index f7c5762c0598..1e780ee5ed32 100644 --- a/packages/CredentialManager/res/values-nb/strings.xml +++ b/packages/CredentialManager/res/values-nb/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av passnøkler."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Velg hvor du vil lagre <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Velg et verktøy for passordlagring for å lagre informasjonen din og logge på raskere neste gang"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Vil du opprette en passnøkkel for å logge på <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Vil du lagre passordet for å logge på <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vil du lagre påloggingsinformasjon for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passnøkkel"</string> <string name="password" msgid="6738570945182936667">"passord"</string> diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml index bc3fc0ef1f09..55d4e87d740c 100644 --- a/packages/CredentialManager/res/values-ne/strings.xml +++ b/packages/CredentialManager/res/values-ne/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"हामी पासवर्डरहित भविष्यतर्फ बढ्दै गर्दा पासकीका साथसाथै पासवर्ड पनि उपलब्ध हुने छ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"तपाईं आफ्ना <xliff:g id="CREATETYPES">%1$s</xliff:g> कहाँ सेभ गर्न चाहनुहुन्छ भन्ने कुरा छनौट गर्नुहोस्"</string> <string name="choose_provider_body" msgid="4967074531845147434">"कुनै पासवर्ड म्यानेजरमा आफ्नो जानकारी सेभ गरी अर्को पटक अझ छिटो साइन इन गर्नुहोस्"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> मा साइन इन गर्न पासकी बनाउने हो?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> मा साइन इन गर्न पासवर्ड सेभ गर्ने हो?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> मा साइन गर्न प्रयोग गरिनु पर्ने जानकारी सेभ गर्ने हो?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> diff --git a/packages/CredentialManager/res/values-nl/strings.xml b/packages/CredentialManager/res/values-nl/strings.xml index d4ce16b9d023..53b3d70a2997 100644 --- a/packages/CredentialManager/res/values-nl/strings.xml +++ b/packages/CredentialManager/res/values-nl/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"We zijn op weg naar een wachtwoordloze toekomst, maar naast toegangssleutels kun je nog steeds gebruikmaken van wachtwoorden."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Kiezen waar je je <xliff:g id="CREATETYPES">%1$s</xliff:g> wilt opslaan"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecteer een wachtwoordmanager om je informatie op te slaan en de volgende keer sneller in te loggen"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Toegangssleutel maken om in te loggen bij <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Wachtwoord opslaan om in te loggen bij <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Inloggegevens opslaan voor <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"Toegangssleutel"</string> <string name="password" msgid="6738570945182936667">"wachtwoord"</string> diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml index 4ca9c396c94d..ad268c97bf03 100644 --- a/packages/CredentialManager/res/values-or/strings.xml +++ b/packages/CredentialManager/res/values-or/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ଆପଣଙ୍କ <xliff:g id="CREATETYPES">%1$s</xliff:g> କେଉଁଠାରେ ସେଭ କରିବେ ତାହା ବାଛନ୍ତୁ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ଆପଣଙ୍କ ସୂଚନା ସେଭ କରି ପରବର୍ତ୍ତୀ ସମୟରେ ଶୀଘ୍ର ସାଇନ ଇନ କରିବା ପାଇଁ ଏକ Password Manager ଚୟନ କରନ୍ତୁ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବାକୁ ପାସକୀ ତିଆରି କରିବେ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବାକୁ ପାସୱାର୍ଡ ସେଭ କରିବେ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ସାଇନ-ଇନର ସୂଚନା ସେଭ କରିବେ?"</string> <string name="passkey" msgid="632353688396759522">"ପାସକୀ"</string> <string name="password" msgid="6738570945182936667">"ପାସୱାର୍ଡ"</string> diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml index 414a4cebf87c..8328d4774bcc 100644 --- a/packages/CredentialManager/res/values-pa/strings.xml +++ b/packages/CredentialManager/res/values-pa/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ਹਾਲਾਂਕਿ, ਅਸੀਂ ਪਾਸਵਰਡ ਰਹਿਤ ਭਵਿੱਖ ਵੱਲ ਵਧ ਰਹੇ ਹਾਂ, ਪਰ ਪਾਸਕੀਆਂ ਦੇ ਨਾਲ ਪਾਸਵਰਡ ਹਾਲੇ ਵੀ ਉਪਲਬਧ ਹੋਣਗੇ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ਚੁਣੋ ਕਿ ਆਪਣੀਆਂ <xliff:g id="CREATETYPES">%1$s</xliff:g> ਨੂੰ ਕਿੱਥੇ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ਆਪਣੀ ਜਾਣਕਾਰੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਅਤੇ ਅਗਲੀ ਵਾਰ ਤੇਜ਼ੀ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ ਚੁਣੋ"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਲਈ ਸਾਈਨ-ਇਨ ਜਾਣਕਾਰੀ ਰੱਖਿਅਤ ਕਰਨੀ ਹੈ?"</string> <string name="passkey" msgid="632353688396759522">"ਪਾਸਕੀ"</string> <string name="password" msgid="6738570945182936667">"ਪਾਸਵਰਡ"</string> diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml index 91e227653eaf..7114c3a6fef3 100644 --- a/packages/CredentialManager/res/values-pl/strings.xml +++ b/packages/CredentialManager/res/values-pl/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"W czasie przechodzenia na technologie niewymagające haseł możliwość stosowania haseł – niezależnie od kluczy dostępu – wciąż będzie dostępna."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Wybierz, gdzie zapisywać <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Wybierz menedżera haseł, aby zapisywać informacje i logować się szybciej"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Utworzyć klucz dostępu do logowania w aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Zapisać hasło do logowania w aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Zapisać dane logowania do aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"klucz"</string> <string name="password" msgid="6738570945182936667">"hasło"</string> diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml index 105441f25267..0b03f721fd01 100644 --- a/packages/CredentialManager/res/values-pt-rBR/strings.xml +++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Criar chave de acesso para fazer login no app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Salvar senha para fazer login no app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Salvar informações de login do app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"senha"</string> diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml index f7259d8f9711..b4cf374e21bb 100644 --- a/packages/CredentialManager/res/values-pt-rPT/strings.xml +++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"À medida que avançamos para um futuro sem palavras-passe, as palavras-passe continuam disponíveis juntamente com as chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde guardar as suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gestor de palavras-passe para guardar as suas informações e iniciar sessão mais rapidamente da próxima vez"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Criar a chave de acesso para iniciar sessão na app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Guardar a palavra-passe para iniciar sessão na app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Guardar as informações de início de sessão da app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"palavra-passe"</string> diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml index 105441f25267..0b03f721fd01 100644 --- a/packages/CredentialManager/res/values-pt/strings.xml +++ b/packages/CredentialManager/res/values-pt/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Criar chave de acesso para fazer login no app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Salvar senha para fazer login no app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Salvar informações de login do app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"senha"</string> diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml index cfe61a96a382..8c865c4f8e7c 100644 --- a/packages/CredentialManager/res/values-ro/strings.xml +++ b/packages/CredentialManager/res/values-ro/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Ne îndreptăm spre un viitor fără parole, însă acestea sunt încă disponibile, alături de cheile de acces."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Alege unde dorești să salvezi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selectează un manager de parole pentru a salva informațiile și a te conecta mai rapid data viitoare"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Creezi o cheie de acces pentru a te conecta la <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Salvezi parola pentru a te conecta la <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Salvezi informațiile de conectare pentru <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"cheia de acces"</string> <string name="password" msgid="6738570945182936667">"parolă"</string> diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml index ba7d34ae7bd6..92eea321c5c8 100644 --- a/packages/CredentialManager/res/values-ru/strings.xml +++ b/packages/CredentialManager/res/values-ru/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Хотя движение к будущему без паролей уже началось, их по-прежнему можно будет использовать наряду с ключами доступа."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Укажите, куда нужно сохранить <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Выберите менеджер паролей, чтобы сохранять учетные данные и быстро выполнять вход."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Создать ключ доступа для входа в приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Сохранить ключ доступа для входа в приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Сохранить учетные данные для приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступа"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> diff --git a/packages/CredentialManager/res/values-si/strings.xml b/packages/CredentialManager/res/values-si/strings.xml index 03ada97da904..ec47018ce19b 100644 --- a/packages/CredentialManager/res/values-si/strings.xml +++ b/packages/CredentialManager/res/values-si/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"අපි මුරපද රහිත අනාගතයක් කරා ගමන් කරන විට, මුරයතුරු සමග මුරපද තවමත් පවතී."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ඔබේ <xliff:g id="CREATETYPES">%1$s</xliff:g> සුරැකිය යුතු ස්ථානය තෝරා ගන්න"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ඔබේ තතු සුරැකීමට සහ මීළඟ වතාවේ වේගයෙන් පුරනය වීමට මුරපද කළමනාකරුවෙකු තෝරන්න"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> වෙත පුරනය වීමට මුරයතුරක් තනන්න ද?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> වෙත පුරනය වීමට මුරපදය සුරකින්න ද?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> සඳහා පුරනය වීමේ තතු සුරකින්න ද?"</string> <string name="passkey" msgid="632353688396759522">"මුරයතුර"</string> <string name="password" msgid="6738570945182936667">"මුරපදය"</string> diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml index 7198625818e1..7426c9784252 100644 --- a/packages/CredentialManager/res/values-sk/strings.xml +++ b/packages/CredentialManager/res/values-sk/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Blížime sa k budúcnosti bez hesiel, ale heslá budú popri prístupových kľúčoch stále k dispozícii."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Vyberte, kam sa majú ukladať <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vyberte správcu hesiel, do ktorého sa budú ukladať vaše údaje, aby ste sa nabudúce mohli rýchlejšie prihlásiť"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Chcete vytvoriť prístupový kľúč na prihlasovanie do aplikácie <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Chcete uložiť heslo na prihlasovanie do aplikácie <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Chcete uložiť prihlasovacie údaje pre aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"prístupový kľúč"</string> <string name="password" msgid="6738570945182936667">"heslo"</string> diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml index 3ff85f0e41fb..8e085125884e 100644 --- a/packages/CredentialManager/res/values-sl/strings.xml +++ b/packages/CredentialManager/res/values-sl/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Na poti v prihodnost brez gesel bodo poleg ključev za dostop še vedno v uporabi tudi gesla."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Izbira mesta za shranjevanje <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Izberite upravitelja gesel za shranjevanje podatkov za prijavo, da se boste naslednjič lahko hitreje prijavili."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Želite ustvariti ključ za dostop za prijavo v aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Želite shraniti geslo za prijavo v aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Želite shraniti podatke za prijavo za aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ključ za dostop"</string> <string name="password" msgid="6738570945182936667">"geslo"</string> diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml index 41f63915771f..96f1ff0cc110 100644 --- a/packages/CredentialManager/res/values-sq/strings.xml +++ b/packages/CredentialManager/res/values-sq/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Teksa shkojmë drejt një të ardhmeje pa fjalëkalime, këto të fundit do të ofrohen ende së bashku me çelësat e kalimit."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Zgjidh se ku t\'i ruash <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Zgjidh një menaxher fjalëkalimesh për të ruajtur informacionet e tua dhe për t\'u identifikuar më shpejt herën tjetër"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Të krijohet një çelës kalimit për t\'u identifikuar në <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Të ruhet fjalëkalimi për t\'u identifikuar në <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Të ruhen informacionet e identifikimit për <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"çelësin e kalimit"</string> <string name="password" msgid="6738570945182936667">"fjalëkalimi"</string> diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml index 1a5567fe4c46..dae62bccdbe8 100644 --- a/packages/CredentialManager/res/values-sr/strings.xml +++ b/packages/CredentialManager/res/values-sr/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Како се крећемо ка будућности без лозинки, лозинке ће и даље бити доступне уз приступне кодове."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Одаберите где ћете сачувати: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изаберите менаџера лозинки да бисте сачували податке и брже се пријавили следећи пут"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Желите да направите приступни кључ да бисте се пријавили у <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Желите да сачувате лозинку да бисте се пријавили у <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Желите да сачувате податке за пријављивање за: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"приступни кôд"</string> <string name="password" msgid="6738570945182936667">"лозинка"</string> diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml index 8937b019ffc0..2326497f0dca 100644 --- a/packages/CredentialManager/res/values-sv/strings.xml +++ b/packages/CredentialManager/res/values-sv/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Medan vi beger oss mot en lösenordslös framtid kommer lösenord fortfarande att vara tillgängliga utöver nycklar."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Välj var du vill spara <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Välj en lösenordshanterare för att spara dina uppgifter och logga in snabbare nästa gång"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Vill du skapa en nyckel för att logga in i <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Vill du spara lösenordet för att logga in i <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vill du spara inloggningsuppgifterna för <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"nyckel"</string> <string name="password" msgid="6738570945182936667">"lösenord"</string> diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml index 051122f4ab71..6c39509a1925 100644 --- a/packages/CredentialManager/res/values-sw/strings.xml +++ b/packages/CredentialManager/res/values-sw/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Tunavyoelekea katika enzi isiyo ya manenosiri, manenosiri yataendelea kupatikana pamoja na funguo za siri."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Chagua ambako unahifadhi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Chagua kidhibiti cha manenosiri ili uhifadhi taarifa zako na uingie kwenye akaunti kwa urahisi wakati mwingine"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Ungependa kuunda ufunguo wa siri ili uingie katika <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Ungependa kuhifadhi nenosiri ili uingie katika <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Ungependa kuhifadhi maelezo ya kuingia katika akaunti kwa ajili ya <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ufunguo wa siri"</string> <string name="password" msgid="6738570945182936667">"nenosiri"</string> diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml index 64d4a2458cd0..6feb66f0141a 100644 --- a/packages/CredentialManager/res/values-ta/strings.xml +++ b/packages/CredentialManager/res/values-ta/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"கடவுச்சொல்லற்ற எதிர்காலத்தை நோக்கி நாம் பயணிக்கிறோம். கடவுச்சாவிகளைப் பயன்படுத்தும் இதே வேளையில் கடவுச்சொற்களையும் பயன்படுத்த முடியும்."</string> <string name="choose_provider_title" msgid="8870795677024868108">"உங்கள் <xliff:g id="CREATETYPES">%1$s</xliff:g> எங்கே சேமிக்கப்பட வேண்டும் என்பதைத் தேர்வுசெய்யுங்கள்"</string> <string name="choose_provider_body" msgid="4967074531845147434">"உங்கள் தகவல்களைச் சேமித்து அடுத்த முறை விரைவாக உள்நுழைய ஒரு கடவுச்சொல் நிர்வாகியைத் தேர்வுசெய்யுங்கள்"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய கடவுச்சாவியை உருவாக்கவா?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய கடவுச்சொல்லைச் சேமிக்கவா?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸுக்கான உள்நுழைவு விவரங்களைச் சேமிக்கவா?"</string> <string name="passkey" msgid="632353688396759522">"கடவுச்சாவி"</string> <string name="password" msgid="6738570945182936667">"கடவுச்சொல்"</string> diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml index 066f785282b1..bf3c1e0176cd 100644 --- a/packages/CredentialManager/res/values-te/strings.xml +++ b/packages/CredentialManager/res/values-te/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"మనం భవిష్యత్తులో పాస్వర్డ్ రహిత టెక్నాలజీని ఉపయోగించినా, పాస్కీలతో పాటు పాస్వర్డ్లు కూడా అందుబాటులో ఉంటాయి."</string> <string name="choose_provider_title" msgid="8870795677024868108">"మీ <xliff:g id="CREATETYPES">%1$s</xliff:g> ఎక్కడ సేవ్ చేయాలో ఎంచుకోండి"</string> <string name="choose_provider_body" msgid="4967074531845147434">"తర్వాతిసారి మరింత వేగంగా సైన్ ఇన్ చేసేందుకు వీలుగా మీ సమాచారాన్ని సేవ్ చేయడం కోసం ఒక పాస్వర్డ్ మేనేజర్ను ఎంచుకోండి"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g>కు సైన్ ఇన్ చేయడానికి పాస్-కీని క్రియేట్ చేయాలా?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g>కు సైన్ ఇన్ చేయడానికి పాస్వర్డ్ను సేవ్ చేయాలా?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> కోసం సైన్ ఇన్ సమాచారాన్ని సేవ్ చేయాలా?"</string> <string name="passkey" msgid="632353688396759522">"పాస్-కీ"</string> <string name="password" msgid="6738570945182936667">"పాస్వర్డ్"</string> diff --git a/packages/CredentialManager/res/values-th/strings.xml b/packages/CredentialManager/res/values-th/strings.xml index 783d05769b20..4fc8ba0ee980 100644 --- a/packages/CredentialManager/res/values-th/strings.xml +++ b/packages/CredentialManager/res/values-th/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ในขณะที่เราก้าวไปสู่อนาคตที่ไม่ต้องใช้รหัสผ่านนั้น รหัสผ่านจะยังคงใช้ได้อยู่ควบคู่ไปกับการเปลี่ยนไปใช้พาสคีย์"</string> <string name="choose_provider_title" msgid="8870795677024868108">"เลือกว่าต้องการบันทึก<xliff:g id="CREATETYPES">%1$s</xliff:g>ไว้ที่ใด"</string> <string name="choose_provider_body" msgid="4967074531845147434">"เลือกเครื่องมือจัดการรหัสผ่านเพื่อบันทึกข้อมูลและลงชื่อเข้าใช้เร็วขึ้นในครั้งถัดไป"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"สร้างพาสคีย์เพื่อลงชื่อเข้าใช้ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"บันทึกรหัสผ่านเพื่อลงชื่อเข้าใช้ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"บันทึกข้อมูลการลงชื่อเข้าใช้สำหรับ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string> <string name="passkey" msgid="632353688396759522">"พาสคีย์"</string> <string name="password" msgid="6738570945182936667">"รหัสผ่าน"</string> diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml index 18283eacdba0..e6bcaddf95f1 100644 --- a/packages/CredentialManager/res/values-tl/strings.xml +++ b/packages/CredentialManager/res/values-tl/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Habang lumalayo tayo sa mga password, magiging available pa rin ang mga password kasama ng mga passkey."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Piliin kung saan mo ise-save ang iyong <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pumili ng password manager para ma-save ang iyong impormasyon at makapag-sign in nang mas mabilis sa susunod na pagkakataon"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Gumawa ng passkey para mag-sign in sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"I-save ang password para mag-sign in sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"I-save ang impormasyon sa pag-sign in para sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml index 8778797d5968..f9455e7148a9 100644 --- a/packages/CredentialManager/res/values-tr/strings.xml +++ b/packages/CredentialManager/res/values-tr/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, geçiş anahtarlarıyla birlikte kullanılmaya devam edecektir."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> kaydedileceği yeri seçin"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Bilgilerinizi kaydedip bir dahaki sefere daha hızlı oturum açmak için bir şifre yöneticisi seçin"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasında oturum açmak için geçiş anahtarı oluşturulsun mu?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasında oturum açmak için şifre kaydedilsin mi?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> için oturum açma bilgileri kaydedilsin mi?"</string> <string name="passkey" msgid="632353688396759522">"Geçiş anahtarı"</string> <string name="password" msgid="6738570945182936667">"Şifre"</string> diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml index 53de1b313c34..e804777ffeca 100644 --- a/packages/CredentialManager/res/values-uk/strings.xml +++ b/packages/CredentialManager/res/values-uk/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами доступу."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Виберіть, де зберігати <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Виберіть менеджер паролів, щоб зберігати свої дані й надалі входити в облікові записи швидше"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Створити ключ доступу для входу в додаток <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Зберегти пароль для входу в додаток <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Зберегти дані для входу для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступу"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> diff --git a/packages/CredentialManager/res/values-ur/strings.xml b/packages/CredentialManager/res/values-ur/strings.xml index 47e33fb5aeaf..9562fdf2907a 100644 --- a/packages/CredentialManager/res/values-ur/strings.xml +++ b/packages/CredentialManager/res/values-ur/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"چونکہ ہم بغیر پاس ورڈ والے مستقبل کی طرف جا رہے ہیں اس کے باوجود پاس ورڈز پاس کیز کے ساتھ ہی دستیاب ہوں گے۔"</string> <string name="choose_provider_title" msgid="8870795677024868108">"منتخب کریں کہ آپ کی <xliff:g id="CREATETYPES">%1$s</xliff:g> کو کہاں محفوظ کرنا ہے"</string> <string name="choose_provider_body" msgid="4967074531845147434">"اپنی معلومات کو محفوظ کرنے اور اگلی بار تیزی سے سائن ان کرنے کے لیے پاس ورڈ مینیجر منتخب کریں"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> میں سائن ان کرنے کیلئے پاس کی تخلیق کریں؟"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> میں سائن ان کرنے کیلئے پاس ورڈ محفوظ کریں؟"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> کے لیے سائن ان کی معلومات محفوظ کریں؟"</string> <string name="passkey" msgid="632353688396759522">"پاس کی"</string> <string name="password" msgid="6738570945182936667">"پاس ورڈ"</string> diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml index 6025cae04b6c..4e27d3e71fd9 100644 --- a/packages/CredentialManager/res/values-uz/strings.xml +++ b/packages/CredentialManager/res/values-uz/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari harakatlanar ekanmiz, parollar kalitlar bilan birga ishlatilishda davom etadi."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Bu <xliff:g id="CREATETYPES">%1$s</xliff:g> qayerga saqlanishini tanlang"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Maʼlumotlaringizni saqlash va keyingi safar tez kirish uchun parollar menejerini tanlang"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasiga kirish uchun kirish kaliti yaratilsinmi?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasiga kirish uchun parol saqlansinmi?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kirish maʼlumoti saqlansinmi?"</string> <string name="passkey" msgid="632353688396759522">"kalit"</string> <string name="password" msgid="6738570945182936667">"parol"</string> diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml index 141103630ee3..c774b9342dec 100644 --- a/packages/CredentialManager/res/values-vi/strings.xml +++ b/packages/CredentialManager/res/values-vi/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá truy cập."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Chọn vị trí lưu <xliff:g id="CREATETYPES">%1$s</xliff:g> của bạn"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Hãy chọn một trình quản lý mật khẩu để lưu thông tin của bạn và đăng nhập nhanh hơn vào lần tới"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Tạo khoá truy cập để đăng nhập vào <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Lưu mật khẩu để đăng nhập vào <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Lưu thông tin đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"khoá đăng nhập"</string> <string name="password" msgid="6738570945182936667">"mật khẩu"</string> diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml index dcc226986d23..11448e9c4ae1 100644 --- a/packages/CredentialManager/res/values-zh-rCN/strings.xml +++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"在我们向无密码未来迈进的过程中,密码仍会与通行密钥并行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"选择保存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string> <string name="choose_provider_body" msgid="4967074531845147434">"请选择一款密码管理工具来保存您的信息,以便下次更快地登录"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"要创建通行密钥以便登录 <xliff:g id="APPNAME">%1$s</xliff:g> 吗?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"要保存密码以便登录 <xliff:g id="APPNAME">%1$s</xliff:g> 吗?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"要保存“<xliff:g id="APPNAME">%1$s</xliff:g>”的登录信息吗?"</string> <string name="passkey" msgid="632353688396759522">"通行密钥"</string> <string name="password" msgid="6738570945182936667">"密码"</string> diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml index 5e893f6d8d4c..8f6964393a46 100644 --- a/packages/CredentialManager/res/values-zh-rHK/strings.xml +++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"我們將會改用無密碼技術,而密碼仍可與密鑰並行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"選擇儲存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string> <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具即可儲存自己的資料,縮短下次登入的時間"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"要建立密鑰以登入「<xliff:g id="APPNAME">%1$s</xliff:g>」嗎?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"要儲存密碼以登入「<xliff:g id="APPNAME">%1$s</xliff:g>」嗎?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"要儲存「<xliff:g id="APPNAME">%1$s</xliff:g>」的登入資料嗎?"</string> <string name="passkey" msgid="632353688396759522">"密鑰"</string> <string name="password" msgid="6738570945182936667">"密碼"</string> diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml index 1e1dca491961..b5fa62c73545 100644 --- a/packages/CredentialManager/res/values-zh-rTW/strings.xml +++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"我們日後將改採無密碼技術,密碼仍可與密碼金鑰並行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"選擇要將<xliff:g id="CREATETYPES">%1$s</xliff:g>存在哪裡"</string> <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具並儲存資訊,下次就能更快登入"</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"要建立密碼金鑰以登入「<xliff:g id="APPNAME">%1$s</xliff:g>」嗎?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"要儲存密碼以登入「<xliff:g id="APPNAME">%1$s</xliff:g>」嗎?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"要儲存「<xliff:g id="APPNAME">%1$s</xliff:g>」的登入資訊嗎?"</string> <string name="passkey" msgid="632353688396759522">"密碼金鑰"</string> <string name="password" msgid="6738570945182936667">"密碼"</string> diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml index 72a1e8f43a0a..5915a735e9f8 100644 --- a/packages/CredentialManager/res/values-zu/strings.xml +++ b/packages/CredentialManager/res/values-zu/strings.xml @@ -39,10 +39,8 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Njengoba sibhekela kwikusasa elingenaphasiwedi, amagama ayimfihlo asazotholakala eceleni kokhiye bokudlula."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Khetha lapho ongagcina khona i-<xliff:g id="CREATETYPES">%1$s</xliff:g> yakho"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Khetha isiphathi sephasiwedi ukuze ulondoloze ulwazi lwakho futhi ungene ngemvume ngokushesha ngesikhathi esizayo."</string> - <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> - <skip /> - <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> - <skip /> + <string name="choose_create_option_passkey_title" msgid="7980430650778623135">"Sungula ukhiye wokudlula ukuze ungene ngemvume ku-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <string name="choose_create_option_password_title" msgid="6238446571944651980">"Londoloza iphasiwedi ukuze ungene ngemvume ku-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Londoloza ulwazi lokungena lwe-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ukhiye wokudlula"</string> <string name="password" msgid="6738570945182936667">"iphasiwedi"</string> diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt index 4f2fa790f9d7..6ba684d9dfcc 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt @@ -574,7 +574,7 @@ class CredentialAutofillService : AutofillService() { ) { viewNode.autofillId?.let { val domain = viewNode.webDomain - val request = viewNode.credentialManagerRequest + val request = viewNode.pendingCredentialRequest if (domain != null && request != null) { responseClientState.putBoolean( WEBVIEW_REQUESTED_CREDENTIAL_KEY, true) @@ -604,8 +604,8 @@ class CredentialAutofillService : AutofillService() { sessionId: Int ): MutableList<CredentialOption> { val credentialOptions: MutableList<CredentialOption> = mutableListOf() - if (Flags.autofillCredmanDevIntegration() && viewNode.credentialManagerRequest != null) { - viewNode.credentialManagerRequest + if (Flags.autofillCredmanDevIntegration() && viewNode.pendingCredentialRequest != null) { + viewNode.pendingCredentialRequest ?.getCredentialOptions() ?.forEach { credentialOption -> credentialOption.candidateQueryData diff --git a/packages/EasterEgg/res/values-night/styles.xml b/packages/EasterEgg/res/values-night/styles.xml index 4edf6926da41..6ea2eaee821c 100644 --- a/packages/EasterEgg/res/values-night/styles.xml +++ b/packages/EasterEgg/res/values-night/styles.xml @@ -15,7 +15,7 @@ --> <resources> <style name="AppTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"> - <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> + <item name="android:windowLayoutInDisplayCutoutMode">always</item> <item name="android:windowLightNavigationBar">false</item> </style> </resources> diff --git a/packages/EasterEgg/res/values/styles.xml b/packages/EasterEgg/res/values/styles.xml index e576526f49b7..4a2cb48f60e5 100644 --- a/packages/EasterEgg/res/values/styles.xml +++ b/packages/EasterEgg/res/values/styles.xml @@ -16,7 +16,7 @@ <resources> <style name="AppTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen"> - <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> + <item name="android:windowLayoutInDisplayCutoutMode">always</item> <item name="android:windowLightNavigationBar">true</item> </style> diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreFileArchiver.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreFileArchiver.kt index 621a8d758d65..9d3fb66c7ce0 100644 --- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreFileArchiver.kt +++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreFileArchiver.kt @@ -62,7 +62,7 @@ internal class BackupRestoreFileArchiver( } Log.i(LOG_TAG, "[$name] Restore ${data.size()} bytes for $key to $file") val inputStream = LimitedNoCloseInputStream(data) - checksum.reset() + val checksum = createChecksum() val checkedInputStream = CheckedInputStream(inputStream, checksum) try { val codec = BackupCodec.fromId(checkedInputStream.read().toByte()) diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreStorage.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreStorage.kt index ea2fb727f56e..c4c00cbb8191 100644 --- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreStorage.kt +++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/BackupRestoreStorage.kt @@ -36,6 +36,7 @@ import java.io.OutputStream import java.util.zip.CRC32 import java.util.zip.CheckedInputStream import java.util.zip.CheckedOutputStream +import java.util.zip.Checksum internal const val LOG_TAG = "BackupRestoreStorage" @@ -54,15 +55,6 @@ abstract class BackupRestoreStorage : BackupHelper { */ abstract val name: String - private val entities: List<BackupRestoreEntity> by lazy { createBackupRestoreEntities() } - - /** - * Checksum of the data. - * - * Always call [java.util.zip.Checksum.reset] before using it. - */ - protected val checksum = CRC32() - /** * Entity states represented by checksum. * @@ -70,13 +62,16 @@ abstract class BackupRestoreStorage : BackupHelper { */ protected val entityStates = MutableScatterMap<String, Long>() + /** Entities created by [createBackupRestoreEntities]. This field is for restore only. */ + private var entities: List<BackupRestoreEntity>? = null + /** Entities to back up and restore. */ abstract fun createBackupRestoreEntities(): List<BackupRestoreEntity> /** Default codec used to encode/decode the entity data. */ open fun defaultCodec(): BackupCodec = BackupZipCodec.BEST_COMPRESSION - override fun performBackup( + final override fun performBackup( oldState: ParcelFileDescriptor?, data: BackupDataOutput, newState: ParcelFileDescriptor, @@ -88,6 +83,9 @@ abstract class BackupRestoreStorage : BackupHelper { return } Log.i(LOG_TAG, "[$name] Backup start") + val checksum = createChecksum() + // recreate entities for backup to avoid stale states + val entities = createBackupRestoreEntities() for (entity in entities) { val key = entity.key val outputStream = ByteArrayOutputStream() @@ -103,7 +101,8 @@ abstract class BackupRestoreStorage : BackupHelper { } when (result) { EntityBackupResult.UPDATE -> { - if (updateEntityState(key)) { + val value = checksum.value + if (entityStates.put(key, value) != value) { val payload = outputStream.toByteArray() val size = payload.size data.writeEntityHeader(key, size) @@ -126,15 +125,10 @@ abstract class BackupRestoreStorage : BackupHelper { } } } - newState.writeEntityStates(entityStates) + newState.writeAndClearEntityStates() Log.i(LOG_TAG, "[$name] Backup end") } - private fun updateEntityState(key: String): Boolean { - val value = checksum.value - return entityStates.put(key, value) != value - } - /** Returns if backup is enabled. */ open fun enableBackup(backupContext: BackupContext): Boolean = true @@ -144,13 +138,14 @@ abstract class BackupRestoreStorage : BackupHelper { return codec.encode(outputStream) } + /** This callback is invoked for every backed up entity. */ override fun restoreEntity(data: BackupDataInputStream) { val key = data.key if (!enableRestore()) { Log.i(LOG_TAG, "[$name] Restore disabled, ignore entity $key") return } - val entity = entities.firstOrNull { it.key == key } + val entity = ensureEntities().firstOrNull { it.key == key } if (entity == null) { Log.w(LOG_TAG, "[$name] Cannot find handler for entity $key") return @@ -159,7 +154,7 @@ abstract class BackupRestoreStorage : BackupHelper { val restoreContext = RestoreContext(key) val codec = entity.codec() ?: defaultCodec() val inputStream = LimitedNoCloseInputStream(data) - checksum.reset() + val checksum = createChecksum() val checkedInputStream = CheckedInputStream(inputStream, checksum) try { entity.restore(restoreContext, wrapRestoreInputStream(codec, checkedInputStream)) @@ -169,6 +164,9 @@ abstract class BackupRestoreStorage : BackupHelper { } } + private fun ensureEntities(): List<BackupRestoreEntity> = + entities ?: createBackupRestoreEntities().also { entities = it } + /** Returns if restore is enabled. */ open fun enableRestore(): Boolean = true @@ -185,7 +183,8 @@ abstract class BackupRestoreStorage : BackupHelper { } final override fun writeNewStateDescription(newState: ParcelFileDescriptor) { - newState.writeEntityStates(entityStates) + entities = null // clear to reduce memory footprint + newState.writeAndClearEntityStates() onRestoreFinished() } @@ -223,24 +222,29 @@ abstract class BackupRestoreStorage : BackupHelper { } } - private fun ParcelFileDescriptor.writeEntityStates(state: MutableScatterMap<String, Long>) { + private fun ParcelFileDescriptor.writeAndClearEntityStates() { // do not close the streams val fileOutputStream = FileOutputStream(fileDescriptor) val dataOutputStream = DataOutputStream(fileOutputStream) try { dataOutputStream.writeByte(STATE_VERSION.toInt()) - dataOutputStream.writeInt(state.size) - state.forEach { key, value -> + dataOutputStream.writeInt(entityStates.size) + entityStates.forEach { key, value -> dataOutputStream.writeUTF(key) dataOutputStream.writeLong(value) } } catch (exception: Exception) { Log.e(LOG_TAG, "[$name] Fail to write state file", exception) } + entityStates.clear() + entityStates.trim() // trim to reduce memory footprint } companion object { private const val STATE_VERSION: Byte = 0 + + /** Checksum for entity backup data. */ + fun createChecksum(): Checksum = CRC32() } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetButtonPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetButtonPreference.kt index 986602394b3b..3f74ed5e2814 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetButtonPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetButtonPreference.kt @@ -36,7 +36,7 @@ fun TwoTargetButtonPreference( TwoTargetPreference( title = title, summary = summary, - onClick = onClick, + primaryOnClick = onClick, icon = icon, ) { IconButton(onClick = onButtonClick) { diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt index 3216e37b5db4..3f688045fa19 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt @@ -34,7 +34,8 @@ import com.android.settingslib.spa.framework.theme.divider internal fun TwoTargetPreference( title: String, summary: () -> String, - onClick: () -> Unit, + primaryEnabled: () -> Boolean = { true }, + primaryOnClick: (() -> Unit)?, icon: @Composable (() -> Unit)? = null, widget: @Composable () -> Unit, ) { @@ -50,7 +51,8 @@ internal fun TwoTargetPreference( override val title = title override val summary = summary override val icon = icon - override val onClick = onClick + override val enabled = primaryEnabled + override val onClick = primaryOnClick } ) } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt index 7eed74588fb2..8b546b4de069 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreference.kt @@ -24,13 +24,15 @@ import com.android.settingslib.spa.widget.ui.SettingsSwitch fun TwoTargetSwitchPreference( model: SwitchPreferenceModel, icon: @Composable (() -> Unit)? = null, - onClick: () -> Unit, + primaryEnabled: () -> Boolean = { true }, + primaryOnClick: (() -> Unit)?, ) { EntryHighlight { TwoTargetPreference( title = model.title, summary = model.summary, - onClick = onClick, + primaryEnabled = primaryEnabled, + primaryOnClick = primaryOnClick, icon = icon, ) { SettingsSwitch( diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreferenceTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreferenceTest.kt index 3455851a10bb..0acf2878bf0c 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreferenceTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/TwoTargetSwitchPreferenceTest.kt @@ -23,6 +23,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertIsOff import androidx.compose.ui.test.assertIsOn import androidx.compose.ui.test.isToggleable @@ -46,7 +47,7 @@ class TwoTargetSwitchPreferenceTest { TestTwoTargetSwitchPreference(changeable = true) } - composeTestRule.onNodeWithText("TwoTargetSwitchPreference").assertIsDisplayed() + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed() } @Test @@ -79,7 +80,7 @@ class TwoTargetSwitchPreferenceTest { } @Test - fun clickable_canBeClick() { + fun clickable_primaryEnabled_canBeClick() { var clicked = false composeTestRule.setContent { TestTwoTargetSwitchPreference(changeable = false) { @@ -87,26 +88,54 @@ class TwoTargetSwitchPreferenceTest { } } - composeTestRule.onNodeWithText("TwoTargetSwitchPreference").performClick() + composeTestRule.onNodeWithText(TITLE).performClick() assertThat(clicked).isTrue() } -} -@Composable -private fun TestTwoTargetSwitchPreference( - changeable: Boolean, - onClick: () -> Unit = {}, -) { - var checked by rememberSaveable { mutableStateOf(false) } - TwoTargetSwitchPreference( - model = remember { - object : SwitchPreferenceModel { - override val title = "TwoTargetSwitchPreference" - override val checked = { checked } - override val changeable = { changeable } - override val onCheckedChange = { newChecked: Boolean -> checked = newChecked } + @Test + fun clickable_primaryNotEnabled_assertIsNotEnabled() { + composeTestRule.setContent { + TestTwoTargetSwitchPreference(changeable = false, primaryEnabled = false) + } + + composeTestRule.onNodeWithText(TITLE).assertIsNotEnabled() + } + + @Test + fun clickable_primaryNotEnabled_canNotBeClick() { + var clicked = false + composeTestRule.setContent { + TestTwoTargetSwitchPreference(changeable = false, primaryEnabled = false) { + clicked = true } - }, - onClick = onClick, - ) + } + + composeTestRule.onNodeWithText(TITLE).performClick() + assertThat(clicked).isFalse() + } + + @Composable + private fun TestTwoTargetSwitchPreference( + changeable: Boolean, + primaryEnabled: Boolean = true, + primaryOnClick: () -> Unit = {}, + ) { + var checked by rememberSaveable { mutableStateOf(false) } + TwoTargetSwitchPreference( + model = remember { + object : SwitchPreferenceModel { + override val title = TITLE + override val checked = { checked } + override val changeable = { changeable } + override val onCheckedChange = { newChecked: Boolean -> checked = newChecked } + } + }, + primaryEnabled = { primaryEnabled }, + primaryOnClick = primaryOnClick, + ) + } + + private companion object { + const val TITLE = "Title" + } } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItem.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItem.kt index bea14c360238..5c2d7701fd6f 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItem.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppListTwoTargetSwitchItem.kt @@ -38,6 +38,6 @@ fun <T : AppRecord> AppListItemModel<T>.AppListTwoTargetSwitchItem( override val onCheckedChange = onCheckedChange }, icon = { AppIcon(record.app, SettingsDimension.appIconItemSize) }, - onClick = onClick, + primaryOnClick = onClick, ) } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreference.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreference.kt index ac85dd4249f6..389b3c1b4be4 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreference.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedPreference.kt @@ -54,14 +54,27 @@ internal fun RestrictedPreference( return } val restrictedMode = restrictionsProviderFactory.rememberRestrictedMode(restrictions).value - val restrictedSwitchModel = remember(restrictedMode) { + val restrictedModel = remember(restrictedMode) { RestrictedPreferenceModel(model, restrictedMode) } - restrictedSwitchModel.RestrictionWrapper { - Preference(restrictedSwitchModel) + restrictedModel.RestrictionWrapper { + Preference(restrictedModel) } } +internal fun RestrictedMode?.restrictEnabled(enabled: () -> Boolean) = when (this) { + NoRestricted -> enabled + else -> ({ false }) +} + +internal fun <T> RestrictedMode?.restrictOnClick(onClick: T): T? = when (this) { + NoRestricted -> onClick + // Need to passthrough onClick for clickable semantics, although since enabled is false so + // this will not be called. + BaseUserRestricted -> onClick + else -> null +} + private class RestrictedPreferenceModel( model: PreferenceModel, private val restrictedMode: RestrictedMode?, @@ -69,19 +82,8 @@ private class RestrictedPreferenceModel( override val title = model.title override val summary = model.summary override val icon = model.icon - - override val enabled = when (restrictedMode) { - NoRestricted -> model.enabled - else -> ({ false }) - } - - override val onClick = when (restrictedMode) { - NoRestricted -> model.onClick - // Need to passthrough onClick for clickable semantics, although since enabled is false so - // this will not be called. - BaseUserRestricted -> model.onClick - else -> null - } + override val enabled = restrictedMode.restrictEnabled(model.enabled) + override val onClick = restrictedMode.restrictOnClick(model.onClick) @Composable fun RestrictionWrapper(content: @Composable () -> Unit) { diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt index aba3460fc1b9..5dfecb0b7bd4 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt @@ -60,18 +60,9 @@ internal class RestrictedSwitchPreferenceModel( is BlockedByEcm -> model.checked } - override val changeable = if (restrictedMode is NoRestricted) model.changeable else ({ false }) - - override val onCheckedChange = when (restrictedMode) { - null -> null - is NoRestricted -> model.onCheckedChange - // Need to passthrough onCheckedChange for toggleable semantics, although since changeable - // is false so this will not be called. - is BaseUserRestricted -> model.onCheckedChange - // Pass null since semantics ToggleableState is provided in RestrictionWrapper. - is BlockedByAdmin -> null - is BlockedByEcm -> null - } + override val changeable = restrictedMode.restrictEnabled(model.changeable) + + override val onCheckedChange = restrictedMode.restrictOnClick(model.onCheckedChange) @Composable fun RestrictionWrapper(content: @Composable () -> Unit) { @@ -116,13 +107,12 @@ internal class RestrictedSwitchPreferenceModel( companion object { @Composable - fun RestrictionsProviderFactory.RestrictedSwitchWrapper( + fun RestrictedSwitchWrapper( model: SwitchPreferenceModel, - restrictions: Restrictions, + restrictedMode: RestrictedMode?, content: @Composable (SwitchPreferenceModel) -> Unit, ) { val context = LocalContext.current - val restrictedMode = rememberRestrictedMode(restrictions).value val restrictedSwitchPreferenceModel = remember(restrictedMode) { RestrictedSwitchPreferenceModel(context, model, restrictedMode) } @@ -131,6 +121,15 @@ internal class RestrictedSwitchPreferenceModel( } } + @Composable + fun RestrictionsProviderFactory.RestrictedSwitchWrapper( + model: SwitchPreferenceModel, + restrictions: Restrictions, + content: @Composable (SwitchPreferenceModel) -> Unit, + ) { + RestrictedSwitchWrapper(model, rememberRestrictedMode(restrictions).value, content) + } + fun getSummary( context: Context, restrictedModeSupplier: () -> RestrictedMode?, diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreference.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreference.kt new file mode 100644 index 000000000000..e100773b2358 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreference.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.settingslib.spaprivileged.template.preference + +import androidx.annotation.VisibleForTesting +import androidx.compose.runtime.Composable +import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel +import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderFactory +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl +import com.android.settingslib.spaprivileged.model.enterprise.rememberRestrictedMode +import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreferenceModel.Companion.RestrictedSwitchWrapper + +@Composable +fun RestrictedTwoTargetSwitchPreference( + model: SwitchPreferenceModel, + icon: @Composable (() -> Unit)? = null, + restrictions: Restrictions, + primaryEnabled: () -> Boolean = { true }, + primaryOnClick: (() -> Unit)?, +) { + RestrictedTwoTargetSwitchPreference( + model = model, + icon = icon, + primaryEnabled = primaryEnabled, + primaryOnClick = primaryOnClick, + restrictions = restrictions, + restrictionsProviderFactory = ::RestrictionsProviderImpl, + ) +} + +@VisibleForTesting +@Composable +internal fun RestrictedTwoTargetSwitchPreference( + model: SwitchPreferenceModel, + icon: @Composable (() -> Unit)? = null, + primaryEnabled: () -> Boolean = { true }, + primaryOnClick: (() -> Unit)?, + restrictions: Restrictions, + restrictionsProviderFactory: RestrictionsProviderFactory, +) { + if (restrictions.isEmpty()) { + TwoTargetSwitchPreference(model, icon, primaryEnabled, primaryOnClick) + return + } + val restrictedMode = restrictionsProviderFactory.rememberRestrictedMode(restrictions).value + RestrictedSwitchWrapper(model, restrictedMode) { restrictedModel -> + TwoTargetSwitchPreference( + model = restrictedModel, + icon = icon, + primaryEnabled = restrictedMode.restrictEnabled(primaryEnabled), + primaryOnClick = restrictedMode.restrictOnClick(primaryOnClick), + ) + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt new file mode 100644 index 000000000000..bdff89f6d69b --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedTwoTargetSwitchPreferenceTest.kt @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.settingslib.spaprivileged.template.preference + +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.isOff +import androidx.compose.ui.test.isOn +import androidx.compose.ui.test.isToggleable +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel +import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted +import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.tests.testutils.FakeBlockedByAdmin +import com.android.settingslib.spaprivileged.tests.testutils.FakeBlockedByEcm +import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class RestrictedTwoTargetSwitchPreferenceTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val fakeBlockedByAdmin = FakeBlockedByAdmin() + private val fakeBlockedByEcm = FakeBlockedByEcm() + + private val fakeRestrictionsProvider = FakeRestrictionsProvider() + + private val switchPreferenceModel = object : SwitchPreferenceModel { + override val title = TITLE + private val checkedState = mutableStateOf(true) + override val checked = { checkedState.value } + override val onCheckedChange: (Boolean) -> Unit = { checkedState.value = it } + } + + @Test + fun whenRestrictionsKeysIsEmpty_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNode(isOn()).assertIsDisplayed() + } + + @Test + fun whenRestrictionsKeysIsEmpty_toggleable() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + composeTestRule.onNode(isToggleable()).performClick() + + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenNoRestricted_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNode(isOn()).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenNoRestricted_toggleable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + composeTestRule.onNode(isToggleable()).performClick() + + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenBaseUserRestricted_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsNotEnabled() + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenBaseUserRestricted_notToggleable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + composeTestRule.onNode(isToggleable()).performClick() + + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test + fun whenBlockedByAdmin_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNodeWithText(FakeBlockedByAdmin.SUMMARY).assertIsDisplayed() + composeTestRule.onNode(isOn()).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenBlockedByAdmin_clickPrimary() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + composeTestRule.onNodeWithText(TITLE).performClick() + + assertThat(fakeBlockedByAdmin.sendShowAdminSupportDetailsIntentIsCalled).isTrue() + } + + @Test + fun whenBlockedByAdmin_clickSwitch() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + composeTestRule.onNode(isToggleable()).performClick() + + assertThat(fakeBlockedByAdmin.sendShowAdminSupportDetailsIntentIsCalled).isTrue() + } + + @Test + fun whenBlockedByEcm_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByEcm + + setContent(restrictions) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNodeWithText(FakeBlockedByEcm.SUMMARY).assertIsDisplayed() + composeTestRule.onNode(isOn()).assertIsDisplayed() + } + + @Test + fun whenBlockedByEcm_click() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByEcm + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(fakeBlockedByEcm.showRestrictedSettingsDetailsIsCalled).isTrue() + } + + private fun setContent(restrictions: Restrictions, primaryOnClick: (() -> Unit)? = {}) { + composeTestRule.setContent { + RestrictedTwoTargetSwitchPreference( + model = switchPreferenceModel, + primaryOnClick = primaryOnClick, + restrictions = restrictions, + ) { _, _ -> + fakeRestrictionsProvider + } + } + } + + private companion object { + const val TITLE = "Title" + const val USER_ID = 0 + const val RESTRICTION_KEY = "restriction_key" + } +} diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 256a71bb57c4..22162bbc79a3 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -457,7 +457,7 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladingen er satt på vent for å beskytte batteriet"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – Sjekk ladetilbehøret"</string> + <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – sjekk ladetilbehøret"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen basert på bruken din"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index 1150ac10c063..87b4c0f4230d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -785,30 +785,6 @@ public class Utils { return false; } - /** Whether to show the wireless charging notification. */ - public static boolean shouldShowWirelessChargingNotification( - @NonNull Context context, @NonNull String tag) { - try { - return shouldShowWirelessChargingNotificationInternal(context, tag); - } catch (Exception e) { - Log.e(tag, "shouldShowWirelessChargingNotification()", e); - return false; - } - } - - /** Stores the timestamp of the wireless charging notification. */ - public static void updateWirelessChargingNotificationTimestamp( - @NonNull Context context, long timestamp, @NonNull String tag) { - try { - Secure.putLong( - context.getContentResolver(), - WIRELESS_CHARGING_NOTIFICATION_TIMESTAMP, - timestamp); - } catch (Exception e) { - Log.e(tag, "setWirelessChargingNotificationTimestamp()", e); - } - } - /** Whether to show the wireless charging warning in Settings. */ public static boolean shouldShowWirelessChargingWarningTip( @NonNull Context context, @NonNull String tag) { @@ -833,37 +809,4 @@ public class Utils { Log.e(tag, "setWirelessChargingWarningEnabled()", e); } } - - private static boolean shouldShowWirelessChargingNotificationInternal( - @NonNull Context context, @NonNull String tag) { - final long lastNotificationTimeMillis = - Secure.getLong( - context.getContentResolver(), - WIRELESS_CHARGING_NOTIFICATION_TIMESTAMP, - WIRELESS_CHARGING_DEFAULT_TIMESTAMP); - if (isWirelessChargingNotificationDisabled(lastNotificationTimeMillis)) { - return false; - } - if (isInitialWirelessChargingNotification(lastNotificationTimeMillis)) { - updateWirelessChargingNotificationTimestamp(context, System.currentTimeMillis(), tag); - updateWirelessChargingWarningEnabled(context, /* enabled= */ true, tag); - return true; - } - final long durationMillis = System.currentTimeMillis() - lastNotificationTimeMillis; - final boolean show = durationMillis > WIRELESS_CHARGING_NOTIFICATION_THRESHOLD_MILLIS; - Log.d(tag, "shouldShowWirelessChargingNotification = " + show); - if (show) { - updateWirelessChargingNotificationTimestamp(context, System.currentTimeMillis(), tag); - updateWirelessChargingWarningEnabled(context, /* enabled= */ true, tag); - } - return show; - } - - private static boolean isWirelessChargingNotificationDisabled(long lastNotificationTimeMillis) { - return lastNotificationTimeMillis == Long.MIN_VALUE; - } - - private static boolean isInitialWirelessChargingNotification(long lastNotificationTimeMillis) { - return lastNotificationTimeMillis == WIRELESS_CHARGING_DEFAULT_TIMESTAMP; - } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java index 2d07e5d471ed..6f31fad104d0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java @@ -16,9 +16,7 @@ package com.android.settingslib; import static com.android.settingslib.Utils.STORAGE_MANAGER_ENABLED_PROPERTY; -import static com.android.settingslib.Utils.WIRELESS_CHARGING_DEFAULT_TIMESTAMP; import static com.android.settingslib.Utils.shouldShowWirelessChargingWarningTip; -import static com.android.settingslib.Utils.updateWirelessChargingNotificationTimestamp; import static com.google.common.truth.Truth.assertThat; @@ -62,7 +60,6 @@ import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowSettings; -import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -547,77 +544,6 @@ public class UtilsTest { } @Test - public void shouldShowWirelessChargingNotification_neverSendNotification_returnTrue() { - updateWirelessChargingNotificationTimestamp( - mContext, WIRELESS_CHARGING_DEFAULT_TIMESTAMP, TAG); - - assertThat(Utils.shouldShowWirelessChargingNotification(mContext, TAG)).isTrue(); - } - - @Test - public void shouldShowNotification_neverSendNotification_updateTimestampAndEnabledState() { - updateWirelessChargingNotificationTimestamp( - mContext, WIRELESS_CHARGING_DEFAULT_TIMESTAMP, TAG); - - Utils.shouldShowWirelessChargingNotification(mContext, TAG); - - assertThat(getWirelessChargingNotificationTimestamp()) - .isNotEqualTo(WIRELESS_CHARGING_DEFAULT_TIMESTAMP); - assertThat(shouldShowWirelessChargingWarningTip(mContext, TAG)).isTrue(); - } - - @Test - public void shouldShowWirelessChargingNotification_notificationDisabled_returnFalse() { - updateWirelessChargingNotificationTimestamp(mContext, CURRENT_TIMESTAMP, TAG); - - assertThat(Utils.shouldShowWirelessChargingNotification(mContext, TAG)).isFalse(); - } - - @Test - public void shouldShowWirelessChargingNotification_withinTimeThreshold_returnFalse() { - updateWirelessChargingNotificationTimestamp(mContext, CURRENT_TIMESTAMP, TAG); - - assertThat(Utils.shouldShowWirelessChargingNotification(mContext, TAG)).isFalse(); - } - - @Test - public void shouldShowWirelessChargingNotification_exceedTimeThreshold_returnTrue() { - final long monthAgo = Duration.ofDays(31).toMillis(); - final long timestamp = CURRENT_TIMESTAMP - monthAgo; - updateWirelessChargingNotificationTimestamp(mContext, timestamp, TAG); - - assertThat(Utils.shouldShowWirelessChargingNotification(mContext, TAG)).isTrue(); - } - - @Test - public void shouldShowNotification_exceedTimeThreshold_updateTimestampAndEnabledState() { - final long monthAgo = Duration.ofDays(31).toMillis(); - final long timestamp = CURRENT_TIMESTAMP - monthAgo; - updateWirelessChargingNotificationTimestamp(mContext, timestamp, TAG); - - Utils.shouldShowWirelessChargingNotification(mContext, TAG); - - assertThat(getWirelessChargingNotificationTimestamp()).isNotEqualTo(timestamp); - assertThat(shouldShowWirelessChargingWarningTip(mContext, TAG)).isTrue(); - } - - @Test - public void updateWirelessChargingNotificationTimestamp_dismissForever_setMinValue() { - updateWirelessChargingNotificationTimestamp(mContext, Long.MIN_VALUE, TAG); - - assertThat(getWirelessChargingNotificationTimestamp()).isEqualTo(Long.MIN_VALUE); - } - - @Test - public void updateWirelessChargingNotificationTimestamp_notDismissForever_setTimestamp() { - updateWirelessChargingNotificationTimestamp(mContext, CURRENT_TIMESTAMP, TAG); - - assertThat(getWirelessChargingNotificationTimestamp()) - .isNotEqualTo(WIRELESS_CHARGING_DEFAULT_TIMESTAMP); - assertThat(getWirelessChargingNotificationTimestamp()).isNotEqualTo(Long.MIN_VALUE); - } - - @Test public void shouldShowWirelessChargingWarningTip_enabled_returnTrue() { Utils.updateWirelessChargingWarningEnabled(mContext, true, TAG); @@ -644,11 +570,4 @@ public class UtilsTest { when(mUsbPortStatus.isConnected()).thenReturn(true); when(mUsbPortStatus.getComplianceWarnings()).thenReturn(new int[] {complianceWarningType}); } - - private long getWirelessChargingNotificationTimestamp() { - return Settings.Secure.getLong( - mContext.getContentResolver(), - Utils.WIRELESS_CHARGING_NOTIFICATION_TIMESTAMP, - WIRELESS_CHARGING_DEFAULT_TIMESTAMP); - } } diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp index 94ea01607714..7ec3d243529f 100644 --- a/packages/SettingsProvider/Android.bp +++ b/packages/SettingsProvider/Android.bp @@ -67,6 +67,8 @@ android_test { "mockito-target-minus-junit4", "platform-test-annotations", "truth", + "Nene", + "Harrier", ], libs: [ "android.test.base", diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 2a8eb9bc0845..3266c12f3ad2 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -707,23 +707,36 @@ final class SettingsState { // Update/add new keys for (String key : keyValues.keySet()) { String value = keyValues.get(key); + + // Rename key if it's an aconfig flag. + String flagName = key; + if (Flags.stageAllAconfigFlags() && isConfigSettingsKey(mKey)) { + int slashIndex = flagName.indexOf("/"); + boolean stageFlag = slashIndex > 0 && slashIndex != flagName.length(); + boolean isAconfig = trunkFlagMap != null && trunkFlagMap.containsKey(flagName); + if (stageFlag && isAconfig) { + String flagWithoutNamespace = flagName.substring(slashIndex + 1); + flagName = "staged/" + namespace + "*" + flagWithoutNamespace; + } + } + String oldValue = null; - Setting state = mSettings.get(key); + Setting state = mSettings.get(flagName); if (state == null) { - state = new Setting(key, value, false, packageName, null); - mSettings.put(key, state); - changedKeys.add(key); // key was added + state = new Setting(flagName, value, false, packageName, null); + mSettings.put(flagName, state); + changedKeys.add(flagName); // key was added } else if (state.value != value) { oldValue = state.value; state.update(value, false, packageName, null, true, /* overrideableByRestore */ false); - changedKeys.add(key); // key was updated + changedKeys.add(flagName); // key was updated } else { // this key/value already exists, no change and no logging necessary continue; } - FrameworkStatsLog.write(FrameworkStatsLog.SETTING_CHANGED, key, value, state.value, + FrameworkStatsLog.write(FrameworkStatsLog.SETTING_CHANGED, flagName, value, state.value, oldValue, /* tag */ null, /* make default */ false, getUserIdFromKey(mKey), FrameworkStatsLog.SETTING_CHANGED__REASON__UPDATED); addHistoricalOperationLocked(HISTORICAL_OPERATION_UPDATE, state); diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml index 0bf53ccf81a6..dccc2d398f12 100644 --- a/packages/SettingsProvider/test/AndroidTest.xml +++ b/packages/SettingsProvider/test/AndroidTest.xml @@ -14,6 +14,8 @@ limitations under the License. --> <configuration description="Run Settings Provider Tests."> + <option name="config-descriptor:metadata" key="parameter" value="multiuser" /> + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" /> <option name="restore-settings" value="true" /> @@ -30,5 +32,7 @@ <option name="package" value="com.android.providers.setting.test" /> <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> + <option name="exclude-annotation" value="com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile" /> + <option name="exclude-annotation" value="com.android.bedstead.harrier.annotations.RequireRunOnSecondaryUser" /> </test> </configuration> diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderMultiUsersTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderMultiUsersTest.java new file mode 100644 index 000000000000..ca1e4c10d339 --- /dev/null +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderMultiUsersTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 static android.provider.Settings.Secure.ACCESSIBILITY_ENABLED; +import static android.provider.Settings.Secure.SYNC_PARENT_SOUNDS; +import static android.provider.Settings.System.RINGTONE; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.pm.PackageManager; +import android.support.test.uiautomator.UiDevice; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.bedstead.harrier.BedsteadJUnit4; +import com.android.bedstead.harrier.DeviceState; +import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile; +import com.android.bedstead.harrier.annotations.EnsureHasSecondaryUser; +import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile; +import com.android.bedstead.harrier.annotations.RequireFeature; +import com.android.bedstead.harrier.annotations.RequireRunOnInitialUser; +import com.android.bedstead.harrier.annotations.RequireRunOnPrimaryUser; +import com.android.bedstead.nene.TestApis; +import com.android.bedstead.nene.users.UserReference; +import com.android.bedstead.nene.users.UserType; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; + +@RunWith(BedsteadJUnit4.class) +@RequireRunOnPrimaryUser +public class SettingsProviderMultiUsersTest { + + @ClassRule @Rule + public static final DeviceState sDeviceState = new DeviceState(); + + private static final String SETTINGS = "some_random_setting"; + + private static final String GET_SHELL_COMMAND = "settings get --user "; + private static final String SET_SHELL_COMMAND = "settings put --user "; + private static final String DELETE_SHELL_COMMAND = "settings delete --user "; + + private static final String SPACE_GLOBAL = "global"; + private static final String SPACE_SYSTEM = "system"; + private static final String SPACE_SECURE = "secure"; + + private static final String CLONE_TO_MANAGED_PROFILE_SETTING = ACCESSIBILITY_ENABLED; + private static final String CLONE_FROM_PARENT_SETTINGS = RINGTONE; + private static final String SYNC_FROM_PARENT_SETTINGS = SYNC_PARENT_SOUNDS; + + private UiDevice mUiDevice; + private UserReference mPrimaryUser; + + @Before + public void setUp() throws Exception { + mPrimaryUser = sDeviceState.initialUser(); + + mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + } + + @Test + @RequireFeature(PackageManager.FEATURE_MANAGED_USERS) + @EnsureHasWorkProfile + public void testSettings_workProfile() throws Exception { + UserReference profile = sDeviceState.workProfile(); + + // Settings.Global settings are shared between different users + assertSettingsShared(SPACE_GLOBAL, mPrimaryUser.id(), profile.id()); + // Settings.System and Settings.Secure settings can be different on different users + assertSettingsDifferent(SPACE_SYSTEM, mPrimaryUser.id(), profile.id()); + assertSettingsDifferent(SPACE_SECURE, mPrimaryUser.id(), profile.id()); + } + + @Test + @RequireFeature(PackageManager.FEATURE_MANAGED_USERS) + @RequireRunOnInitialUser + @EnsureHasSecondaryUser + public void testSettings_secondaryUser() throws Exception { + UserReference secondaryUser = sDeviceState.secondaryUser(); + + // Settings.Global settings are shared between different users + assertSettingsShared(SPACE_GLOBAL, mPrimaryUser.id(), secondaryUser.id()); + // Settings.System and Settings.Secure settings can be different on different users + assertSettingsDifferent(SPACE_SYSTEM, mPrimaryUser.id(), secondaryUser.id()); + assertSettingsDifferent(SPACE_SECURE, mPrimaryUser.id(), secondaryUser.id()); + } + + private void assertSettingsDifferent(String type, int userId1, int userId2) throws Exception { + // reset settings + setSetting(type, SETTINGS, "noValue", userId2); + waitForIdle(); + + // set the value with user 1 + setSetting(type, SETTINGS, "value1", userId1); + waitForIdle(); + + // check no value with user 2 + String value = getSetting(type, SETTINGS, userId2); + assertThat(value).startsWith("noValue"); + + // set the value with user 2 + setSetting(type, SETTINGS, "value2", userId2); + waitForIdle(); + + // check the value with user 1 is not changed + value = getSetting(type, SETTINGS, userId1); + assertThat(value).startsWith("value1"); + } + + private void assertSettingsShared(String type, int userId1, int userId2) throws Exception { + // reset settings + setSetting(type, SETTINGS, "noValue", userId2); + waitForIdle(); + + // set the value with user 1 + setSetting(type, SETTINGS, "value1", userId1); + waitForIdle(); + + // check no value with user 2 + String value = getSetting(type, SETTINGS, userId2); + assertThat(value).startsWith("value1"); + + // set the value with user 2 + setSetting(type, SETTINGS, "value2", userId2); + waitForIdle(); + + // check the value with user 1 is not changed + value = getSetting(type, SETTINGS, userId1); + assertThat(value).startsWith("value2"); + } + + @Test + @RequireFeature(PackageManager.FEATURE_MANAGED_USERS) + @EnsureHasNoWorkProfile + public void testSettings_profile_cloneToManagedProfile() throws Exception { + assertSettingsCloned(SPACE_SECURE, CLONE_TO_MANAGED_PROFILE_SETTING, false); + } + + @Test + @RequireFeature(PackageManager.FEATURE_MANAGED_USERS) + @EnsureHasNoWorkProfile + public void testSettings_profile_cloneFromParent() throws Exception { + assertSettingsCloned(SPACE_SYSTEM, CLONE_FROM_PARENT_SETTINGS, true); + } + + private void assertSettingsCloned(String type, String name, boolean isSyncSettings) + throws Exception { + boolean resetSyncValue = false; + if (isSyncSettings) { + // set to sync settings from parent + final String oldSyncValue = + getSetting(SPACE_SECURE, SYNC_FROM_PARENT_SETTINGS, mPrimaryUser.id()); + resetSyncValue = oldSyncValue.startsWith("0"); + if (resetSyncValue) { + setSetting(SPACE_SECURE, SYNC_FROM_PARENT_SETTINGS, "1", mPrimaryUser.id()); + waitForIdle(); + } + } + + final String oldValue = getSetting(type, name, mPrimaryUser.id()); + + try (UserReference myProfile = TestApis.users().createUser() + .parent(mPrimaryUser) + .type(TestApis.users().supportedType(UserType.MANAGED_PROFILE_TYPE_NAME)) + .createAndStart()) { + String value = getSetting(type, name, myProfile.id()); + assertThat(value).isEqualTo(oldValue); + + String newValue; + if (isSyncSettings) { + newValue = generateNewValue(oldValue); + } else { + newValue = oldValue.startsWith("0") ? "1" : "0"; + } + + setSetting(type, name, newValue, mPrimaryUser.id()); + waitForIdle(); + + value = getSetting(type, name, myProfile.id()); + assertThat(value).startsWith(newValue); + } finally { + // reset settings + setSetting(type, name, oldValue, mPrimaryUser.id()); + if (resetSyncValue) { + setSetting(SPACE_SECURE, SYNC_FROM_PARENT_SETTINGS, "0", mPrimaryUser.id()); + } + } + } + + private String generateNewValue(String oldValue) { + String newValue = oldValue.replace("\n", ""); + if (newValue.endsWith("0")) { + final int size = newValue.length(); + newValue = newValue.substring(0, size - 1) + "1"; + } else { + final int size = newValue.length(); + newValue = newValue.substring(0, size - 1) + "0"; + } + return newValue; + } + + @Test + @RequireRunOnInitialUser + @EnsureHasSecondaryUser + public void testSettings_stopAndRestartSecondaryUser() throws Exception { + UserReference secondaryUser = sDeviceState.secondaryUser(); + + assertSettingsDifferent(SPACE_SECURE, mPrimaryUser.id(), secondaryUser.id()); + + secondaryUser.stop(); + + assertSettingsDifferent(SPACE_SECURE, mPrimaryUser.id(), secondaryUser.id()); + + secondaryUser.start(); + + assertSettingsDifferent(SPACE_SECURE, mPrimaryUser.id(), secondaryUser.id()); + } + + private void waitForIdle() { + final UiDevice uiDevice = UiDevice.getInstance( + InstrumentationRegistry.getInstrumentation()); + uiDevice.waitForIdle(); + } + + private String getSetting(String type, String name, int userId) throws Exception { + return executeShellCmd(GET_SHELL_COMMAND + userId + " " + type + " " + name); + } + + private void setSetting(String type, String name, String setting, int userId) + throws Exception { + setSetting(name, setting, userId + " " + type); + } + + private void setSetting(String name, String setting, String type) throws Exception { + if (setting == null || setting.equals("null")) { + executeShellCmd(DELETE_SHELL_COMMAND + type + " " + name); + } else { + setting = setting.replace("\n", ""); + executeShellCmd(SET_SHELL_COMMAND + type + " " + name + " " + setting); + } + } + + private String executeShellCmd(String command) throws IOException { + return mUiDevice.executeShellCommand(command); + } +} diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java index 33362a22ffba..e0e31d785ae8 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java @@ -740,6 +740,51 @@ public class SettingsStateTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_STAGE_ALL_ACONFIG_FLAGS) + public void testSetSettingsLockedStagesAconfigFlags() throws Exception { + int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); + + SettingsState settingsState = new SettingsState( + InstrumentationRegistry.getContext(), mLock, mSettingsFile, configKey, + SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); + + String prefix = "test_namespace"; + String packageName = "com.android.flags"; + Map<String, String> keyValues = + Map.of("test_namespace/com.android.flags.flag3", "true"); + + parsed_flags flags = parsed_flags + .newBuilder() + .addParsedFlag(parsed_flag + .newBuilder() + .setPackage(packageName) + .setName("flag3") + .setNamespace(prefix) + .setDescription("test flag") + .addBug("12345678") + .setState(Aconfig.flag_state.DISABLED) + .setPermission(Aconfig.flag_permission.READ_WRITE)) + .build(); + + synchronized (mLock) { + settingsState.loadAconfigDefaultValues( + flags.toByteArray(), settingsState.getAconfigDefaultValues()); + List<String> updates = + settingsState.setSettingsLocked("test_namespace/", keyValues, packageName); + assertEquals(1, updates.size()); + assertEquals(updates.get(0), "staged/test_namespace*com.android.flags.flag3"); + + SettingsState.Setting s; + + s = settingsState.getSettingLocked("test_namespace/com.android.flags.flag3"); + assertNull(s.getValue()); + + s = settingsState.getSettingLocked("staged/test_namespace*com.android.flags.flag3"); + assertEquals("true", s.getValue()); + } + } + + @Test public void testsetSettingsLockedKeepTrunkDefault() throws Exception { final PrintStream os = new PrintStream(new FileOutputStream(mSettingsFile)); os.print( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt index 9ee69bc065f6..a3372e3e83da 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt @@ -28,6 +28,7 @@ import com.android.systemui.communal.ui.compose.extensions.allowGestures import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.res.R +import com.android.systemui.statusbar.phone.SystemUIDialogFactory object Communal { object Elements { @@ -63,6 +64,7 @@ val sceneTransitions = transitions { fun CommunalContainer( modifier: Modifier = Modifier, viewModel: CommunalViewModel, + dialogFactory: SystemUIDialogFactory, ) { val currentScene: SceneKey by viewModel.currentScene.collectAsState(CommunalScenes.Blank) val sceneTransitionLayoutState = @@ -104,7 +106,7 @@ fun CommunalContainer( userActions = mapOf(Swipe(SwipeDirection.Right, fromSource = Edge.Left) to CommunalScenes.Blank), ) { - CommunalScene(viewModel, modifier = modifier) + CommunalScene(viewModel, dialogFactory, modifier = modifier) } } } @@ -113,6 +115,7 @@ fun CommunalContainer( @Composable private fun SceneScope.CommunalScene( viewModel: BaseCommunalViewModel, + dialogFactory: SystemUIDialogFactory, modifier: Modifier = Modifier, ) { Box( @@ -121,5 +124,7 @@ private fun SceneScope.CommunalScene( .fillMaxSize() .background(LocalAndroidColorScheme.current.outlineVariant), ) - Box(modifier.element(Communal.Elements.Content)) { CommunalHub(viewModel = viewModel) } + Box(modifier.element(Communal.Elements.Content)) { + CommunalHub(viewModel = viewModel, dialogFactory = dialogFactory) + } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt index eb6d3036be48..0d6b71066557 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt @@ -29,6 +29,7 @@ import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope @@ -90,7 +91,6 @@ import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.positionInWindow -import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag @@ -108,6 +108,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.window.Popup import androidx.core.view.setPadding +import androidx.window.layout.WindowMetricsCalculator import com.android.compose.modifiers.thenIf import com.android.compose.theme.LocalAndroidColorScheme import com.android.compose.ui.graphics.painter.rememberDrawablePainter @@ -118,12 +119,13 @@ import com.android.systemui.communal.ui.compose.Dimensions.CardOutlineWidth import com.android.systemui.communal.ui.compose.extensions.allowGestures import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset -import com.android.systemui.communal.ui.compose.extensions.observeTapsWithoutConsuming +import com.android.systemui.communal.ui.compose.extensions.observeTaps import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.communal.widgets.WidgetConfigurator import com.android.systemui.res.R +import com.android.systemui.statusbar.phone.SystemUIDialogFactory import kotlinx.coroutines.launch @OptIn(ExperimentalComposeUiApi::class) @@ -131,6 +133,7 @@ import kotlinx.coroutines.launch fun CommunalHub( modifier: Modifier = Modifier, viewModel: BaseCommunalViewModel, + dialogFactory: SystemUIDialogFactory? = null, widgetConfigurator: WidgetConfigurator? = null, onOpenWidgetPicker: (() -> Unit)? = null, onEditDone: (() -> Unit)? = null, @@ -165,7 +168,7 @@ fun CommunalHub( .pointerInput(gridState, contentOffset, contentListState) { // If not in edit mode, don't allow selecting items. if (!viewModel.isEditMode) return@pointerInput - observeTapsWithoutConsuming { offset -> + observeTaps { offset -> val adjustedOffset = offset - contentOffset val index = firstIndexAtOffset(gridState, adjustedOffset) val key = index?.let { keyAtIndexIfEditable(contentListState.list, index) } @@ -271,6 +274,31 @@ fun CommunalHub( ) } + if (viewModel is CommunalViewModel && dialogFactory != null) { + val isEnableWidgetDialogShowing by + viewModel.isEnableWidgetDialogShowing.collectAsState(false) + val isEnableWorkProfileDialogShowing by + viewModel.isEnableWorkProfileDialogShowing.collectAsState(false) + + EnableWidgetDialog( + isEnableWidgetDialogVisible = isEnableWidgetDialogShowing, + dialogFactory = dialogFactory, + title = stringResource(id = R.string.dialog_title_to_allow_any_widget), + positiveButtonText = stringResource(id = R.string.button_text_to_open_settings), + onConfirm = viewModel::onEnableWidgetDialogConfirm, + onCancel = viewModel::onEnableWidgetDialogCancel + ) + + EnableWidgetDialog( + isEnableWidgetDialogVisible = isEnableWorkProfileDialogShowing, + dialogFactory = dialogFactory, + title = stringResource(id = R.string.work_mode_off_title), + positiveButtonText = stringResource(id = R.string.work_mode_turn_on), + onConfirm = viewModel::onEnableWorkProfileDialogConfirm, + onCancel = viewModel::onEnableWorkProfileDialogCancel + ) + } + // This spacer covers the edge of the LazyHorizontalGrid and prevents it from receiving // touches, so that the SceneTransitionLayout can intercept the touches and allow an edge // swipe back to the blank scene. @@ -398,11 +426,11 @@ private fun BoxScope.CommunalHubLazyGrid( } } else { CommunalContent( + modifier = cardModifier.animateItemPlacement(), model = list[index], viewModel = viewModel, size = size, selected = false, - modifier = cardModifier, ) } } @@ -616,7 +644,7 @@ private fun CommunalContent( WidgetContent(viewModel, model, size, selected, widgetConfigurator, modifier) is CommunalContentModel.WidgetPlaceholder -> HighlightedItem(modifier) is CommunalContentModel.WidgetContent.DisabledWidget -> - DisabledWidgetPlaceholder(model, modifier) + DisabledWidgetPlaceholder(model, viewModel, modifier) is CommunalContentModel.CtaTileInViewMode -> CtaTileInViewModeContent(viewModel, modifier) is CommunalContentModel.CtaTileInEditMode -> CtaTileInEditModeContent(modifier, onOpenWidgetPicker) @@ -645,7 +673,7 @@ private fun CtaTileInViewModeContent( ) { val colors = LocalAndroidColorScheme.current Card( - modifier = modifier.padding(CardOutlineWidth), + modifier = modifier, colors = CardDefaults.cardColors( containerColor = colors.primary, @@ -716,7 +744,7 @@ private fun CtaTileInEditModeContent( } val colors = LocalAndroidColorScheme.current Card( - modifier = modifier.padding(CardOutlineWidth), + modifier = modifier, colors = CardDefaults.cardColors(containerColor = Color.Transparent), border = BorderStroke(1.dp, colors.primary), shape = RoundedCornerShape(200.dp), @@ -754,23 +782,28 @@ private fun WidgetContent( modifier: Modifier = Modifier, ) { Box( - modifier = modifier, + modifier = + modifier.thenIf(!viewModel.isEditMode && model.inQuietMode) { + Modifier.pointerInput(Unit) { + // consume tap to prevent the child view from triggering interactions with the + // app widget + observeTaps(shouldConsume = true) { _ -> + viewModel.onOpenEnableWorkProfileDialog() + } + } + } ) { - val paddingInPx = - if (selected) with(LocalDensity.current) { CardOutlineWidth.toPx().toInt() } else 0 AndroidView( modifier = Modifier.fillMaxSize().allowGestures(allowed = !viewModel.isEditMode), factory = { context -> model.appWidgetHost .createViewForCommunal(context, model.appWidgetId, model.providerInfo) - .apply { updateAppWidgetSize(Bundle.EMPTY, listOf(size)) } - }, - update = { view -> - // Remove the extra padding applied to AppWidgetHostView to allow widgets to - // occupy the entire box. The added padding is now adjusted to leave only - // sufficient space for displaying the outline around the box when the widget - // is selected. - view.setPadding(paddingInPx) + .apply { + updateAppWidgetSize(Bundle.EMPTY, listOf(size)) + // Remove the extra padding applied to AppWidgetHostView to allow widgets to + // occupy the entire box. + setPadding(0) + } }, // For reusing composition in lazy lists. onReset = {}, @@ -830,6 +863,7 @@ fun WidgetConfigureButton( @Composable fun DisabledWidgetPlaceholder( model: CommunalContentModel.WidgetContent.DisabledWidget, + viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier, ) { val context = LocalContext.current @@ -843,10 +877,17 @@ fun DisabledWidgetPlaceholder( Column( modifier = - modifier.background( - MaterialTheme.colorScheme.surfaceVariant, - RoundedCornerShape(dimensionResource(system_app_widget_background_radius)) - ), + modifier + .background( + MaterialTheme.colorScheme.surfaceVariant, + RoundedCornerShape(dimensionResource(system_app_widget_background_radius)) + ) + .clickable( + enabled = !viewModel.isEditMode, + interactionSource = null, + indication = null, + onClick = viewModel::onOpenEnableWidgetDialog + ), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { @@ -906,14 +947,14 @@ private fun gridContentPadding(isEditMode: Boolean, toolbarSize: IntSize?): Padd if (!isEditMode || toolbarSize == null) { return PaddingValues(start = 48.dp, end = 48.dp, top = Dimensions.GridTopSpacing) } - val configuration = LocalConfiguration.current + val context = LocalContext.current val density = LocalDensity.current - val screenHeight = configuration.screenHeightDp.dp + val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context) + val screenHeight = with(density) { windowMetrics.bounds.height().toDp() } val toolbarHeight = with(density) { Dimensions.ToolbarPaddingTop + toolbarSize.height.toDp() } val verticalPadding = - ((screenHeight - toolbarHeight - Dimensions.GridHeight) / 2).coerceAtLeast( - Dimensions.Spacing - ) + ((screenHeight - toolbarHeight - Dimensions.GridHeight + Dimensions.GridTopSpacing) / 2) + .coerceAtLeast(Dimensions.Spacing) return PaddingValues( start = Dimensions.ToolbarPaddingHorizontal, end = Dimensions.ToolbarPaddingHorizontal, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt index 3d88ad53685e..9e905ac11b1e 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt @@ -27,6 +27,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.ComposableScene +import com.android.systemui.statusbar.phone.SystemUIDialogFactory import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -38,6 +39,7 @@ class CommunalScene @Inject constructor( private val viewModel: CommunalViewModel, + private val dialogFactory: SystemUIDialogFactory, ) : ComposableScene { override val key = Scenes.Communal @@ -51,6 +53,6 @@ constructor( @Composable override fun SceneScope.Content(modifier: Modifier) { - CommunalHub(modifier, viewModel) + CommunalHub(modifier, viewModel, dialogFactory) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/EnableWidgetDialog.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/EnableWidgetDialog.kt new file mode 100644 index 000000000000..df11206826b8 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/EnableWidgetDialog.kt @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.communal.ui.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.android.compose.theme.LocalAndroidColorScheme +import com.android.systemui.res.R +import com.android.systemui.statusbar.phone.ComponentSystemUIDialog +import com.android.systemui.statusbar.phone.SystemUIDialogFactory +import com.android.systemui.statusbar.phone.create + +/** Dialog shown upon tapping a disabled widget which allows users to enable the widget. */ +@Composable +fun EnableWidgetDialog( + isEnableWidgetDialogVisible: Boolean, + dialogFactory: SystemUIDialogFactory, + title: String, + positiveButtonText: String, + onConfirm: () -> Unit, + onCancel: () -> Unit +) { + var dialog: ComponentSystemUIDialog? by remember { mutableStateOf(null) } + val context = LocalView.current.context + + DisposableEffect(isEnableWidgetDialogVisible) { + if (isEnableWidgetDialogVisible) { + dialog = + dialogFactory.create( + context = context, + ) { + DialogComposable(title, positiveButtonText, onConfirm, onCancel) + } + dialog?.apply { + setCancelable(true) + setCanceledOnTouchOutside(true) + setOnCancelListener { onCancel() } + show() + } + } + + onDispose { + dialog?.dismiss() + dialog = null + } + } +} + +@Composable +private fun DialogComposable( + title: String, + positiveButtonText: String, + onConfirm: () -> Unit, + onCancel: () -> Unit, +) { + Box( + Modifier.fillMaxWidth() + .padding(top = 18.dp, bottom = 8.dp) + .background(LocalAndroidColorScheme.current.surfaceBright, RoundedCornerShape(28.dp)) + ) { + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(20.dp), + ) { + Box( + modifier = Modifier.padding(horizontal = 24.dp).fillMaxWidth().wrapContentHeight(), + contentAlignment = Alignment.TopStart + ) { + Text( + text = title, + style = MaterialTheme.typography.titleMedium, + color = LocalAndroidColorScheme.current.onSurface, + textAlign = TextAlign.Center, + maxLines = 1, + ) + } + + Box( + modifier = Modifier.padding(end = 12.dp).fillMaxWidth().wrapContentHeight(), + contentAlignment = Alignment.Center + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End, + ) { + TextButton( + contentPadding = PaddingValues(16.dp), + onClick = onCancel, + ) { + Text( + text = stringResource(R.string.cancel), + ) + } + TextButton( + contentPadding = PaddingValues(16.dp), + onClick = onConfirm, + ) { + Text( + text = positiveButtonText, + ) + } + } + } + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt index beb8ddef949d..1adb3359b17f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt @@ -41,7 +41,6 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.toOffset import androidx.compose.ui.unit.toSize -import androidx.compose.ui.zIndex import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset import com.android.systemui.communal.ui.compose.extensions.plus import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel @@ -247,7 +246,7 @@ fun LazyGridItemScope.DraggableItem( content: @Composable (isDragging: Boolean) -> Unit ) { if (!enabled) { - return Box(modifier = modifier) { content(false) } + return content(false) } val dragging = index == dragDropState.draggingItemIndex @@ -258,7 +257,7 @@ fun LazyGridItemScope.DraggableItem( ) val draggingModifier = if (dragging) { - Modifier.zIndex(1f).graphicsLayer { + Modifier.graphicsLayer { translationX = dragDropState.draggingItemOffset.x translationY = dragDropState.draggingItemOffset.y alpha = itemAlpha @@ -268,13 +267,14 @@ fun LazyGridItemScope.DraggableItem( } Box(modifier) { + Box(draggingModifier) { content(dragging) } AnimatedVisibility( + modifier = Modifier.matchParentSize(), visible = (dragging || selected) && !dragDropState.isDraggingToRemove, enter = fadeIn(), exit = fadeOut() ) { - HighlightedItem() + HighlightedItem(Modifier.matchParentSize()) } - Box(modifier = draggingModifier, propagateMinConstraints = true) { content(dragging) } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/extensions/PointerInputScopeExt.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/extensions/PointerInputScopeExt.kt index bc1e429e57cf..379c1656a3ac 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/extensions/PointerInputScopeExt.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/extensions/PointerInputScopeExt.kt @@ -30,16 +30,18 @@ import androidx.compose.ui.util.fastForEach import kotlinx.coroutines.coroutineScope /** - * Observe taps without actually consuming them, so child elements can still respond to them. Long + * Observe taps without consuming them by default, so child elements can still respond to them. Long * presses are excluded. */ -suspend fun PointerInputScope.observeTapsWithoutConsuming( +suspend fun PointerInputScope.observeTaps( pass: PointerEventPass = PointerEventPass.Initial, + shouldConsume: Boolean = false, onTap: ((Offset) -> Unit)? = null, ) = coroutineScope { if (onTap == null) return@coroutineScope awaitEachGesture { - awaitFirstDown(pass = pass) + val down = awaitFirstDown(pass = pass) + if (shouldConsume) down.consume() val tapTimeout = viewConfiguration.longPressTimeoutMillis val up = withTimeoutOrNull(tapTimeout) { waitForUpOrCancellation(pass = pass) } if (up != null) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt index b5499b7bce35..bc4e55505579 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt @@ -18,13 +18,16 @@ package com.android.systemui.keyguard.ui.composable import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalView import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.transitions +import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.blueprint.ComposableLockscreenSceneBlueprint import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import javax.inject.Inject @@ -40,6 +43,7 @@ class LockscreenContent constructor( private val viewModel: LockscreenContentViewModel, private val blueprints: Set<@JvmSuppressWildcards ComposableLockscreenSceneBlueprint>, + private val clockInteractor: KeyguardClockInteractor, ) { private val sceneKeyByBlueprint: Map<ComposableLockscreenSceneBlueprint, SceneKey> by lazy { @@ -55,6 +59,12 @@ constructor( ) { val coroutineScope = rememberCoroutineScope() val blueprintId by viewModel.blueprintId(coroutineScope).collectAsState() + val view = LocalView.current + DisposableEffect(view) { + clockInteractor.clockEventController.registerListeners(view) + + onDispose { clockInteractor.clockEventController.unregisterListeners() } + } // Switch smoothly between blueprints, any composable tagged with element() will be // transition-animated between any two blueprints, if they both display the same element. diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt index a02781ba63f7..96520b21cc72 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt @@ -39,7 +39,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** The lock screen scene shows when the device is locked. */ @@ -54,8 +53,17 @@ constructor( override val key = Scenes.Lockscreen override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = - combine(viewModel.upDestinationSceneKey, viewModel.leftDestinationSceneKey, ::Pair) - .map { (upKey, leftKey) -> destinationScenes(up = upKey, left = leftKey) } + combine( + viewModel.upDestinationSceneKey, + viewModel.leftDestinationSceneKey, + viewModel.downFromTopEdgeDestinationSceneKey, + ) { upKey, leftKey, downFromTopEdgeKey -> + destinationScenes( + up = upKey, + left = leftKey, + downFromTopEdge = downFromTopEdgeKey, + ) + } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, @@ -63,6 +71,7 @@ constructor( destinationScenes( up = viewModel.upDestinationSceneKey.value, left = viewModel.leftDestinationSceneKey.value, + downFromTopEdge = viewModel.downFromTopEdgeDestinationSceneKey.value, ) ) @@ -79,12 +88,15 @@ constructor( private fun destinationScenes( up: SceneKey?, left: SceneKey?, + downFromTopEdge: SceneKey?, ): Map<UserAction, UserActionResult> { return buildMap { up?.let { this[Swipe(SwipeDirection.Up)] = UserActionResult(up) } left?.let { this[Swipe(SwipeDirection.Left)] = UserActionResult(left) } - this[Swipe(fromSource = Edge.Top, direction = SwipeDirection.Down)] = - UserActionResult(Scenes.QuickSettings) + downFromTopEdge?.let { + this[Swipe(fromSource = Edge.Top, direction = SwipeDirection.Down)] = + UserActionResult(downFromTopEdge) + } this[Swipe(direction = SwipeDirection.Down)] = UserActionResult(Scenes.Shade) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt new file mode 100644 index 000000000000..c5ff859def17 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.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.keyguard.ui.composable.blueprint + +import androidx.compose.animation.core.tween +import com.android.compose.animation.scene.ElementKey +import com.android.compose.animation.scene.SceneKey +import com.android.compose.animation.scene.TransitionBuilder +import com.android.compose.animation.scene.transitions +import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.largeClockElementKey +import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smallClockElementKey +import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smartspaceElementKey +import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.ClockFaceInTransition.Companion.CLOCK_IN_MILLIS +import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.ClockFaceInTransition.Companion.CLOCK_IN_START_DELAY_MILLIS +import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.ClockFaceOutTransition.Companion.CLOCK_OUT_MILLIS +import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.SmartspaceMoveTransition.Companion.STATUS_AREA_MOVE_DOWN_MILLIS +import com.android.systemui.keyguard.ui.view.layout.sections.transitions.ClockSizeTransition.SmartspaceMoveTransition.Companion.STATUS_AREA_MOVE_UP_MILLIS + +object ClockTransition { + val defaultClockTransitions = transitions { + from(ClockScenes.smallClockScene, to = ClockScenes.largeClockScene) { + transitioningToLargeClock() + } + from(ClockScenes.largeClockScene, to = ClockScenes.smallClockScene) { + transitioningToSmallClock() + } + } + + private fun TransitionBuilder.transitioningToLargeClock() { + spec = tween(durationMillis = STATUS_AREA_MOVE_UP_MILLIS.toInt()) + timestampRange( + startMillis = CLOCK_IN_START_DELAY_MILLIS.toInt(), + endMillis = (CLOCK_IN_START_DELAY_MILLIS + CLOCK_IN_MILLIS).toInt() + ) { + fade(largeClockElementKey) + } + + timestampRange(endMillis = CLOCK_OUT_MILLIS.toInt()) { fade(smallClockElementKey) } + anchoredTranslate(smallClockElementKey, smartspaceElementKey) + } + + private fun TransitionBuilder.transitioningToSmallClock() { + spec = tween(durationMillis = STATUS_AREA_MOVE_DOWN_MILLIS.toInt()) + timestampRange( + startMillis = CLOCK_IN_START_DELAY_MILLIS.toInt(), + endMillis = (CLOCK_IN_START_DELAY_MILLIS + CLOCK_IN_MILLIS).toInt() + ) { + fade(smallClockElementKey) + } + + timestampRange(endMillis = CLOCK_OUT_MILLIS.toInt()) { fade(largeClockElementKey) } + anchoredTranslate(smallClockElementKey, smartspaceElementKey) + } +} + +object ClockScenes { + val smallClockScene = SceneKey("small-clock-scene") + val largeClockScene = SceneKey("large-clock-scene") +} + +object ClockElementKeys { + val largeClockElementKey = ElementKey("large-clock") + val smallClockElementKey = ElementKey("small-clock") + val smartspaceElementKey = ElementKey("smart-space") +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt index d23cd0c06aab..9509fd22534a 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt @@ -17,19 +17,14 @@ package com.android.systemui.keyguard.ui.composable.blueprint import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.IntRect import com.android.compose.animation.scene.SceneScope -import com.android.compose.modifiers.padding -import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.LockscreenLongPress import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection @@ -38,11 +33,8 @@ import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection import com.android.systemui.keyguard.ui.composable.section.NotificationSection import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection -import com.android.systemui.keyguard.ui.composable.section.SmartSpaceSection import com.android.systemui.keyguard.ui.composable.section.StatusBarSection import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel -import com.android.systemui.media.controls.ui.composable.MediaCarousel -import com.android.systemui.res.R import dagger.Binds import dagger.Module import dagger.multibindings.IntoSet @@ -59,14 +51,12 @@ constructor( private val viewModel: LockscreenContentViewModel, private val statusBarSection: StatusBarSection, private val clockSection: DefaultClockSection, - private val smartSpaceSection: SmartSpaceSection, private val notificationSection: NotificationSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val mediaCarouselSection: MediaCarouselSection, - private val clockInteractor: KeyguardClockInteractor, ) : ComposableLockscreenSceneBlueprint { override val id: String = "default" @@ -74,7 +64,6 @@ constructor( @Composable override fun SceneScope.Content(modifier: Modifier) { val isUdfpsVisible = viewModel.isUdfpsVisible - val burnIn = rememberBurnIn(clockInteractor) val resources = LocalContext.current.resources LockscreenLongPress( @@ -88,40 +77,7 @@ constructor( modifier = Modifier.fillMaxWidth(), ) { with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) } - with(clockSection) { - SmallClock( - burnInParams = burnIn.parameters, - onTopChanged = burnIn.onSmallClockTopChanged, - modifier = Modifier.fillMaxWidth(), - ) - } - with(smartSpaceSection) { - SmartSpace( - burnInParams = burnIn.parameters, - onTopChanged = burnIn.onSmartspaceTopChanged, - modifier = - Modifier.fillMaxWidth() - .padding( - top = { viewModel.getSmartSpacePaddingTop(resources) }, - ) - .padding( - bottom = - dimensionResource( - R.dimen.keyguard_status_view_bottom_margin - ), - ), - ) - } - - if (viewModel.isLargeClockVisible) { - Spacer(modifier = Modifier.weight(weight = 1f)) - with(clockSection) { - LargeClock( - modifier = Modifier.fillMaxWidth(), - ) - } - } - + with(clockSection) { DefaultClockLayout() } with(mediaCarouselSection) { MediaCarousel() } if (viewModel.areNotificationsVisible(resources = resources)) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt index c422c4b58b55..9abfa4233a15 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt @@ -17,19 +17,14 @@ package com.android.systemui.keyguard.ui.composable.blueprint import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.IntRect import com.android.compose.animation.scene.SceneScope -import com.android.compose.modifiers.padding -import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.LockscreenLongPress import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection @@ -38,10 +33,8 @@ import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection import com.android.systemui.keyguard.ui.composable.section.NotificationSection import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection -import com.android.systemui.keyguard.ui.composable.section.SmartSpaceSection import com.android.systemui.keyguard.ui.composable.section.StatusBarSection import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel -import com.android.systemui.res.R import dagger.Binds import dagger.Module import dagger.multibindings.IntoSet @@ -58,14 +51,12 @@ constructor( private val viewModel: LockscreenContentViewModel, private val statusBarSection: StatusBarSection, private val clockSection: DefaultClockSection, - private val smartSpaceSection: SmartSpaceSection, private val notificationSection: NotificationSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val mediaCarouselSection: MediaCarouselSection, - private val clockInteractor: KeyguardClockInteractor, ) : ComposableLockscreenSceneBlueprint { override val id: String = "shortcuts-besides-udfps" @@ -73,7 +64,6 @@ constructor( @Composable override fun SceneScope.Content(modifier: Modifier) { val isUdfpsVisible = viewModel.isUdfpsVisible - val burnIn = rememberBurnIn(clockInteractor) val resources = LocalContext.current.resources LockscreenLongPress( @@ -87,36 +77,7 @@ constructor( modifier = Modifier.fillMaxWidth(), ) { with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) } - with(clockSection) { - SmallClock( - onTopChanged = burnIn.onSmallClockTopChanged, - modifier = Modifier.fillMaxWidth(), - burnInParams = burnIn.parameters, - ) - } - with(smartSpaceSection) { - SmartSpace( - burnInParams = burnIn.parameters, - onTopChanged = burnIn.onSmartspaceTopChanged, - modifier = - Modifier.fillMaxWidth() - .padding( - top = { viewModel.getSmartSpacePaddingTop(resources) } - ) - .padding( - bottom = - dimensionResource( - R.dimen.keyguard_status_view_bottom_margin - ) - ), - ) - } - - if (viewModel.isLargeClockVisible) { - Spacer(modifier = Modifier.weight(weight = 1f)) - with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) } - } - + with(clockSection) { DefaultClockLayout() } with(mediaCarouselSection) { MediaCarousel() } if (viewModel.areNotificationsVisible(resources = resources)) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt index d2184252102b..652412d13aba 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.composable.blueprint import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -27,7 +26,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.Layout -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntRect @@ -35,7 +33,6 @@ import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope import com.android.compose.modifiers.padding import com.android.systemui.Flags -import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.LockscreenLongPress import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection @@ -44,7 +41,6 @@ import com.android.systemui.keyguard.ui.composable.section.LockSection import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection import com.android.systemui.keyguard.ui.composable.section.NotificationSection import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection -import com.android.systemui.keyguard.ui.composable.section.SmartSpaceSection import com.android.systemui.keyguard.ui.composable.section.StatusBarSection import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import com.android.systemui.res.R @@ -65,14 +61,12 @@ constructor( private val viewModel: LockscreenContentViewModel, private val statusBarSection: StatusBarSection, private val clockSection: DefaultClockSection, - private val smartSpaceSection: SmartSpaceSection, private val notificationSection: NotificationSection, private val lockSection: LockSection, private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>, private val bottomAreaSection: BottomAreaSection, private val settingsMenuSection: SettingsMenuSection, private val mediaCarouselSection: MediaCarouselSection, - private val clockInteractor: KeyguardClockInteractor, private val largeScreenHeaderHelper: LargeScreenHeaderHelper, ) : ComposableLockscreenSceneBlueprint { @@ -81,8 +75,6 @@ constructor( @Composable override fun SceneScope.Content(modifier: Modifier) { val isUdfpsVisible = viewModel.isUdfpsVisible - val burnIn = rememberBurnIn(clockInteractor) - val resources = LocalContext.current.resources LockscreenLongPress( viewModel = viewModel.longPress, @@ -102,41 +94,7 @@ constructor( modifier = Modifier.fillMaxHeight().weight(weight = 1f), horizontalAlignment = Alignment.CenterHorizontally, ) { - with(clockSection) { - SmallClock( - burnInParams = burnIn.parameters, - onTopChanged = burnIn.onSmallClockTopChanged, - modifier = Modifier.fillMaxWidth(), - ) - } - - with(smartSpaceSection) { - SmartSpace( - burnInParams = burnIn.parameters, - onTopChanged = burnIn.onSmartspaceTopChanged, - modifier = - Modifier.fillMaxWidth() - .padding( - top = { - viewModel.getSmartSpacePaddingTop(resources) - }, - ) - .padding( - bottom = - dimensionResource( - R.dimen - .keyguard_status_view_bottom_margin - ) - ), - ) - } - - if (viewModel.isLargeClockVisible) { - Spacer(modifier = Modifier.weight(weight = 1f)) - with(clockSection) { LargeClock() } - Spacer(modifier = Modifier.weight(weight = 1f)) - } - + with(clockSection) { DefaultClockLayout() } with(mediaCarouselSection) { MediaCarousel() } } with(notificationSection) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt index 152cc67f6c9e..1ab2bc76c1fd 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt @@ -18,27 +18,37 @@ package com.android.systemui.keyguard.ui.composable.section import android.view.ViewGroup import android.widget.FrameLayout +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.viewinterop.AndroidView -import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.modifiers.padding -import com.android.keyguard.KeyguardClockSwitch import com.android.systemui.customization.R as customizationR import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor +import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.largeClockElementKey +import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smallClockElementKey +import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smartspaceElementKey +import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.largeClockScene +import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.smallClockScene +import com.android.systemui.keyguard.ui.composable.blueprint.ClockTransition.defaultClockTransitions +import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn import com.android.systemui.keyguard.ui.composable.modifier.burnInAware import com.android.systemui.keyguard.ui.composable.modifier.onTopPlacementChanged import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel +import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel +import com.android.systemui.res.R import javax.inject.Inject /** Provides small clock and large clock composables for the default clock face. */ @@ -48,112 +58,152 @@ constructor( private val viewModel: KeyguardClockViewModel, private val clockInteractor: KeyguardClockInteractor, private val aodBurnInViewModel: AodBurnInViewModel, + private val lockscreenContentViewModel: LockscreenContentViewModel, + private val smartSpaceSection: SmartSpaceSection, ) { - @Composable - fun SceneScope.SmallClock( - burnInParams: BurnInParameters, - onTopChanged: (top: Float?) -> Unit, + fun DefaultClockLayout( modifier: Modifier = Modifier, ) { - val clockSize by viewModel.clockSize.collectAsState() - val currentClock by viewModel.currentClock.collectAsState() - viewModel.clock = currentClock + val isLargeClockVisible by viewModel.isLargeClockVisible.collectAsState() + val burnIn = rememberBurnIn(clockInteractor) + val currentScene = + if (isLargeClockVisible) { + largeClockScene + } else { + smallClockScene + } - if (clockSize != KeyguardClockSwitch.SMALL || currentClock?.smallClock?.view == null) { - onTopChanged(null) - return + LaunchedEffect(isLargeClockVisible) { + if (isLargeClockVisible) { + burnIn.onSmallClockTopChanged(null) + } } - val view = LocalView.current - - DisposableEffect(view) { - clockInteractor.clockEventController.registerListeners(view) + SceneTransitionLayout( + modifier = modifier, + currentScene = currentScene, + onChangeScene = {}, + transitions = defaultClockTransitions, + ) { + scene(smallClockScene) { + Column { + SmallClock( + burnInParams = burnIn.parameters, + onTopChanged = burnIn.onSmallClockTopChanged, + modifier = Modifier.element(smallClockElementKey).fillMaxWidth() + ) + SmartSpaceContent() + } + } - onDispose { clockInteractor.clockEventController.unregisterListeners() } + scene(largeClockScene) { + Column { + SmartSpaceContent() + LargeClock(modifier = Modifier.element(largeClockElementKey).fillMaxWidth()) + } + } } + } - MovableElement( - key = ClockElementKey, - modifier = modifier, - ) { + @Composable + private fun SceneScope.SmartSpaceContent( + modifier: Modifier = Modifier, + ) { + val burnIn = rememberBurnIn(clockInteractor) + val resources = LocalContext.current.resources + + MovableElement(key = smartspaceElementKey, modifier = modifier) { content { - AndroidView( - factory = { context -> - FrameLayout(context).apply { - val newClockView = checkNotNull(currentClock).smallClock.view - (newClockView.parent as? ViewGroup)?.removeView(newClockView) - addView(newClockView) - } - }, - modifier = - Modifier.padding( - horizontal = - dimensionResource(customizationR.dimen.clock_padding_start) - ) - .padding(top = { viewModel.getSmallClockTopMargin(view.context) }) - .onTopPlacementChanged(onTopChanged) - .burnInAware( - viewModel = aodBurnInViewModel, - params = burnInParams, - ), - update = { - val newClockView = checkNotNull(currentClock).smallClock.view - it.removeAllViews() - (newClockView.parent as? ViewGroup)?.removeView(newClockView) - it.addView(newClockView) - }, - ) + with(smartSpaceSection) { + this@SmartSpaceContent.SmartSpace( + burnInParams = burnIn.parameters, + onTopChanged = burnIn.onSmartspaceTopChanged, + modifier = + Modifier.fillMaxWidth() + .padding( + top = { + lockscreenContentViewModel.getSmartSpacePaddingTop( + resources + ) + }, + bottom = { + resources.getDimensionPixelSize( + R.dimen.keyguard_status_view_bottom_margin + ) + } + ), + ) + } } } } @Composable - fun SceneScope.LargeClock(modifier: Modifier = Modifier) { - val clockSize by viewModel.clockSize.collectAsState() + private fun SceneScope.SmallClock( + burnInParams: BurnInParameters, + onTopChanged: (top: Float?) -> Unit, + modifier: Modifier = Modifier, + ) { val currentClock by viewModel.currentClock.collectAsState() - viewModel.clock = currentClock - - if (clockSize != KeyguardClockSwitch.LARGE) { + if (currentClock?.smallClock?.view == null) { return } + viewModel.clock = currentClock + val context = LocalContext.current + + AndroidView( + factory = { context -> + FrameLayout(context).apply { + val newClockView = checkNotNull(currentClock).smallClock.view + (newClockView.parent as? ViewGroup)?.removeView(newClockView) + addView(newClockView) + } + }, + update = { + val newClockView = checkNotNull(currentClock).smallClock.view + it.removeAllViews() + (newClockView.parent as? ViewGroup)?.removeView(newClockView) + it.addView(newClockView) + }, + modifier = + modifier + .padding( + horizontal = dimensionResource(customizationR.dimen.clock_padding_start) + ) + .padding(top = { viewModel.getSmallClockTopMargin(context) }) + .onTopPlacementChanged(onTopChanged) + .burnInAware( + viewModel = aodBurnInViewModel, + params = burnInParams, + ), + ) + } + + @Composable + private fun SceneScope.LargeClock(modifier: Modifier = Modifier) { + val currentClock by viewModel.currentClock.collectAsState() + viewModel.clock = currentClock if (currentClock?.largeClock?.view == null) { return } - val view = LocalView.current - - DisposableEffect(view) { - clockInteractor.clockEventController.registerListeners(view) - - onDispose { clockInteractor.clockEventController.unregisterListeners() } - } - - MovableElement( - key = ClockElementKey, - modifier = modifier, - ) { - content { - AndroidView( - factory = { context -> - FrameLayout(context).apply { - val newClockView = checkNotNull(currentClock).largeClock.view - (newClockView.parent as? ViewGroup)?.removeView(newClockView) - addView(newClockView) - } - }, - update = { - val newClockView = checkNotNull(currentClock).largeClock.view - it.removeAllViews() - (newClockView.parent as? ViewGroup)?.removeView(newClockView) - it.addView(newClockView) - }, - modifier = Modifier.fillMaxSize() - ) - } - } + AndroidView( + factory = { context -> + FrameLayout(context).apply { + val newClockView = checkNotNull(currentClock).largeClock.view + (newClockView.parent as? ViewGroup)?.removeView(newClockView) + addView(newClockView) + } + }, + update = { + val newClockView = checkNotNull(currentClock).largeClock.view + it.removeAllViews() + (newClockView.parent as? ViewGroup)?.removeView(newClockView) + it.addView(newClockView) + }, + modifier = modifier.fillMaxSize() + ) } } - -private val ClockElementKey = ElementKey("Clock") diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt index 9b718444b75c..d1cc53e093a5 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt @@ -33,7 +33,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView -import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.ui.composable.modifier.burnInAware @@ -60,7 +59,7 @@ constructor( modifier: Modifier = Modifier, ) { Column( - modifier = modifier.element(SmartSpaceElementKey).onTopPlacementChanged(onTopChanged), + modifier = modifier.onTopPlacementChanged(onTopChanged), ) { if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) { return @@ -192,5 +191,3 @@ constructor( ) } } - -private val SmartSpaceElementKey = ElementKey("SmartSpace") diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt index eb71490f049a..5d9b014c5c96 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt @@ -16,6 +16,7 @@ package com.android.systemui.qs.footer.ui.compose +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Canvas import androidx.compose.foundation.LocalIndication @@ -76,9 +77,31 @@ import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel +import com.android.systemui.qs.ui.composable.QuickSettingsTheme import com.android.systemui.res.R import kotlinx.coroutines.launch +@Composable +fun FooterActionsWithAnimatedVisibility( + viewModel: FooterActionsViewModel, + isCustomizing: Boolean, + lifecycleOwner: LifecycleOwner, + footerActionsModifier: (Modifier) -> Modifier, + modifier: Modifier = Modifier, +) { + AnimatedVisibility(visible = !isCustomizing, modifier = modifier.fillMaxWidth()) { + QuickSettingsTheme { + // This view has its own horizontal padding + // TODO(b/321716470) This should use a lifecycle tied to the scene. + FooterActions( + viewModel = viewModel, + qsVisibilityLifecycleOwner = lifecycleOwner, + modifier = footerActionsModifier(Modifier), + ) + } + } +} + /** The Quick Settings footer actions row. */ @Composable fun FooterActions( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt index 91b737d33418..bc48dd1d431f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt @@ -63,12 +63,14 @@ object QuickSettings { } private fun SceneScope.stateForQuickSettingsContent( + isSplitShade: Boolean, squishiness: Float = QuickSettings.SharedValues.SquishinessValues.Default ): QSSceneAdapter.State { return when (val transitionState = layoutState.transitionState) { is TransitionState.Idle -> { when (transitionState.currentScene) { - Scenes.Shade -> QSSceneAdapter.State.QQS + Scenes.Shade -> QSSceneAdapter.State.QQS.takeUnless { isSplitShade } + ?: QSSceneAdapter.State.QS Scenes.QuickSettings -> QSSceneAdapter.State.QS else -> QSSceneAdapter.State.CLOSED } @@ -76,6 +78,7 @@ private fun SceneScope.stateForQuickSettingsContent( is TransitionState.Transition -> with(transitionState) { when { + isSplitShade -> QSSceneAdapter.State.QS fromScene == Scenes.Shade && toScene == Scenes.QuickSettings -> Expanding(progress) fromScene == Scenes.QuickSettings && toScene == Scenes.Shade -> @@ -111,10 +114,11 @@ private fun SceneScope.stateForQuickSettingsContent( fun SceneScope.QuickSettings( qsSceneAdapter: QSSceneAdapter, heightProvider: () -> Int, + isSplitShade: Boolean, modifier: Modifier = Modifier, squishiness: Float = QuickSettings.SharedValues.SquishinessValues.Default, ) { - val contentState = stateForQuickSettingsContent(squishiness) + val contentState = stateForQuickSettingsContent(isSplitShade, squishiness) MovableElement( key = QuickSettings.Elements.Content, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt index 3b8b863fdde2..6ae1410623a3 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt @@ -61,6 +61,7 @@ import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.qs.footer.ui.compose.FooterActions +import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Scenes @@ -238,24 +239,21 @@ private fun SceneScope.QuickSettingsScene( QuickSettings( viewModel.qsSceneAdapter, { viewModel.qsSceneAdapter.qsHeight }, + isSplitShade = false, modifier = Modifier.sysuiResTag("expanded_qs_scroll_view"), ) } } - AnimatedVisibility( - visible = !isCustomizing, - modifier = Modifier.align(Alignment.CenterHorizontally).fillMaxWidth() - ) { - QuickSettingsTheme { - // This view has its own horizontal padding - // TODO(b/321716470) This should use a lifecycle tied to the scene. - FooterActions( - viewModel = footerActionsViewModel, - qsVisibilityLifecycleOwner = lifecycleOwner, - modifier = Modifier.element(QuickSettings.Elements.FooterActions) - ) - } - } + + FooterActionsWithAnimatedVisibility( + viewModel = footerActionsViewModel, + isCustomizing = isCustomizing, + lifecycleOwner = lifecycleOwner, + footerActionsModifier = { modifier -> + modifier.element(QuickSettings.Elements.FooterActions) + }, + modifier = Modifier.align(Alignment.CenterHorizontally), + ) } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt index 82f56abbded6..975829ab3760 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt @@ -20,21 +20,16 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.SceneScope -import com.android.compose.animation.scene.Swipe -import com.android.compose.animation.scene.SwipeDirection import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateSceneFloatAsState import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel +import com.android.systemui.scene.ui.viewmodel.GoneSceneViewModel import javax.inject.Inject -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow /** * "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any @@ -44,22 +39,12 @@ import kotlinx.coroutines.flow.asStateFlow class GoneScene @Inject constructor( - private val notificationsViewModel: NotificationsPlaceholderViewModel, + private val viewModel: GoneSceneViewModel, ) : ComposableScene { override val key = Scenes.Gone override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = - MutableStateFlow<Map<UserAction, UserActionResult>>( - mapOf( - Swipe( - pointerCount = 2, - fromSource = Edge.Top, - direction = SwipeDirection.Down, - ) to UserActionResult(Scenes.QuickSettings), - Swipe(direction = SwipeDirection.Down) to UserActionResult(Scenes.Shade), - ) - ) - .asStateFlow() + viewModel.destinationScenes @Composable override fun SceneScope.Content( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt index 3620cc570c66..51464d059890 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt @@ -19,14 +19,26 @@ package com.android.systemui.shade.ui.composable import android.view.ViewGroup import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.clipScrollableContainer +import androidx.compose.foundation.gestures.Orientation +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.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -36,22 +48,19 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.layout import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexScenePicker -import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.SceneScope -import com.android.compose.animation.scene.Swipe -import com.android.compose.animation.scene.SwipeDirection import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateSceneFloatAsState import com.android.compose.modifiers.thenIf import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.media.controls.ui.composable.MediaCarousel import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager @@ -59,10 +68,12 @@ import com.android.systemui.media.controls.ui.view.MediaHost import com.android.systemui.media.controls.ui.view.MediaHostState import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL import com.android.systemui.notifications.ui.composable.NotificationScrollingStack +import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.ComposableScene +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager @@ -71,11 +82,7 @@ import com.android.systemui.util.animation.MeasurementInput import javax.inject.Inject import javax.inject.Named import kotlin.math.roundToInt -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn object Shade { object Elements { @@ -103,7 +110,6 @@ object Shade { class ShadeScene @Inject constructor( - @Application private val applicationScope: CoroutineScope, private val viewModel: ShadeSceneViewModel, private val tintedIconManagerFactory: TintedIconManager.Factory, private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory, @@ -114,13 +120,7 @@ constructor( override val key = Scenes.Shade override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = - viewModel.upDestinationSceneKey - .map { sceneKey -> destinationScenes(up = sceneKey) } - .stateIn( - scope = applicationScope, - started = SharingStarted.Eagerly, - initialValue = destinationScenes(up = viewModel.upDestinationSceneKey.value), - ) + viewModel.destinationScenes @Composable override fun SceneScope.Content( @@ -141,19 +141,46 @@ constructor( mediaHost.showsOnlyActiveMedia = true mediaHost.init(MediaHierarchyManager.LOCATION_QQS) } +} - private fun destinationScenes( - up: SceneKey, - ): Map<UserAction, UserActionResult> { - return mapOf( - Swipe(SwipeDirection.Up) to UserActionResult(up), - Swipe(SwipeDirection.Down) to UserActionResult(Scenes.QuickSettings), - ) +@Composable +private fun SceneScope.ShadeScene( + viewModel: ShadeSceneViewModel, + createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, + createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, + statusBarIconController: StatusBarIconController, + mediaCarouselController: MediaCarouselController, + mediaHost: MediaHost, + modifier: Modifier = Modifier, +) { + val shadeMode by viewModel.shadeMode.collectAsState() + when (shadeMode) { + is ShadeMode.Single -> + SingleShade( + viewModel = viewModel, + createTintedIconManager = createTintedIconManager, + createBatteryMeterViewController = createBatteryMeterViewController, + statusBarIconController = statusBarIconController, + mediaCarouselController = mediaCarouselController, + mediaHost = mediaHost, + modifier = modifier, + ) + is ShadeMode.Split -> + SplitShade( + viewModel = viewModel, + createTintedIconManager = createTintedIconManager, + createBatteryMeterViewController = createBatteryMeterViewController, + statusBarIconController = statusBarIconController, + mediaCarouselController = mediaCarouselController, + mediaHost = mediaHost, + modifier = modifier, + ) + is ShadeMode.Dual -> error("Dual shade is not yet implemented!") } } @Composable -private fun SceneScope.ShadeScene( +private fun SceneScope.SingleShade( viewModel: ShadeSceneViewModel, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, @@ -162,8 +189,6 @@ private fun SceneScope.ShadeScene( mediaHost: MediaHost, modifier: Modifier = Modifier, ) { - val density = LocalDensity.current - val layoutWidth = remember { mutableStateOf(0) } val maxNotifScrimTop = remember { mutableStateOf(0f) } val tileSquishiness by animateSceneFloatAsState(value = 1f, key = QuickSettings.SharedValues.TilesSquishiness) @@ -203,38 +228,15 @@ private fun SceneScope.ShadeScene( (viewModel.qsSceneAdapter.qqsHeight * tileSquishiness) .roundToInt() }, + isSplitShade = false, squishiness = tileSquishiness, ) - if (viewModel.isMediaVisible()) { - val mediaHeight = - dimensionResource(R.dimen.qs_media_session_height_expanded) - MediaCarousel( - modifier = - Modifier.height(mediaHeight).fillMaxWidth().layout { - measurable, - constraints -> - val placeable = measurable.measure(constraints) - - // Notify controller to size the carousel for the - // current space - mediaHost.measurementInput = - MeasurementInput(placeable.width, placeable.height) - mediaCarouselController.setSceneContainerSize( - placeable.width, - placeable.height - ) - - layout(placeable.width, placeable.height) { - placeable.placeRelative(0, 0) - } - }, - mediaHost = mediaHost, - layoutWidth = layoutWidth.value, - layoutHeight = with(density) { mediaHeight.toPx() }.toInt(), - carouselController = mediaCarouselController, - ) - } + MediaIfVisible( + viewModel = viewModel, + mediaCarouselController = mediaCarouselController, + mediaHost = mediaHost, + ) Spacer(modifier = Modifier.height(16.dp)) } @@ -263,3 +265,133 @@ private fun SceneScope.ShadeScene( } } } + +@Composable +private fun SceneScope.SplitShade( + viewModel: ShadeSceneViewModel, + createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, + createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, + statusBarIconController: StatusBarIconController, + mediaCarouselController: MediaCarouselController, + mediaHost: MediaHost, + modifier: Modifier = Modifier, +) { + val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() + val lifecycleOwner = LocalLifecycleOwner.current + val footerActionsViewModel = + remember(lifecycleOwner, viewModel) { viewModel.getFooterActionsViewModel(lifecycleOwner) } + + val navBarBottomHeight = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + val density = LocalDensity.current + LaunchedEffect(navBarBottomHeight, density) { + with(density) { + viewModel.qsSceneAdapter.applyBottomNavBarPadding(navBarBottomHeight.roundToPx()) + } + } + + val quickSettingsScrollState = rememberScrollState() + LaunchedEffect(isCustomizing, quickSettingsScrollState) { + if (isCustomizing) { + quickSettingsScrollState.scrollTo(0) + } + } + + Box( + modifier = + modifier + .fillMaxSize() + .element(Shade.Elements.BackgroundScrim) + .background(colorResource(R.color.shade_scrim_background_dark)) + ) { + Column( + modifier = Modifier.fillMaxSize(), + ) { + CollapsedShadeHeader( + viewModel = viewModel.shadeHeaderViewModel, + createTintedIconManager = createTintedIconManager, + createBatteryMeterViewController = createBatteryMeterViewController, + statusBarIconController = statusBarIconController, + modifier = Modifier.padding(horizontal = Shade.Dimensions.HorizontalPadding) + ) + + Row(modifier = Modifier.fillMaxWidth().weight(1f)) { + Column( + verticalArrangement = Arrangement.Top, + modifier = + Modifier.weight(1f).fillMaxHeight().thenIf(!isCustomizing) { + Modifier.verticalNestedScrollToScene() + .verticalScroll(quickSettingsScrollState) + .clipScrollableContainer(Orientation.Horizontal) + .padding(bottom = navBarBottomHeight) + } + ) { + QuickSettings( + qsSceneAdapter = viewModel.qsSceneAdapter, + heightProvider = { viewModel.qsSceneAdapter.qsHeight }, + isSplitShade = true, + modifier = Modifier.fillMaxWidth(), + ) + + MediaIfVisible( + viewModel = viewModel, + mediaCarouselController = mediaCarouselController, + mediaHost = mediaHost, + modifier = Modifier.fillMaxWidth(), + ) + + Spacer( + modifier = Modifier.weight(1f), + ) + + FooterActionsWithAnimatedVisibility( + viewModel = footerActionsViewModel, + isCustomizing = isCustomizing, + lifecycleOwner = lifecycleOwner, + footerActionsModifier = { modifier -> + modifier.element(QuickSettings.Elements.FooterActions) + }, + modifier = Modifier.align(Alignment.CenterHorizontally), + ) + } + + NotificationScrollingStack( + viewModel = viewModel.notifications, + maxScrimTop = { 0f }, + modifier = Modifier.weight(1f).fillMaxHeight(), + ) + } + } + } +} + +@Composable +private fun SceneScope.MediaIfVisible( + viewModel: ShadeSceneViewModel, + mediaCarouselController: MediaCarouselController, + mediaHost: MediaHost, + modifier: Modifier = Modifier, +) { + if (viewModel.isMediaVisible()) { + val density = LocalDensity.current + val layoutWidth = remember { mutableStateOf(0) } + val mediaHeight = dimensionResource(R.dimen.qs_media_session_height_expanded) + + MediaCarousel( + modifier = + modifier.height(mediaHeight).fillMaxWidth().layout { measurable, constraints -> + val placeable = measurable.measure(constraints) + + // Notify controller to size the carousel for the + // current space + mediaHost.measurementInput = MeasurementInput(placeable.width, placeable.height) + mediaCarouselController.setSceneContainerSize(placeable.width, placeable.height) + + layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) } + }, + mediaHost = mediaHost, + layoutWidth = layoutWidth.value, + layoutHeight = with(density) { mediaHeight.toPx() }.toInt(), + carouselController = mediaCarouselController, + ) + } +} diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt index b9b472f5ac6d..6cff30cf0369 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt @@ -21,6 +21,7 @@ import androidx.compose.animation.core.AnimationVector1D import androidx.compose.animation.core.SpringSpec import kotlin.math.absoluteValue import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.launch /** @@ -147,13 +148,16 @@ private fun CoroutineScope.animate( } // Animate the progress to its target value. - launch { animatable.animateTo(targetProgress, animationSpec) } - .invokeOnCompletion { - // Settle the state to Idle(target). Note that this will do nothing if this transition - // was replaced/interrupted by another one, and this also runs if this coroutine is - // cancelled, i.e. if [this] coroutine scope is cancelled. - layoutState.finishTransition(transition, target) - } + transition.job = + launch { animatable.animateTo(targetProgress, animationSpec) } + .apply { + invokeOnCompletion { + // Settle the state to Idle(target). Note that this will do nothing if this + // transition was replaced/interrupted by another one, and this also runs if + // this coroutine is cancelled, i.e. if [this] coroutine scope is cancelled. + layoutState.finishTransition(transition, target) + } + } return transition } @@ -174,8 +178,13 @@ private class OneOffTransition( */ lateinit var animatable: Animatable<Float, AnimationVector1D> + /** The job that is animating [animatable]. */ + lateinit var job: Job + override val progress: Float get() = animatable.value + + override fun finish(): Job = job } // TODO(b/290184746): Compute a good default visibility threshold that depends on the layout size 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 b94e49bb0edc..6114499a2f5e 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 @@ -20,6 +20,7 @@ package com.android.compose.animation.scene import android.util.Log import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.AnimationVector1D import androidx.compose.animation.core.SpringSpec import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.getValue @@ -96,9 +97,15 @@ internal class DraggableHandlerImpl( return false } + val swipeTransition = dragController.swipeTransition + + // Don't intercept a transition that is finishing. + if (swipeTransition.isFinishing) { + return false + } + // Only intercept the current transition if one of the 2 swipes results is also a transition // between the same pair of scenes. - val swipeTransition = dragController.swipeTransition val fromScene = swipeTransition._currentScene val swipes = computeSwipes(fromScene, startedPosition, pointersDown = 1) val (upOrLeft, downOrRight) = swipes.computeSwipesResults(fromScene) @@ -149,15 +156,24 @@ internal class DraggableHandlerImpl( val fromScene = layoutImpl.scene(transitionState.currentScene) val swipes = computeSwipes(fromScene, startedPosition, pointersDown) - val result = swipes.findUserActionResult(fromScene, overSlop, true) - - // As we were unable to locate a valid target scene, the initial SwipeTransition cannot be - // defined. Consequently, a simple NoOp Controller will be returned. - if (result == null) return NoOpDragController + val result = + swipes.findUserActionResult(fromScene, overSlop, true) + // As we were unable to locate a valid target scene, the initial SwipeTransition + // cannot be defined. Consequently, a simple NoOp Controller will be returned. + ?: return NoOpDragController return updateDragController( swipes = swipes, - swipeTransition = SwipeTransition(fromScene, result, swipes, layoutImpl, orientation) + swipeTransition = + SwipeTransition( + layoutImpl.state, + coroutineScope, + fromScene, + result, + swipes, + layoutImpl, + orientation, + ) ) } @@ -277,7 +293,7 @@ private class DragControllerImpl( * @return the consumed delta */ override fun onDrag(delta: Float) { - if (delta == 0f || !isDrivingTransition) return + if (delta == 0f || !isDrivingTransition || swipeTransition.isFinishing) return swipeTransition.dragOffset += delta val (fromScene, acceleratedOffset) = @@ -305,6 +321,8 @@ private class DragControllerImpl( ) { val swipeTransition = SwipeTransition( + layoutState = layoutState, + coroutineScope = draggableHandler.coroutineScope, fromScene = fromScene, result = result, swipes = swipes, @@ -355,15 +373,9 @@ private class DragControllerImpl( } } - private fun snapToScene(scene: SceneKey) { - if (!isDrivingTransition) return - swipeTransition.cancelOffsetAnimation() - layoutState.finishTransition(swipeTransition, idleScene = scene) - } - override fun onStop(velocity: Float, canChangeScene: Boolean) { // The state was changed since the drag started; don't do anything. - if (!isDrivingTransition) { + if (!isDrivingTransition || swipeTransition.isFinishing) { return } @@ -389,7 +401,7 @@ private class DragControllerImpl( coroutineScope = draggableHandler.coroutineScope, initialVelocity = velocity, targetOffset = targetOffset, - onAnimationCompleted = { snapToScene(targetScene.key) } + targetScene = targetScene.key, ) } @@ -451,12 +463,14 @@ private class DragControllerImpl( val result = swipes.findUserActionResultStrict(velocity) if (result == null) { // We will not animate - snapToScene(fromScene.key) + swipeTransition.snapToScene(fromScene.key) return } val newSwipeTransition = SwipeTransition( + layoutState = layoutState, + coroutineScope = draggableHandler.coroutineScope, fromScene = fromScene, result = result, swipes = swipes, @@ -514,6 +528,8 @@ private class DragControllerImpl( } private fun SwipeTransition( + layoutState: BaseSceneTransitionLayoutState, + coroutineScope: CoroutineScope, fromScene: Scene, result: UserActionResult, swipes: Swipes, @@ -530,6 +546,8 @@ private fun SwipeTransition( } return SwipeTransition( + layoutState = layoutState, + coroutineScope = coroutineScope, key = result.transitionKey, _fromScene = fromScene, _toScene = layoutImpl.scene(result.toScene), @@ -541,6 +559,8 @@ private fun SwipeTransition( private fun SwipeTransition(old: SwipeTransition): SwipeTransition { return SwipeTransition( + layoutState = old.layoutState, + coroutineScope = old.coroutineScope, key = old.key, _fromScene = old._fromScene, _toScene = old._toScene, @@ -555,6 +575,8 @@ private fun SwipeTransition(old: SwipeTransition): SwipeTransition { } private class SwipeTransition( + val layoutState: BaseSceneTransitionLayoutState, + val coroutineScope: CoroutineScope, val key: TransitionKey?, val _fromScene: Scene, val _toScene: Scene, @@ -573,7 +595,7 @@ private class SwipeTransition( // Important: If we are going to return early because distance is equal to 0, we should // still make sure we read the offset before returning so that the calling code still // subscribes to the offset value. - val offset = if (isAnimatingOffset) offsetAnimatable.value else dragOffset + val offset = offsetAnimation?.animatable?.value ?: dragOffset val distance = distance() if (distance == DistanceUnspecified) { @@ -588,20 +610,11 @@ private class SwipeTransition( /** The current offset caused by the drag gesture. */ var dragOffset by mutableFloatStateOf(0f) - /** - * Whether the offset is animated (the user lifted their finger) or if it is driven by gesture. - */ - var isAnimatingOffset by mutableStateOf(false) + /** The offset animation that animates the offset once the user lifts their finger. */ + private var offsetAnimation: OffsetAnimation? by mutableStateOf(null) - // If we are not animating offset, it means the offset is being driven by the user's finger. override val isUserInputOngoing: Boolean - get() = !isAnimatingOffset - - /** The animatable used to animate the offset once the user lifted its finger. */ - val offsetAnimatable = Animatable(0f, OffsetVisibilityThreshold) - - /** Job to check that there is at most one offset animation in progress. */ - private var offsetAnimationJob: Job? = null + get() = offsetAnimation == null /** * The [TransformationSpecImpl] associated to this transition. @@ -617,6 +630,10 @@ private class SwipeTransition( private var lastDistance = DistanceUnspecified + /** Whether [TransitionState.Transition.finish] was called on this transition. */ + var isFinishing = false + private set + /** * The signed distance between [fromScene] and [toScene]. It is negative if [fromScene] is above * or to the left of [toScene]. @@ -647,25 +664,21 @@ private class SwipeTransition( return distance } - /** Ends any previous [offsetAnimationJob] and runs the new [job]. */ - private fun startOffsetAnimation(job: () -> Job) { + /** Ends any previous [offsetAnimation] and runs the new [animation]. */ + private fun startOffsetAnimation(animation: () -> OffsetAnimation): OffsetAnimation { cancelOffsetAnimation() - offsetAnimationJob = job() + return animation().also { offsetAnimation = it } } /** Cancel any ongoing offset animation. */ // TODO(b/317063114) This should be a suspended function to avoid multiple jobs running at // the same time. fun cancelOffsetAnimation() { - offsetAnimationJob?.cancel() - finishOffsetAnimation() - } + val animation = offsetAnimation ?: return + offsetAnimation = null - fun finishOffsetAnimation() { - if (isAnimatingOffset) { - isAnimatingOffset = false - dragOffset = offsetAnimatable.value - } + dragOffset = animation.animatable.value + animation.job.cancel() } fun animateOffset( @@ -673,32 +686,74 @@ private class SwipeTransition( coroutineScope: CoroutineScope, initialVelocity: Float, targetOffset: Float, - onAnimationCompleted: () -> Unit, - ) { - startOffsetAnimation { - coroutineScope.launch { - animateOffset(targetOffset, initialVelocity) - onAnimationCompleted() - } + targetScene: SceneKey, + ): OffsetAnimation { + return startOffsetAnimation { + val animatable = Animatable(dragOffset, OffsetVisibilityThreshold) + val job = + coroutineScope + .launch { + animatable.animateTo( + targetValue = targetOffset, + animationSpec = swipeSpec, + initialVelocity = initialVelocity, + ) + } + // Make sure that we settle to target scene at the end of the animation or if + // the animation is cancelled. + .apply { invokeOnCompletion { snapToScene(targetScene) } } + + OffsetAnimation(animatable, job) } } - private suspend fun animateOffset(targetOffset: Float, initialVelocity: Float) { - if (!isAnimatingOffset) { - offsetAnimatable.snapTo(dragOffset) + fun snapToScene(scene: SceneKey) { + if (layoutState.transitionState != this) return + cancelOffsetAnimation() + layoutState.finishTransition(this, idleScene = scene) + } + + override fun finish(): Job { + if (isFinishing) return requireNotNull(offsetAnimation).job + isFinishing = true + + // If we were already animating the offset, simply return the job. + offsetAnimation?.let { + return it.job } - isAnimatingOffset = true - val animationSpec = transformationSpec - offsetAnimatable.animateTo( - targetValue = targetOffset, - animationSpec = swipeSpec, - initialVelocity = initialVelocity, - ) + // Animate to the current scene. + val targetScene = currentScene + val targetOffset = + if (targetScene == fromScene) { + 0f + } else { + val distance = distance() + check(distance != DistanceUnspecified) { + "targetScene != fromScene but distance is unspecified" + } + distance + } - finishOffsetAnimation() + val animation = + animateOffset( + coroutineScope = coroutineScope, + initialVelocity = 0f, + targetOffset = targetOffset, + targetScene = currentScene, + ) + check(offsetAnimation == animation) + return animation.job } + internal class OffsetAnimation( + /** The animatable used to animate the offset. */ + val animatable: Animatable<Float, AnimationVector1D>, + + /** The job in which [animatable] is animated. */ + val job: Job, + ) + companion object { const val DistanceUnspecified = 0f } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt index cdc4778dbf4d..be066fd0018a 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt @@ -133,18 +133,14 @@ private class MovableElementScopeImpl( if (shouldComposeMovableElement) { val movableContent: MovableElementContent = layoutImpl.movableContents[element] - ?: movableContentOf { - contentScope: MovableElementContentScope, - content: @Composable MovableElementContentScope.() -> Unit -> - contentScope.content() - } + ?: movableContentOf { content: @Composable () -> Unit -> content() } .also { layoutImpl.movableContents[element] = it } // Important: Don't introduce any parent Box or other layout here, because contentScope // delegates its BoxScope implementation to the Box where this content() function is // called, so it's important that this movableContent is composed directly under that // Box. - movableContent(contentScope, content) + movableContent { contentScope.content() } } else { // If we are not composed, we still need to lay out an empty space with the same *target // size* as its movable content, i.e. the same *size when idle*. During transitions, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt index 1670e9cee731..25b0895fafb3 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt @@ -38,15 +38,8 @@ import androidx.compose.ui.util.fastForEach import com.android.compose.ui.util.lerp import kotlinx.coroutines.CoroutineScope -/** - * The type for the content of movable elements. - * - * TODO(b/317972419): Revert back to make this movable content have a single @Composable lambda - * parameter. - */ -internal typealias MovableElementContent = - @Composable - (MovableElementContentScope, @Composable MovableElementContentScope.() -> Unit) -> Unit +/** The type for the content of movable elements. */ +internal typealias MovableElementContent = @Composable (@Composable () -> Unit) -> Unit @Stable internal class SceneTransitionLayoutImpl( 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 0fa19bb33818..86124df295b4 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 @@ -31,6 +31,7 @@ import com.android.compose.animation.scene.transition.link.LinkedTransition import com.android.compose.animation.scene.transition.link.StateLink import kotlin.math.absoluteValue import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.channels.Channel /** @@ -188,13 +189,8 @@ sealed interface TransitionState { val fromScene: SceneKey, /** The scene this transition is going to. Can't be the same as fromScene */ - val toScene: SceneKey + val toScene: SceneKey, ) : TransitionState { - - init { - check(fromScene != toScene) - } - /** * The progress of the transition. This is usually in the `[0; 1]` range, but it can also be * less than `0` or greater than `1` when using transitions with a spring AnimationSpec or @@ -208,6 +204,21 @@ sealed interface TransitionState { /** Whether user input is currently driving the transition. */ abstract val isUserInputOngoing: Boolean + init { + check(fromScene != toScene) + } + + /** + * Force this transition to finish and animate to [currentScene], so that this transition + * progress will settle to either 0% (if [currentScene] == [fromScene]) or 100% (if + * [currentScene] == [toScene]) in a finite amount of time. + * + * @return the [Job] that animates the progress to [currentScene]. It can be used to wait + * until the animation is complete or cancel it to snap to [currentScene]. Calling + * [finish] multiple times will return the same [Job]. + */ + abstract fun finish(): Job + /** * Whether we are transitioning. If [from] or [to] is empty, we will also check that they * match the scenes we are animating from and/or to. diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt index 33b57b25fd10..73393a1ab0cf 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt @@ -18,6 +18,7 @@ package com.android.compose.animation.scene.transition.link import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.TransitionState +import kotlinx.coroutines.Job /** A linked transition which is driven by a [originalTransition]. */ internal class LinkedTransition( @@ -43,4 +44,6 @@ internal class LinkedTransition( override val progress: Float get() = originalTransition.progress + + override fun finish(): Job = originalTransition.finish() } 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 eb9b4280aacb..1e9a7e2bb667 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 @@ -39,6 +39,7 @@ import com.android.compose.test.runMonotonicClockTest import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.launch import org.junit.Test import org.junit.runner.RunWith @@ -892,6 +893,50 @@ class DraggableHandlerTest { } @Test + fun finish() = runGestureTest { + // Start at scene C. + navigateToSceneC() + + // Swipe up from the middle to transition to scene B. + val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f) + onDragStarted(startedPosition = middle, overSlop = up(0.1f)) + assertTransition(fromScene = SceneC, toScene = SceneB, isUserInputOngoing = true) + + // The current transition can be intercepted. + assertThat(draggableHandler.shouldImmediatelyIntercept(middle)).isTrue() + + // Finish the transition. + val transition = transitionState as Transition + val job = transition.finish() + assertTransition(isUserInputOngoing = false) + + // The current transition can not be intercepted anymore. + assertThat(draggableHandler.shouldImmediatelyIntercept(middle)).isFalse() + + // Calling finish() multiple times returns the same Job. + assertThat(transition.finish()).isSameInstanceAs(job) + assertThat(transition.finish()).isSameInstanceAs(job) + assertThat(transition.finish()).isSameInstanceAs(job) + + // We can join the job to wait for the animation to end. + assertTransition() + job.join() + assertIdle(SceneC) + } + + @Test + fun finish_cancelled() = runGestureTest { + // Swipe up from the middle to transition to scene B. + val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f) + onDragStarted(startedPosition = middle, overSlop = up(0.1f)) + assertTransition(fromScene = SceneA, toScene = SceneB) + + // Finish the transition and cancel the returned job. + (transitionState as Transition).finish().cancelAndJoin() + assertIdle(SceneA) + } + + @Test fun blockTransition() = runGestureTest { assertIdle(SceneA) @@ -951,4 +996,15 @@ class DraggableHandlerTest { assertThat(transition).isNotNull() assertThat(transition!!.progress).isEqualTo(-0.1f) } + + @Test + fun transitionIsImmediatelyUpdatedWhenReleasingFinger() = runGestureTest { + // Swipe up from the middle to transition to scene B. + val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f) + val dragController = onDragStarted(startedPosition = middle, overSlop = up(0.1f)) + assertTransition(fromScene = SceneA, toScene = SceneB, isUserInputOngoing = true) + + dragController.onDragStopped(velocity = 0f) + assertTransition(isUserInputOngoing = false) + } } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt index 35cb691e6e37..224ffe29a1b8 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt @@ -45,7 +45,6 @@ import androidx.compose.ui.unit.dp import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.compose.test.assertSizeIsEqualTo import com.google.common.truth.Truth.assertThat -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -262,7 +261,6 @@ class MovableElementTest { } @Test - @Ignore("b/317972419#comment2") fun movableElementContentIsRecomposedIfContentParametersChange() { @Composable fun SceneScope.MovableFoo(text: String, modifier: Modifier = Modifier) { diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt index 3cbcd73a0adb..9baabc3cfb57 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt @@ -28,6 +28,8 @@ import com.android.compose.animation.scene.transition.link.StateLink import com.android.compose.test.runMonotonicClockTest import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.job import kotlinx.coroutines.launch import org.junit.Rule import org.junit.Test @@ -37,16 +39,6 @@ import org.junit.runner.RunWith class SceneTransitionLayoutStateTest { @get:Rule val rule = createComposeRule() - class TestableTransition( - fromScene: SceneKey, - toScene: SceneKey, - ) : TransitionState.Transition(fromScene, toScene) { - override var currentScene: SceneKey = fromScene - override var progress: Float = 0.0f - override var isInitiatedByUserInput: Boolean = false - override var isUserInputOngoing: Boolean = false - } - @Test fun isTransitioningTo_idle() { val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) @@ -83,25 +75,31 @@ class SceneTransitionLayoutStateTest { assertThat(transition).isNotNull() assertThat(state.transitionState).isEqualTo(transition) - testScheduler.advanceUntilIdle() + transition!!.finish().join() assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneB)) } @Test fun setTargetScene_transitionToSameScene() = runMonotonicClockTest { val state = MutableSceneTransitionLayoutState(SceneA) - assertThat(state.setTargetScene(SceneB, coroutineScope = this)).isNotNull() + + val transition = state.setTargetScene(SceneB, coroutineScope = this) + assertThat(transition).isNotNull() assertThat(state.setTargetScene(SceneB, coroutineScope = this)).isNull() - testScheduler.advanceUntilIdle() + + transition!!.finish().join() assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneB)) } @Test fun setTargetScene_transitionToDifferentScene() = runMonotonicClockTest { val state = MutableSceneTransitionLayoutState(SceneA) + assertThat(state.setTargetScene(SceneB, coroutineScope = this)).isNotNull() - assertThat(state.setTargetScene(SceneC, coroutineScope = this)).isNotNull() - testScheduler.advanceUntilIdle() + val transition = state.setTargetScene(SceneC, coroutineScope = this) + assertThat(transition).isNotNull() + + transition!!.finish().join() assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneC)) } @@ -127,11 +125,22 @@ class SceneTransitionLayoutStateTest { assertThat(state.transitionState).isEqualTo(transition) // Cancelling the scope/job still sets the state to Idle(targetScene). - job.cancel() - testScheduler.advanceUntilIdle() + job.cancelAndJoin() assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneB)) } + @Test + fun transition_finishReturnsTheSameJobWhenCalledMultipleTimes() = runMonotonicClockTest { + val state = MutableSceneTransitionLayoutState(SceneA) + val transition = state.setTargetScene(SceneB, coroutineScope = this) + assertThat(transition).isNotNull() + + val job = transition!!.finish() + assertThat(transition.finish()).isSameInstanceAs(job) + assertThat(transition.finish()).isSameInstanceAs(job) + assertThat(transition.finish()).isSameInstanceAs(job) + } + private fun setupLinkedStates( parentInitialScene: SceneKey = SceneC, childInitialScene: SceneKey = SceneA, @@ -159,7 +168,7 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_startsLinkAndFinishesLinkInToState() { val (parentState, childState) = setupLinkedStates() - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue() @@ -195,7 +204,7 @@ class SceneTransitionLayoutStateTest { MutableSceneTransitionLayoutState(SceneA, stateLinks = link) as BaseSceneTransitionLayoutState - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue() @@ -212,12 +221,13 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_linkProgressIsEqual() { val (parentState, childState) = setupLinkedStates() - val childTransition = TestableTransition(SceneA, SceneB) + var progress = 0f + val childTransition = transition(SceneA, SceneB, progress = { progress }) childState.startTransition(childTransition, null) assertThat(parentState.currentTransition?.progress).isEqualTo(0f) - childTransition.progress = .5f + progress = .5f assertThat(parentState.currentTransition?.progress).isEqualTo(.5f) } @@ -225,7 +235,7 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_reverseTransitionIsNotLinked() { val (parentState, childState) = setupLinkedStates() - val childTransition = TestableTransition(SceneB, SceneA) + val childTransition = transition(SceneB, SceneA) childState.startTransition(childTransition, null) assertThat(childState.isTransitioning(SceneB, SceneA)).isTrue() @@ -240,7 +250,7 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_startsLinkAndFinishesLinkInFromState() { val (parentState, childState) = setupLinkedStates() - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) childState.finishTransition(childTransition, SceneA) @@ -252,7 +262,7 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_startsLinkAndFinishesLinkInUnknownState() { val (parentState, childState) = setupLinkedStates() - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) childState.finishTransition(childTransition, SceneD) @@ -264,8 +274,8 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_startsLinkButLinkedStateIsTakenOver() { val (parentState, childState) = setupLinkedStates() - val childTransition = TestableTransition(SceneA, SceneB) - val parentTransition = TestableTransition(SceneC, SceneA) + val childTransition = transition(SceneA, SceneB) + val parentTransition = transition(SceneC, SceneA) childState.startTransition(childTransition, null) parentState.startTransition(parentTransition, null) @@ -315,9 +325,9 @@ class SceneTransitionLayoutStateTest { @Test fun snapToIdleIfClose_snapToStart() = runMonotonicClockTest { - val state = MutableSceneTransitionLayoutStateImpl(TestScenes.SceneA, SceneTransitions.Empty) + val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) state.startTransition( - transition(from = TestScenes.SceneA, to = TestScenes.SceneB, progress = { 0.2f }), + transition(from = SceneA, to = TestScenes.SceneB, progress = { 0.2f }), transitionKey = null ) assertThat(state.isTransitioning()).isTrue() @@ -329,14 +339,14 @@ class SceneTransitionLayoutStateTest { // Go to the initial scene if it is close to 0. assertThat(state.snapToIdleIfClose(threshold = 0.2f)).isTrue() assertThat(state.isTransitioning()).isFalse() - assertThat(state.transitionState).isEqualTo(TransitionState.Idle(TestScenes.SceneA)) + assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneA)) } @Test fun snapToIdleIfClose_snapToEnd() = runMonotonicClockTest { - val state = MutableSceneTransitionLayoutStateImpl(TestScenes.SceneA, SceneTransitions.Empty) + val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) state.startTransition( - transition(from = TestScenes.SceneA, to = TestScenes.SceneB, progress = { 0.8f }), + transition(from = SceneA, to = TestScenes.SceneB, progress = { 0.8f }), transitionKey = null ) assertThat(state.isTransitioning()).isTrue() @@ -354,7 +364,7 @@ class SceneTransitionLayoutStateTest { @Test fun linkedTransition_fuzzyLinksAreMatchedAndStarted() { val (parentState, childState) = setupLinkedStates(SceneC, SceneA, null, null, null, SceneD) - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue() @@ -370,7 +380,7 @@ class SceneTransitionLayoutStateTest { val (parentState, childState) = setupLinkedStates(SceneC, SceneA, SceneA, null, null, SceneD) - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue() @@ -385,7 +395,7 @@ class SceneTransitionLayoutStateTest { fun linkedTransition_fuzzyLinksAreNotMatched() { val (parentState, childState) = setupLinkedStates(SceneC, SceneA, SceneB, null, SceneC, SceneD) - val childTransition = TestableTransition(SceneA, SceneB) + val childTransition = transition(SceneA, SceneB) childState.startTransition(childTransition, null) assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue() @@ -402,18 +412,12 @@ class SceneTransitionLayoutStateTest { sceneTransitions, ) state.startTransition( - object : - TransitionState.Transition(SceneA, SceneB), - TransitionState.HasOverscrollProperties { - override val currentScene: SceneKey = SceneA - override val progress: Float - get() = progress() - - override val isInitiatedByUserInput: Boolean = false - override val isUserInputOngoing: Boolean = false - override val isUpOrLeft: Boolean = false - override val orientation: Orientation = Orientation.Vertical - }, + transition( + from = SceneA, + to = SceneB, + progress = progress, + orientation = Orientation.Vertical, + ), transitionKey = null ) assertThat(state.isTransitioning()).isTrue() diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/Transition.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/Transition.kt index 238b21e1ea37..153d2b8769b3 100644 --- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/Transition.kt +++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/Transition.kt @@ -16,6 +16,9 @@ package com.android.compose.animation.scene +import androidx.compose.foundation.gestures.Orientation +import kotlinx.coroutines.Job + /** A utility to easily create a [TransitionState.Transition] in tests. */ fun transition( from: SceneKey, @@ -23,11 +26,21 @@ fun transition( progress: () -> Float = { 0f }, isInitiatedByUserInput: Boolean = false, isUserInputOngoing: Boolean = false, + isUpOrLeft: Boolean = false, + orientation: Orientation = Orientation.Horizontal, ): TransitionState.Transition { - return object : TransitionState.Transition(from, to) { + return object : TransitionState.Transition(from, to), TransitionState.HasOverscrollProperties { override val currentScene: SceneKey = from - override val progress: Float = progress() + override val progress: Float + get() = progress() + override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput override val isUserInputOngoing: Boolean = isUserInputOngoing + override val isUpOrLeft: Boolean = isUpOrLeft + override val orientation: Orientation = orientation + + override fun finish(): Job { + error("finish() is not supported in test transitions") + } } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt new file mode 100644 index 000000000000..def63ec5b171 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.communal + +import android.service.dream.dreamManager +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository +import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository +import com.android.systemui.keyguard.domain.interactor.keyguardInteractor +import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.kosmos.testScope +import com.android.systemui.power.data.repository.fakePowerRepository +import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.power.shared.model.ScreenPowerState +import com.android.systemui.testKosmos +import com.android.systemui.util.mockito.whenever +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.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.never +import org.mockito.Mockito.verify + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +class CommunalDreamStartableTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + private lateinit var underTest: CommunalDreamStartable + + private val dreamManager by lazy { kosmos.dreamManager } + private val keyguardRepository by lazy { kosmos.fakeKeyguardRepository } + private val powerRepository by lazy { kosmos.fakePowerRepository } + + @Before + fun setUp() { + underTest = + CommunalDreamStartable( + powerInteractor = kosmos.powerInteractor, + keyguardInteractor = kosmos.keyguardInteractor, + keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor, + dreamManager = dreamManager, + bgScope = kosmos.applicationCoroutineScope, + ) + .apply { start() } + } + + @Test + fun startDreamWhenTransitioningToHub() = + testScope.runTest { + keyguardRepository.setDreaming(false) + powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) + whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true) + runCurrent() + + verify(dreamManager, never()).startDream() + + transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB) + + verify(dreamManager).startDream() + } + + @Test + fun shouldNotStartDreamWhenIneligibleToDream() = + testScope.runTest { + keyguardRepository.setDreaming(false) + powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) + // Not eligible to dream + whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(false) + transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB) + + verify(dreamManager, never()).startDream() + } + + @Test + fun shouldNotStartDreamIfAlreadyDreaming() = + testScope.runTest { + keyguardRepository.setDreaming(true) + powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) + whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true) + transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB) + + verify(dreamManager, never()).startDream() + } + + @Test + fun shouldNotStartDreamForInvalidTransition() = + testScope.runTest { + keyguardRepository.setDreaming(true) + powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) + whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true) + + // Verify we do not trigger dreaming for any other state besides glanceable hub + for (state in KeyguardState.entries) { + if (state == KeyguardState.GLANCEABLE_HUB) continue + transition(from = KeyguardState.GLANCEABLE_HUB, to = state) + verify(dreamManager, never()).startDream() + } + } + + private suspend fun TestScope.transition(from: KeyguardState, to: KeyguardState) { + kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps( + from = from, + to = to, + testScope = this + ) + runCurrent() + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt index eafd5038759c..a5707e1f6fe4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt @@ -19,8 +19,12 @@ package com.android.systemui.communal.domain.interactor import android.app.smartspace.SmartspaceTarget import android.appwidget.AppWidgetProviderInfo +import android.content.Intent import android.content.pm.UserInfo import android.os.UserHandle +import android.os.UserManager +import android.os.userManager +import android.provider.Settings import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED import android.widget.RemoteViews import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -50,6 +54,8 @@ import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.kosmos.testScope +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.plugins.activityStarter import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags @@ -61,6 +67,9 @@ import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.FakeUserRepository import com.android.systemui.user.data.repository.fakeUserRepository +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.argumentCaptor +import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.settings.fakeSettings @@ -73,6 +82,8 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.mock import org.mockito.Mockito.verify @@ -103,6 +114,8 @@ class CommunalInteractorTest : SysuiTestCase() { private lateinit var editWidgetsActivityStarter: EditWidgetsActivityStarter private lateinit var sceneInteractor: SceneInteractor private lateinit var userTracker: FakeUserTracker + private lateinit var activityStarter: ActivityStarter + private lateinit var userManager: UserManager private lateinit var underTest: CommunalInteractor @@ -121,9 +134,13 @@ class CommunalInteractorTest : SysuiTestCase() { communalPrefsRepository = kosmos.fakeCommunalPrefsRepository sceneInteractor = kosmos.sceneInteractor userTracker = kosmos.fakeUserTracker + activityStarter = kosmos.activityStarter + userManager = kosmos.userManager whenever(mainUser.isMain).thenReturn(true) whenever(secondaryUser.isMain).thenReturn(false) + whenever(userManager.isQuietModeEnabled(any<UserHandle>())).thenReturn(false) + whenever(userManager.isManagedProfile(anyInt())).thenReturn(false) userRepository.setUserInfos(listOf(mainUser, secondaryUser)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) @@ -800,6 +817,16 @@ class CommunalInteractorTest : SysuiTestCase() { } @Test + fun navigateToCommunalWidgetSettings_startsActivity() = + testScope.runTest { + underTest.navigateToCommunalWidgetSettings() + val intentCaptor = argumentCaptor<Intent>() + verify(activityStarter) + .postStartActivityDismissingKeyguard(capture(intentCaptor), eq(0)) + assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_COMMUNAL_SETTING) + } + + @Test fun filterWidgets_whenUserProfileRemoved() = testScope.runTest { // Keyguard showing, and tutorial completed. @@ -832,6 +859,63 @@ class CommunalInteractorTest : SysuiTestCase() { } @Test + fun widgetContent_inQuietMode() = + testScope.runTest { + // Keyguard showing, and tutorial completed. + keyguardRepository.setKeyguardShowing(true) + keyguardRepository.setKeyguardOccluded(false) + tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) + + // Work profile is set up. + val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK) + userRepository.setUserInfos(userInfos) + userTracker.set( + userInfos = userInfos, + selectedUserIndex = 0, + ) + runCurrent() + + // Keyguard widgets are allowed. + kosmos.fakeSettings.putIntForUser( + CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING, + AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD, + mainUser.id + ) + runCurrent() + + // When work profile is paused. + whenever(userManager.isQuietModeEnabled(eq(UserHandle.of(USER_INFO_WORK.id)))) + .thenReturn(true) + whenever(userManager.isManagedProfile(eq(USER_INFO_WORK.id))).thenReturn(true) + + val widgetContent by collectLastValue(underTest.widgetContent) + val widget1 = createWidgetForUser(1, USER_INFO_WORK.id) + val widget2 = createWidgetForUser(2, MAIN_USER_INFO.id) + val widget3 = createWidgetForUser(3, MAIN_USER_INFO.id) + val widgets = listOf(widget1, widget2, widget3) + widgetRepository.setCommunalWidgets(widgets) + + // The work profile widget is in quiet mode, while other widgets are not. + assertThat(widgetContent).hasSize(3) + widgetContent!!.forEach { model -> + assertThat(model) + .isInstanceOf(CommunalContentModel.WidgetContent.Widget::class.java) + } + assertThat( + (widgetContent!![0] as CommunalContentModel.WidgetContent.Widget).inQuietMode + ) + .isTrue() + assertThat( + (widgetContent!![1] as CommunalContentModel.WidgetContent.Widget).inQuietMode + ) + .isFalse() + assertThat( + (widgetContent!![2] as CommunalContentModel.WidgetContent.Widget).inQuietMode + ) + .isFalse() + } + + @Test fun widgetContent_containsDisabledWidgets_whenCategoryNotAllowed() = testScope.runTest { // Communal available, and tutorial completed. @@ -932,7 +1016,10 @@ class CommunalInteractorTest : SysuiTestCase() { private fun createWidgetForUser(appWidgetId: Int, userId: Int): CommunalWidgetContentModel = mock<CommunalWidgetContentModel> { whenever(this.appWidgetId).thenReturn(appWidgetId) - val providerInfo = mock<AppWidgetProviderInfo>() + val providerInfo = + mock<AppWidgetProviderInfo>().apply { + widgetCategory = AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD + } whenever(providerInfo.profile).thenReturn(UserHandle(userId)) whenever(this.providerInfo).thenReturn(providerInfo) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt index c670506d9f04..86fdaa5872e8 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt @@ -8,7 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.complication.ComplicationHostViewController -import com.android.systemui.dreams.ui.viewmodel.DreamOverlayViewModel +import com.android.systemui.dreams.ui.viewmodel.DreamViewModel import com.android.systemui.log.core.FakeLogBuffer import com.android.systemui.statusbar.BlurUtils import com.android.systemui.util.mockito.argumentCaptor @@ -45,7 +45,7 @@ class DreamOverlayAnimationsControllerTest : SysuiTestCase() { @Mock private lateinit var hostViewController: ComplicationHostViewController @Mock private lateinit var statusBarViewController: DreamOverlayStatusBarViewController @Mock private lateinit var stateController: DreamOverlayStateController - @Mock private lateinit var transitionViewModel: DreamOverlayViewModel + @Mock private lateinit var transitionViewModel: DreamViewModel private val logBuffer = FakeLogBuffer.Factory.create() private lateinit var controller: DreamOverlayAnimationsController diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt index 9da34da451c4..e34edb4c442e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt @@ -26,14 +26,9 @@ import com.android.systemui.biometrics.shared.model.SensorStrength import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository -import com.android.systemui.keyguard.shared.model.KeyguardState.AOD -import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING -import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState -import com.android.systemui.keyguard.shared.model.TransitionState.CANCELED -import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.shared.model.TransitionStep @@ -219,37 +214,6 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() { values.forEach { assertThat(it).isIn(Range.closed(-100f, 0f)) } } - @Test - fun transitionEnded() = - testScope.runTest { - val values by collectValues(underTest.transitionEnded) - - keyguardTransitionRepository.sendTransitionSteps( - listOf( - TransitionStep(DOZING, DREAMING, 0.0f, STARTED), - TransitionStep(DOZING, DREAMING, 1.0f, FINISHED), - TransitionStep(DREAMING, LOCKSCREEN, 0.0f, STARTED), - TransitionStep(DREAMING, LOCKSCREEN, 0.1f, RUNNING), - TransitionStep(DREAMING, LOCKSCREEN, 1.0f, FINISHED), - TransitionStep(LOCKSCREEN, DREAMING, 0.0f, STARTED), - TransitionStep(LOCKSCREEN, DREAMING, 0.5f, RUNNING), - TransitionStep(LOCKSCREEN, DREAMING, 1.0f, FINISHED), - TransitionStep(DREAMING, GONE, 0.0f, STARTED), - TransitionStep(DREAMING, GONE, 0.5f, RUNNING), - TransitionStep(DREAMING, GONE, 1.0f, CANCELED), - TransitionStep(DREAMING, AOD, 0.0f, STARTED), - TransitionStep(DREAMING, AOD, 1.0f, FINISHED), - ), - testScope, - ) - - assertThat(values.size).isEqualTo(3) - values.forEach { - assertThat(it.transitionState == FINISHED || it.transitionState == CANCELED) - .isTrue() - } - } - private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep { return TransitionStep( from = DREAMING, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt index 9ff76be30f79..19950a5fb89d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt @@ -31,8 +31,11 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.kosmos.testScope +import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.domain.interactor.shadeInteractor +import com.android.systemui.shade.domain.startable.shadeStartable import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock @@ -92,6 +95,24 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { assertThat(leftDestinationSceneKey).isEqualTo(Scenes.Communal) } + @Test + fun downFromTopEdgeDestinationSceneKey_whenNotSplitShade_quickSettings() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, false) + kosmos.shadeStartable.start() + val sceneKey by collectLastValue(underTest.downFromTopEdgeDestinationSceneKey) + assertThat(sceneKey).isEqualTo(Scenes.QuickSettings) + } + + @Test + fun downFromTopEdgeDestinationSceneKey_whenSplitShade_null() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, true) + kosmos.shadeStartable.start() + val sceneKey by collectLastValue(underTest.downFromTopEdgeDestinationSceneKey) + assertThat(sceneKey).isNull() + } + private fun createLockscreenSceneViewModel(): LockscreenSceneViewModel { return LockscreenSceneViewModel( applicationScope = testScope.backgroundScope, @@ -102,6 +123,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { interactor = mock(), ), notifications = kosmos.notificationsPlaceholderViewModel, + shadeInteractor = kosmos.shadeInteractor, ) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt index 63f00c1356e8..61089049bf89 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt @@ -30,6 +30,7 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.qs.FooterActionsController import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter +import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.privacyChipInteractor import com.android.systemui.shade.domain.interactor.shadeHeaderClockInteractor @@ -108,14 +109,15 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { shadeHeaderViewModel = shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, notifications = kosmos.notificationsPlaceholderViewModel, - footerActionsViewModelFactory, - footerActionsController, + footerActionsViewModelFactory = footerActionsViewModelFactory, + footerActionsController = footerActionsController, ) } @Test fun destinationsNotCustomizing() = testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, false) val destinations by collectLastValue(underTest.destinationScenes) qsFlexiglassAdapter.setCustomizing(false) @@ -131,6 +133,38 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { @Test fun destinationsCustomizing() = testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, false) + val destinations by collectLastValue(underTest.destinationScenes) + qsFlexiglassAdapter.setCustomizing(true) + + assertThat(destinations) + .isEqualTo( + mapOf( + Back to UserActionResult(Scenes.QuickSettings), + ) + ) + } + + @Test + fun destinations_whenNotCustomizing_inSplitShade() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, true) + val destinations by collectLastValue(underTest.destinationScenes) + qsFlexiglassAdapter.setCustomizing(false) + + assertThat(destinations) + .isEqualTo( + mapOf( + Back to UserActionResult(Scenes.Shade), + Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade), + ) + ) + } + + @Test + fun destinations_whenCustomizing_inSplitShade() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, true) val destinations by collectLastValue(underTest.destinationScenes) qsFlexiglassAdapter.setCustomizing(true) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index a2c4f4e63c19..42c33544416d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -20,10 +20,13 @@ package com.android.systemui.scene import android.telecom.TelecomManager import android.telephony.TelephonyManager +import android.testing.TestableLooper.RunWithLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.SwipeDirection import com.android.internal.R import com.android.internal.util.EmergencyAffordanceManager import com.android.internal.util.emergencyAffordanceManager @@ -59,6 +62,8 @@ import com.android.systemui.model.sceneContainerPlugin import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.qs.footerActionsController +import com.android.systemui.qs.footerActionsViewModelFactory import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.SceneContainerStartable @@ -69,6 +74,7 @@ import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.shade.domain.interactor.privacyChipInteractor import com.android.systemui.shade.domain.interactor.shadeHeaderClockInteractor +import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor @@ -127,6 +133,7 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) +@RunWithLooper class SceneFrameworkIntegrationTest : SysuiTestCase() { private val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true } @@ -167,6 +174,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { interactor = mock(), ), notifications = kosmos.notificationsPlaceholderViewModel, + shadeInteractor = kosmos.shadeInteractor, ) } @@ -250,6 +258,9 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { qsSceneAdapter = qsFlexiglassAdapter, notifications = kosmos.notificationsPlaceholderViewModel, mediaDataManager = mediaDataManager, + shadeInteractor = kosmos.shadeInteractor, + footerActionsController = kosmos.footerActionsController, + footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory, ) kosmos.fakeDeviceEntryRepository.setUnlocked(false) @@ -337,7 +348,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { @Test fun swipeUpOnShadeScene_withAuthMethodSwipe_lockscreenNotDismissed_goesToLockscreen() = testScope.runTest { - val upDestinationSceneKey by collectLastValue(shadeSceneViewModel.upDestinationSceneKey) + val destinationScenes by collectLastValue(shadeSceneViewModel.destinationScenes) setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true) assertCurrentScene(Scenes.Lockscreen) @@ -345,6 +356,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { emulateUserDrivenTransition(to = Scenes.Shade) assertCurrentScene(Scenes.Shade) + val upDestinationSceneKey = destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene assertThat(upDestinationSceneKey).isEqualTo(Scenes.Lockscreen) emulateUserDrivenTransition( to = upDestinationSceneKey, @@ -354,7 +366,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { @Test fun swipeUpOnShadeScene_withAuthMethodSwipe_lockscreenDismissed_goesToGone() = testScope.runTest { - val upDestinationSceneKey by collectLastValue(shadeSceneViewModel.upDestinationSceneKey) + val destinationScenes by collectLastValue(shadeSceneViewModel.destinationScenes) setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true) assertThat(deviceEntryInteractor.canSwipeToEnter.value).isTrue() assertCurrentScene(Scenes.Lockscreen) @@ -367,6 +379,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { emulateUserDrivenTransition(to = Scenes.Shade) assertCurrentScene(Scenes.Shade) + val upDestinationSceneKey = destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene assertThat(upDestinationSceneKey).isEqualTo(Scenes.Gone) emulateUserDrivenTransition( to = upDestinationSceneKey, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt index b66213330496..d309c6bcfd58 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt @@ -36,12 +36,14 @@ import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assume import org.junit.Before +import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) +@Ignore("b/328827631") class ShadeBackActionInteractorImplTest : SysuiTestCase() { val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true } val testScope = kosmos.testScope diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt index 4cd2c301d6ee..8c9036a4c68e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt @@ -29,9 +29,12 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.data.repository.shadeRepository +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.userRepository import com.google.common.truth.Truth +import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf @@ -45,19 +48,20 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { - val kosmos = testKosmos() - val testComponent = kosmos.testScope - val configurationRepository = kosmos.fakeConfigurationRepository - val keyguardRepository = kosmos.fakeKeyguardRepository - val keyguardTransitionRepository = kosmos.keyguardTransitionRepository - val sceneInteractor = kosmos.sceneInteractor - val userRepository = kosmos.userRepository + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private val configurationRepository = kosmos.fakeConfigurationRepository + private val keyguardRepository = kosmos.fakeKeyguardRepository + private val keyguardTransitionRepository = kosmos.keyguardTransitionRepository + private val sceneInteractor = kosmos.sceneInteractor + private val userRepository = kosmos.userRepository + private val shadeRepository = kosmos.shadeRepository - val underTest = kosmos.shadeInteractorSceneContainerImpl + private val underTest = kosmos.shadeInteractorSceneContainerImpl @Test fun qsExpansionWhenInSplitShadeAndQsExpanded() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.qsExpansion) // WHEN split shade is enabled and QS is expanded @@ -84,7 +88,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun qsExpansionWhenNotInSplitShadeAndQsExpanded() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.qsExpansion) // WHEN split shade is not enabled and QS is expanded @@ -112,7 +116,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun qsFullscreen_falseWhenTransitioning() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.isQsFullscreen) // WHEN scene transition active @@ -136,7 +140,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun qsFullscreen_falseWhenIdleNotQS() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.isQsFullscreen) // WHEN Idle but not on QuickSettings scene @@ -154,7 +158,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun qsFullscreen_trueWhenIdleQS() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.isQsFullscreen) // WHEN Idle on QuickSettings scene @@ -172,7 +176,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun lockscreenShadeExpansion_idle_onScene() = - testComponent.runTest { + testScope.runTest { // GIVEN an expansion flow based on transitions to and from a scene val key = Scenes.Shade val expansion = underTest.sceneBasedExpansion(sceneInteractor, key) @@ -189,7 +193,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun lockscreenShadeExpansion_idle_onDifferentScene() = - testComponent.runTest { + testScope.runTest { // GIVEN an expansion flow based on transitions to and from a scene val expansion = underTest.sceneBasedExpansion(sceneInteractor, Scenes.Shade) val expansionAmount by collectLastValue(expansion) @@ -207,7 +211,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun lockscreenShadeExpansion_transitioning_toScene() = - testComponent.runTest { + testScope.runTest { // GIVEN an expansion flow based on transitions to and from a scene val key = Scenes.QuickSettings val expansion = underTest.sceneBasedExpansion(sceneInteractor, key) @@ -245,7 +249,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun lockscreenShadeExpansion_transitioning_fromScene() = - testComponent.runTest { + testScope.runTest { // GIVEN an expansion flow based on transitions to and from a scene val key = Scenes.QuickSettings val expansion = underTest.sceneBasedExpansion(sceneInteractor, key) @@ -282,7 +286,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { } fun isQsBypassingShade_goneToQs() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.isQsBypassingShade) // WHEN transitioning from QS directly to Gone @@ -305,7 +309,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { } fun isQsBypassingShade_shadeToQs() = - testComponent.runTest { + testScope.runTest { val actual by collectLastValue(underTest.isQsBypassingShade) // WHEN transitioning from QS to Shade @@ -329,7 +333,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun lockscreenShadeExpansion_transitioning_toAndFromDifferentScenes() = - testComponent.runTest { + testScope.runTest { // GIVEN an expansion flow based on transitions to and from a scene val expansion = underTest.sceneBasedExpansion(sceneInteractor, Scenes.QuickSettings) val expansionAmount by collectLastValue(expansion) @@ -366,7 +370,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun userInteracting_idle() = - testComponent.runTest { + testScope.runTest { // GIVEN an interacting flow based on transitions to and from a scene val key = Scenes.Shade val interactingFlow = underTest.sceneBasedInteracting(sceneInteractor, key) @@ -383,7 +387,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun userInteracting_transitioning_toScene_programmatic() = - testComponent.runTest { + testScope.runTest { // GIVEN an interacting flow based on transitions to and from a scene val key = Scenes.QuickSettings val interactingFlow = underTest.sceneBasedInteracting(sceneInteractor, key) @@ -421,7 +425,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun userInteracting_transitioning_toScene_userInputDriven() = - testComponent.runTest { + testScope.runTest { // GIVEN an interacting flow based on transitions to and from a scene val key = Scenes.QuickSettings val interactingFlow = underTest.sceneBasedInteracting(sceneInteractor, key) @@ -459,7 +463,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun userInteracting_transitioning_fromScene_programmatic() = - testComponent.runTest { + testScope.runTest { // GIVEN an interacting flow based on transitions to and from a scene val key = Scenes.QuickSettings val interactingFlow = underTest.sceneBasedInteracting(sceneInteractor, key) @@ -497,7 +501,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun userInteracting_transitioning_fromScene_userInputDriven() = - testComponent.runTest { + testScope.runTest { // GIVEN an interacting flow based on transitions to and from a scene val key = Scenes.QuickSettings val interactingFlow = underTest.sceneBasedInteracting(sceneInteractor, key) @@ -535,7 +539,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { @Test fun userInteracting_transitioning_toAndFromDifferentScenes() = - testComponent.runTest { + testScope.runTest { // GIVEN an interacting flow based on transitions to and from a scene val interactingFlow = underTest.sceneBasedInteracting(sceneInteractor, Scenes.Shade) val interacting by collectLastValue(interactingFlow) @@ -557,4 +561,19 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() { // THEN interacting is false Truth.assertThat(interacting).isFalse() } + + @Test + fun shadeMode() = + testScope.runTest { + val shadeMode by collectLastValue(underTest.shadeMode) + + shadeRepository.setShadeMode(ShadeMode.Split) + assertThat(shadeMode).isEqualTo(ShadeMode.Split) + + shadeRepository.setShadeMode(ShadeMode.Single) + assertThat(shadeMode).isEqualTo(ShadeMode.Single) + + shadeRepository.setShadeMode(ShadeMode.Split) + assertThat(shadeMode).isEqualTo(ShadeMode.Split) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt new file mode 100644 index 000000000000..31dacdd61151 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.shade.domain.startable + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.testScope +import com.android.systemui.res.R +import com.android.systemui.shade.domain.interactor.shadeInteractor +import com.android.systemui.shade.shared.model.ShadeMode +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class ShadeStartableTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private val shadeInteractor = kosmos.shadeInteractor + private val fakeConfigurationRepository = kosmos.fakeConfigurationRepository + + private val underTest = kosmos.shadeStartable + + @Test + fun hydrateShadeMode() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, false) + val shadeMode by collectLastValue(shadeInteractor.shadeMode) + + underTest.start() + assertThat(shadeMode).isEqualTo(ShadeMode.Single) + + overrideResource(R.bool.config_use_split_notification_shade, true) + fakeConfigurationRepository.onAnyConfigurationChange() + assertThat(shadeMode).isEqualTo(ShadeMode.Split) + + overrideResource(R.bool.config_use_split_notification_shade, false) + fakeConfigurationRepository.onAnyConfigurationChange() + assertThat(shadeMode).isEqualTo(ShadeMode.Single) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt index 853b00d345bc..1c5496142fec 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt @@ -16,8 +16,11 @@ package com.android.systemui.shade.ui.viewmodel +import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.SwipeDirection import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.shared.model.AuthenticationMethodModel @@ -28,11 +31,18 @@ import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.kosmos.testScope import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.qs.footerActionsController +import com.android.systemui.qs.footerActionsViewModelFactory import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter +import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.privacyChipInteractor import com.android.systemui.shade.domain.interactor.shadeHeaderClockInteractor +import com.android.systemui.shade.domain.interactor.shadeInteractor +import com.android.systemui.shade.domain.startable.shadeStartable +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor @@ -57,12 +67,14 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) +@TestableLooper.RunWithLooper class ShadeSceneViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor } + private val shadeRepository by lazy { kosmos.shadeRepository } private val mobileIconsInteractor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock()) private val flags = FakeFeatureFlagsClassic().also { it.set(Flags.NEW_NETWORK_SLICE_UI, false) } @@ -113,50 +125,56 @@ class ShadeSceneViewModelTest : SysuiTestCase() { qsSceneAdapter = qsFlexiglassAdapter, notifications = kosmos.notificationsPlaceholderViewModel, mediaDataManager = mediaDataManager, + shadeInteractor = kosmos.shadeInteractor, + footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory, + footerActionsController = kosmos.footerActionsController, ) } @Test fun upTransitionSceneKey_deviceLocked_lockScreen() = testScope.runTest { - val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey) + val destinationScenes by collectLastValue(underTest.destinationScenes) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) kosmos.fakeDeviceEntryRepository.setUnlocked(false) - assertThat(upTransitionSceneKey).isEqualTo(Scenes.Lockscreen) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene) + .isEqualTo(Scenes.Lockscreen) } @Test fun upTransitionSceneKey_deviceUnlocked_gone() = testScope.runTest { - val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey) + val destinationScenes by collectLastValue(underTest.destinationScenes) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) kosmos.fakeDeviceEntryRepository.setUnlocked(true) - assertThat(upTransitionSceneKey).isEqualTo(Scenes.Gone) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene) + .isEqualTo(Scenes.Gone) } @Test fun upTransitionSceneKey_authMethodSwipe_lockscreenNotDismissed_goesToLockscreen() = testScope.runTest { - val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey) + val destinationScenes by collectLastValue(underTest.destinationScenes) kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.None ) sceneInteractor.changeScene(Scenes.Lockscreen, "reason") - assertThat(upTransitionSceneKey).isEqualTo(Scenes.Lockscreen) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene) + .isEqualTo(Scenes.Lockscreen) } @Test fun upTransitionSceneKey_authMethodSwipe_lockscreenDismissed_goesToGone() = testScope.runTest { - val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey) + val destinationScenes by collectLastValue(underTest.destinationScenes) kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true) kosmos.fakeDeviceEntryRepository.setUnlocked(true) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( @@ -165,7 +183,8 @@ class ShadeSceneViewModelTest : SysuiTestCase() { runCurrent() sceneInteractor.changeScene(Scenes.Gone, "reason") - assertThat(upTransitionSceneKey).isEqualTo(Scenes.Gone) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene) + .isEqualTo(Scenes.Gone) } @Test @@ -239,4 +258,38 @@ class ShadeSceneViewModelTest : SysuiTestCase() { assertThat(underTest.isMediaVisible()).isFalse() } + + @Test + fun downTransitionSceneKey_inSplitShade_null() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, true) + kosmos.shadeStartable.start() + val destinationScenes by collectLastValue(underTest.destinationScenes) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.toScene).isNull() + } + + @Test + fun downTransitionSceneKey_notSplitShade_quickSettings() = + testScope.runTest { + overrideResource(R.bool.config_use_split_notification_shade, false) + kosmos.shadeStartable.start() + val destinationScenes by collectLastValue(underTest.destinationScenes) + assertThat(destinationScenes?.get(Swipe(SwipeDirection.Down))?.toScene) + .isEqualTo(Scenes.QuickSettings) + } + + @Test + fun shadeMode() = + testScope.runTest { + val shadeMode by collectLastValue(underTest.shadeMode) + + shadeRepository.setShadeMode(ShadeMode.Split) + assertThat(shadeMode).isEqualTo(ShadeMode.Split) + + shadeRepository.setShadeMode(ShadeMode.Single) + assertThat(shadeMode).isEqualTo(ShadeMode.Single) + + shadeRepository.setShadeMode(ShadeMode.Split) + assertThat(shadeMode).isEqualTo(ShadeMode.Split) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index deb19769372c..e683f34c4ea1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -21,13 +21,10 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.NotificationContainerBounds import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository -import com.android.systemui.communal.domain.interactor.communalInteractor -import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic @@ -80,13 +77,13 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { init { kosmos.aodBurnInViewModel = aodBurnInViewModel } + val testScope = kosmos.testScope val configurationRepository = kosmos.fakeConfigurationRepository val keyguardRepository = kosmos.fakeKeyguardRepository val keyguardInteractor = kosmos.keyguardInteractor val keyguardRootViewModel = kosmos.keyguardRootViewModel val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository - val communalInteractor = kosmos.communalInteractor val shadeRepository = kosmos.shadeRepository val sharedNotificationContainerInteractor = kosmos.sharedNotificationContainerInteractor val largeScreenHeaderHelper = kosmos.mockLargeScreenHeaderHelper @@ -239,7 +236,7 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { } @Test - fun glanceableHubAlpha() = + fun glanceableHubAlpha_lockscreenToHub() = testScope.runTest { val alpha by collectLastValue(underTest.glanceableHubAlpha) @@ -278,12 +275,6 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { value = 1f, ) ) - val idleTransitionState = - MutableStateFlow<ObservableTransitionState>( - ObservableTransitionState.Idle(CommunalScenes.Communal) - ) - communalInteractor.setTransitionState(idleTransitionState) - runCurrent() assertThat(alpha).isEqualTo(0f) // While state is GLANCEABLE_HUB, verify alpha is restored to full if glanceable hub is @@ -293,6 +284,50 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { } @Test + fun glanceableHubAlpha_dreamToHub() = + testScope.runTest { + val alpha by collectLastValue(underTest.glanceableHubAlpha) + + // Start on dream + showDream() + assertThat(alpha).isEqualTo(1f) + + // Start transitioning to glanceable hub + val progress = 0.6f + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.DREAMING, + to = KeyguardState.GLANCEABLE_HUB, + value = 0f, + ) + ) + runCurrent() + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = KeyguardState.DREAMING, + to = KeyguardState.GLANCEABLE_HUB, + value = progress, + ) + ) + runCurrent() + // Keep notifications hidden during the transition from dream to hub + assertThat(alpha).isEqualTo(0) + + // Finish transition to glanceable hub + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.DREAMING, + to = KeyguardState.GLANCEABLE_HUB, + value = 1f, + ) + ) + assertThat(alpha).isEqualTo(0f) + } + + @Test fun validateMarginTop() = testScope.runTest { overrideResource(R.bool.config_use_large_screen_shade_header, false) @@ -391,12 +426,11 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { assertThat(isOnGlanceableHubWithoutShade).isFalse() // Move to glanceable hub - val idleTransitionState = - MutableStateFlow<ObservableTransitionState>( - ObservableTransitionState.Idle(CommunalScenes.Communal) - ) - communalInteractor.setTransitionState(idleTransitionState) - runCurrent() + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GLANCEABLE_HUB, + testScope = this + ) assertThat(isOnGlanceableHubWithoutShade).isTrue() // While state is GLANCEABLE_HUB, validate variations of both shade and qs expansion @@ -726,6 +760,19 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { ) } + private suspend fun TestScope.showDream() { + shadeRepository.setLockscreenShadeExpansion(0f) + shadeRepository.setQsExpansion(0f) + runCurrent() + keyguardRepository.setDreaming(true) + runCurrent() + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.DREAMING, + testScope, + ) + } + private suspend fun TestScope.showLockscreenWithShadeExpanded() { shadeRepository.setLockscreenShadeExpansion(1f) shadeRepository.setQsExpansion(0f) diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 9197149c7f3f..2e2d2866e0eb 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Skakel aan"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Skakel aan"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nee, dankie"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standaard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstreem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Outodraai skerm"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Laat <xliff:g id="APPLICATION">%1$s</xliff:g> toe om by <xliff:g id="USB_DEVICE">%2$s</xliff:g> in te gaan?\nOpneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel vasvang."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ontkoppel"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveer"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Skakel dit môre outomaties weer aan"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Kenmerke soos Kitsdeel, Kry My Toestel en toestelligging gebruik Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Oudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kopstuk"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om op vibreer te stel."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om te demp."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Geraasbeheer"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om luiermodus te verander"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"demp"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ontdemp"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batterykrag oor"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koppel jou stilus aan ’n laaier"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stilus se battery is amper pap"</string> diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml index 1c9a79414ff1..14275745c838 100644 --- a/packages/SystemUI/res/values-af/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Af"</item> <item msgid="578444932039713369">"Aan"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Onbeskikbaar"</item> + <item msgid="9061144428113385092">"Af"</item> + <item msgid="2984256114867200368">"Aan"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Onbeskikbaar"</item> <item msgid="8707481475312432575">"Af"</item> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index a4aa842c004d..897820cd4636 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"አብራ"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"አብራ"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"አይ፣ አመሰግናለሁ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"መደበኛ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"እጅግ ከፍተኛ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ማያ በራስ ሰር አሽከርክር"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲደርስበት ይፈቀድለት?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲደርስ ይፈቀድለት?\nይህ መተግበሪያ የመቅዳት ፈቃድ አልተሰጠውም፣ ነገር ግን በዩኤስቢ መሣሪያ በኩል ኦዲዮን መቅዳት ይችላል።"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"ነገ እንደገና በራስ-ሰር አስጀምር"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"እንደ ፈጣን ማጋራት፣ የእኔን መሣሪያ አግኝ እና የመሣሪያ አካባቢ ያሉ ባህሪያት ብሉቱዝን ይጠቀማሉ"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ባትሪ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ኦዲዮ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ማዳመጫ"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ።"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ።"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"የጫጫታ መቆጣጠሪያ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"የደዋይ ሁነታን ለመቀየር መታ ያድርጉ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ድምጸ-ከል አድርግ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ድምጸ-ከልን አንሳ"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ባትሪ ይቀራል"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ብሮስፌዎን ከኃይል መሙያ ጋር ያገናኙ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"የብሮስፌ ባትሪ ዝቅተኛ ነው"</string> diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml index 3fb24b983162..ab0b68b3e4e5 100644 --- a/packages/SystemUI/res/values-am/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ጠፍቷል"</item> <item msgid="578444932039713369">"በርቷል"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"አይገኝም"</item> + <item msgid="9061144428113385092">"አጥፋ"</item> + <item msgid="2984256114867200368">"አብራ"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"አይገኝም"</item> <item msgid="8707481475312432575">"ጠፍቷል"</item> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 07a5bfc2ca8b..89b4ccf8e382 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"تفعيل"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"تفعيل"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"لا، شكرًا"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"عادي"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"التوفير العالي"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"التدوير التلقائي للشاشة"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟\nلم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"تفعيل البلوتوث تلقائيًا مرة أخرى غدًا"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"يُستخدَم البلوتوث في ميزات مثل Quick Share و\"العثور على جهازي\" والموقع الجغرافي للجهاز"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"سماعة الرأس"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. انقر للتعيين على الاهتزاز."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. انقر لكتم الصوت."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"التحكُّم في مستوى الضجيج"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"إعادة الصوت"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"النسبة المئوية المتبقية من شحن البطارية: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"عليك توصيل قلم الشاشة بشاحن."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"بطارية قلم الشاشة منخفضة"</string> diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml index cf050ac26473..364737db4d1c 100644 --- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"الميزة غير مفعّلة"</item> <item msgid="578444932039713369">"الميزة مفعّلة"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"غير متوفّر"</item> + <item msgid="9061144428113385092">"غير مفعَّل"</item> + <item msgid="2984256114867200368">"مفعَّل"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"الميزة غير متاحة"</item> <item msgid="8707481475312432575">"الميزة غير مفعّلة"</item> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 13bb7eafadb0..9a2d744fcbb3 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"অন কৰক"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"অন কৰক"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"নালাগে, ধন্যবাদ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"মানক"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"চৰম"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> এক্সেছ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক অনুমতি দিবনে?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক <xliff:g id="USB_DEVICE">%2$s</xliff:g> এক্সেছ কৰিবলৈ অনুমতি দিবনে?\nএই এপ্টোক ৰেকর্ড কৰাৰ অনুমতি দিয়া হোৱা নাই কিন্তু ই এই ইউএছবি ডিভাইচটোৰ জৰিয়তে অডিঅ\' ৰেকর্ড কৰিব পাৰে।"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"কাইলৈ পুনৰ স্বয়ংক্ৰিয়ভাৱে অন কৰক"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, Find My Device আৰু ডিভাইচৰ অৱস্থানৰ দৰে সুবিধাই ব্লুটুথ ব্যৱহাৰ কৰে"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিঅ’"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডছেট"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। কম্পন অৱস্থাত ছেট কৰিবলৈ টিপক।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। মিউট কৰিবলৈ টিপক।"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"কোলাহল নিয়ন্ত্ৰণ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ৰিংগাৰ ম’ড সলনি কৰিবলৈ টিপক"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট কৰক"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট কৰক"</string> diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml index f4268ed17ff5..767b34d3712b 100644 --- a/packages/SystemUI/res/values-as/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"অফ আছে"</item> <item msgid="578444932039713369">"অন কৰা আছে"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"উপলব্ধ নহয়"</item> + <item msgid="9061144428113385092">"অফ আছে"</item> + <item msgid="2984256114867200368">"অন আছে"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"উপলব্ধ নহয়"</item> <item msgid="8707481475312432575">"অফ আছে"</item> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 19cb29b075c3..ebd4073155a2 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktivləşdirin"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktiv edin"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Xeyr, təşəkkür"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standart"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstremal"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranın avtomatik dönməsi"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş verilsin?\nTətbiqə qeydə almaq icazəsi verilməsə də, bu USB vasitəsilə səsi qeydə ala bilər."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"əlaqəni kəsin"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivləşdirin"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Sabah avtomatik aktiv edin"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Cəld Paylaşım, Cihazın Tapılması və cihaz məkanı kimi funksiyalar Bluetooth istifadə edir"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Qulaqlıq"</string> @@ -581,7 +586,15 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Səssiz etmək üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Vibrasiyanı ayarlamaq üçün klikləyin."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Səssiz etmək üçün klikləyin."</string> - <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Səs-küy idarəsi"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Səs-küy idarəetməsi"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Zəng rejimini dəyişmək üçün toxunun"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"susdurun"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"səssiz rejimdən çıxarın"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> enerji qalıb"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Qələmi adapterə qoşun"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Qələm enerjisi azdır"</string> diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml index eeb81ccf42e1..3457a717c69b 100644 --- a/packages/SystemUI/res/values-az/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Deaktiv"</item> <item msgid="578444932039713369">"Aktiv"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Əlçatan deyil"</item> + <item msgid="9061144428113385092">"Deaktiv"</item> + <item msgid="2984256114867200368">"Aktiv"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Əlçatan deyil"</item> <item msgid="8707481475312432575">"Deaktiv"</item> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 660400111503..17599b2a92a1 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standardno"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstremno"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Dozvoljavate da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOva aplikacija nema dozvolu za snimanje, ali bi mogla da snima zvuk pomoću ovog USB uređaja."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinite vezu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivirajte"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatski ponovo uključi sutra"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkcije kao što su Quick Share, Pronađi moj uređaj i lokacija uređaja koriste Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste podesili na vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola šuma"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je još<xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisaljku sa punjačem"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Nizak nivo baterije pisaljke"</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 217d99975d3f..75fb3259ba34 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 @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Isključeno"</item> <item msgid="578444932039713369">"Uključeno"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nedostupno"</item> + <item msgid="9061144428113385092">"Isključeno"</item> + <item msgid="2984256114867200368">"Uključeno"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nedostupno"</item> <item msgid="8707481475312432575">"Isključeno"</item> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index de4fc999a3ae..93921fcde82f 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Уключыць"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Уключыць"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, дзякуй"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартны рэжым"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Максімальная"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аўтаматычны паварот экрана"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Даць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nУ гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту прыладу USB."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Аўтаматычнае ўключэнне заўтра"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Такія функцыі, як вызначэнне месцазнаходжання прылады, Хуткае абагульванне і Знайсці прыладу, выкарыстоўваюць Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Гук"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Дакраніцеся, каб уключыць вібрацыю."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дакраніцеся, каб адключыць гук"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Кантроль шуму"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Націсніце, каб змяніць рэжым званка"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"выключыць гук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"уключыць гук"</string> diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml index 717e4c9a9c39..74fc7c63cc38 100644 --- a/packages/SystemUI/res/values-be/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Выключана"</item> <item msgid="578444932039713369">"Уключана"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Недаступна"</item> + <item msgid="9061144428113385092">"Выключана"</item> + <item msgid="2984256114867200368">"Уключана"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Недаступна"</item> <item msgid="8707481475312432575">"Выключана"</item> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 475076fca559..f3ae4411f533 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Включване"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Включване"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, благодаря"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартен"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Екстремен режим"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Авт. завъртане на екрана"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Да се разреши ли на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Наистина ли искате да разрешите на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nНа приложението не е предоставено разрешение за записване, но е възможно да запише звук чрез това USB устройство."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Автоматично включване отново утре"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Bluetooth се използва от различни функции, като например „Бързо споделяне“, „Намиране на устройството ми“ и местоположението на устройството"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Докоснете, за да зададете вибриране."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Докоснете, за да заглушите звука."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Управление на шума"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Докоснете, за да промените режима на звънене"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"спиране"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"пускане"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Оставаща батерия: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Свържете писалката към зарядно устройство"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Батерията на писалката е изтощена"</string> diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml index 58fa82bbc77a..ddd0c3fa49dd 100644 --- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Изкл."</item> <item msgid="578444932039713369">"Вкл."</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Не е налице"</item> + <item msgid="9061144428113385092">"Изкл."</item> + <item msgid="2984256114867200368">"Вкл."</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Не е налице"</item> <item msgid="8707481475312432575">"Изкл."</item> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index c1808a9e0deb..0e95c2c93b24 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"চালু করুন"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"চালু করুন"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"না থাক"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"সাধারণ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"এক্সট্রিম"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"অটো-রোটেট স্ক্রিন"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> কে <xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করতে দেবেন?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করতে <xliff:g id="APPLICATION">%1$s</xliff:g>-কে কি অনুমতি দেবেন?\nএই অ্যাপকে রেকর্ড করার অনুমতি দেওয়া হয়নি কিন্তু USB ডিভাইসের মাধ্যমে সেটি অডিও রেকর্ড করতে পারে।"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"আগামীকাল অটোমেটিক আবার চালু হবে"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"দ্রুত শেয়ার, Find My Device ও ডিভাইসের লোকেশন ব্লুটুথ ব্যবহার করে"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিও"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডসেট"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ভাইব্রেট করতে ট্যাপ করুন।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। মিউট করতে ট্যাপ করুন।"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"আশপাশের আওয়াজ কন্ট্রোল করা"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"রিঙ্গার মোড পরিবর্তন করতে ট্যাপ করুন"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট করুন"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট করুন"</string> diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml index 5c3c66c29461..ad3256068f5f 100644 --- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"বন্ধ আছে"</item> <item msgid="578444932039713369">"চালু আছে"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"উপলভ্য নেই"</item> + <item msgid="9061144428113385092">"বন্ধ আছে"</item> + <item msgid="2984256114867200368">"চালু আছে"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"উপলভ্য নেই"</item> <item msgid="8707481475312432575">"বন্ধ আছে"</item> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index a08edd215d66..7abe5ffc5741 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standardno"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstremno"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatsko rotiranje ekrana"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nOvoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekid veze"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatski uključi ponovo sutra"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkcije kao što su Quick Share, Pronađi moj uređaj i lokacija uređaja koriste Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da postavite vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da isključite zvuk."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Upravljanje bukom"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da promijenite način rada zvuka zvona"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Priključite pisaljku na punjač"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Baterija pisaljke je slaba"</string> diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml index 217d99975d3f..75fb3259ba34 100644 --- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Isključeno"</item> <item msgid="578444932039713369">"Uključeno"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nedostupno"</item> + <item msgid="9061144428113385092">"Isključeno"</item> + <item msgid="2984256114867200368">"Uključeno"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nedostupno"</item> <item msgid="8707481475312432575">"Isključeno"</item> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 57553539a1f3..29ef2f959d17 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activa"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activa"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, gràcies"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Estàndard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Gira la pantalla automàticament"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconnecta"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activa"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Torna\'l a activar automàticament demà"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funcions com ara Quick Share, Troba el meu dispositiu i la ubicació del dispositiu utilitzen el Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Àudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculars"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca per activar la vibració."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca per silenciar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de soroll"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Toca per canviar el mode de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"deixar de silenciar"</string> diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml index c1ac5a356f05..c926e9ec4691 100644 --- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desactivat"</item> <item msgid="578444932039713369">"Activat"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"No disponible"</item> + <item msgid="9061144428113385092">"Desactivat"</item> + <item msgid="2984256114867200368">"Activat"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"No disponible"</item> <item msgid="8707481475312432575">"Desactivat"</item> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 18391eb40908..0bbeb9c998e1 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Zapnout"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Zapnout"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, díky"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standardní"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrémní"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatické otočení obrazovky"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTato aplikace nemá oprávnění k nahrávání, ale může zaznamenávat zvuk prostřednictvím tohoto zařízení USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojit"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovat"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Zítra znovu automaticky zapnout"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkce jako Quick Share, Najdi moje zařízení a vyhledávání zařízení používají Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Sluchátka"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Klepnutím nastavíte vibrace."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Klepnutím vypnete zvuk."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Omezení hluku"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Klepnutím změníte režim vyzvánění"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnout zvuk"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Zbývá <xliff:g id="PERCENTAGE">%s</xliff:g> baterie"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Připojte dotykové pero k nabíječce"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Slabá baterie dotykového pera"</string> diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml index 0a4d4d0cfeef..534556910c01 100644 --- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Vypnuto"</item> <item msgid="578444932039713369">"Zapnuto"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Není k dispozici"</item> + <item msgid="9061144428113385092">"Vypnuto"</item> + <item msgid="2984256114867200368">"Zapnuto"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nedostupné"</item> <item msgid="8707481475312432575">"Vypnuto"</item> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index ad4ff9265e85..2ea1e12def5d 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktivér"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktivér"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nej tak"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstrem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Roter skærm automatisk"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDenne app har ikke fået tilladelse til at optage, men optager muligvis lyd via denne USB-enhed."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"afbryd forbindelse"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivér"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Aktivér automatisk igen i morgen"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funktioner som f.eks. Quick Share, Find min enhed og enhedslokation anvender Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tryk for at aktivere vibration."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tryk for at slå lyden fra."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Støjstyring"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri tilbage"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Slut din styluspen til en oplader"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Lavt batteriniveau på styluspen"</string> diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml index 2391753f8c0b..5a5314933aa2 100644 --- a/packages/SystemUI/res/values-da/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Fra"</item> <item msgid="578444932039713369">"Til"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ikke tilgængelig"</item> + <item msgid="9061144428113385092">"Fra"</item> + <item msgid="2984256114867200368">"Til"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Ikke tilgængelig"</item> <item msgid="8707481475312432575">"Fra"</item> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index a2c9f665efda..edd718fd69fc 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktivieren"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktivieren"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nein danke"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Bildschirm automatisch drehen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_DEVICE">%2$s</xliff:g> gewähren?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_DEVICE">%2$s</xliff:g> gewähren?\nDiese App hat noch nicht die Berechtigung zum Aufnehmen erhalten, könnte jedoch Audio über dieses USB-Gerät aufnehmen."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Verknüpfung aufheben"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivieren"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Morgen automatisch wieder aktivieren"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Für Funktionen wie Quick Share, „Mein Gerät finden“ und den Gerätestandort wird Bluetooth verwendet"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Zum Aktivieren der Vibration tippen."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Zum Stummschalten tippen."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Geräuschunterdrückung"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Zum Ändern des Klingeltonmodus tippen"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Stummschalten"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Aufheben der Stummschaltung"</string> diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml index 3aae04bbc931..e5f86557e171 100644 --- a/packages/SystemUI/res/values-de/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Aus"</item> <item msgid="578444932039713369">"An"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nicht verfügbar"</item> + <item msgid="9061144428113385092">"Aus"</item> + <item msgid="2984256114867200368">"An"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nicht verfügbar"</item> <item msgid="8707481475312432575">"Aus"</item> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 7ab38b7bd7cd..54303b5e3cc6 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ενεργοποίηση"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Ενεργοποίηση"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Όχι, ευχαριστώ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Βασική"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Μέγιστη"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Αυτόματη περιστροφή οθόνης"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Να επιτρέπεται η πρόσβαση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Να επιτρέπεται στο <xliff:g id="APPLICATION">%1$s</xliff:g> να έχει πρόσβαση στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;\nΔεν έχει εκχωρηθεί άδεια εγγραφής σε αυτή την εφαρμογή, αλλά μέσω αυτής της συσκευής USB θα μπορεί να εγγράφει ήχο."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Αυτόματη ενεργοποίηση ξανά αύριο"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Λειτουργίες όπως το Quick Share, η Εύρεση συσκευής και η τοποθεσία της συσκευής χρησιμοποιούν Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ήχος"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ακουστικά"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Πατήστε για να ενεργοποιήσετε τη δόνηση."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Πατήστε για σίγαση."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Έλεγχος θορύβου"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Πατήστε για να αλλάξετε τη λειτουργία ειδοποίησης ήχου"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"σίγαση"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"κατάργηση σίγασης"</string> diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml index 035f1171d3b4..a697711c120c 100644 --- a/packages/SystemUI/res/values-el/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Ανενεργό"</item> <item msgid="578444932039713369">"Ενεργό"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Μη διαθέσιμη"</item> + <item msgid="9061144428113385092">"Ανενεργή"</item> + <item msgid="2984256114867200368">"Ενεργή"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Μη διαθέσιμο"</item> <item msgid="8707481475312432575">"Ανενεργό"</item> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 4a65cc2fef59..0fcd2b08d4bb 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device and device location use Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise control"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</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 2576b6080638..d97c4c914f26 100644 --- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Off"</item> <item msgid="578444932039713369">"On"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Unavailable"</item> + <item msgid="9061144428113385092">"Off"</item> + <item msgid="2984256114867200368">"On"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Unavailable"</item> <item msgid="8707481475312432575">"Off"</item> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 63b2f4a7ba23..da1dcd848b3b 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device, and device location use Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,10 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise Control"</string> + <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Spatial Audio"</string> + <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Off"</string> + <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixed"</string> + <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head Tracking"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -1223,12 +1232,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 4a65cc2fef59..0fcd2b08d4bb 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device and device location use Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise control"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</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 2576b6080638..d97c4c914f26 100644 --- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Off"</item> <item msgid="578444932039713369">"On"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Unavailable"</item> + <item msgid="9061144428113385092">"Off"</item> + <item msgid="2984256114867200368">"On"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Unavailable"</item> <item msgid="8707481475312432575">"Off"</item> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 4a65cc2fef59..0fcd2b08d4bb 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, thanks"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device and device location use Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise control"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</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 2576b6080638..d97c4c914f26 100644 --- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Off"</item> <item msgid="578444932039713369">"On"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Unavailable"</item> + <item msgid="9061144428113385092">"Off"</item> + <item msgid="2984256114867200368">"On"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Unavailable"</item> <item msgid="8707481475312432575">"Off"</item> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index a0d22310fc91..516c3af2e324 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Turn on"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Turn on"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No thanks"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Auto-rotate screen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatically turn on again tomorrow"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Features like Quick Share, Find My Device, and device location use Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,10 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise Control"</string> + <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Spatial Audio"</string> + <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Off"</string> + <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fixed"</string> + <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head Tracking"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -1223,12 +1232,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index ede1a74dd44d..11e31e1c3f2b 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activar"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activar"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, gracias"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Estándar"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extremo"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Girar la pantalla automáticamente"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"¿Deseas permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"¿Quieres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nLa app no tiene permiso para grabar, pero podría capturar audio mediante este dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Volver a activar automáticamente mañana"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Las funciones como Quick Share, Encontrar mi dispositivo y la ubicación del dispositivo usan Bluetooth."</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Presiona para establecer el modo vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Presiona para silenciar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de ruido"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Presiona para cambiar el modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> @@ -796,8 +809,8 @@ <string name="right_keycode" msgid="2480715509844798438">"Clave de código derecho"</string> <string name="left_icon" msgid="5036278531966897006">"Ícono izquierdo"</string> <string name="right_icon" msgid="1103955040645237425">"Ícono derecho"</string> - <string name="drag_to_add_tiles" msgid="8933270127508303672">"Mantén presionado y arrastra para agregar tarjetas"</string> - <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Mantén presionado y arrastra para reorganizar las tarjetas"</string> + <string name="drag_to_add_tiles" msgid="8933270127508303672">"Mantén presionada la tarjeta y arrástrala para agregarla"</string> + <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Mantén presionada la tarjeta y arrástrala para reorganizarla"</string> <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra aquí para quitar"</string> <string name="drag_to_remove_disabled" msgid="933046987838658850">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tarjetas"</string> <string name="qs_edit" msgid="5583565172803472437">"Editar"</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 09abc543dbcf..6446bdff9ffc 100644 --- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desactivado"</item> <item msgid="578444932039713369">"Activado"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"No disponible"</item> + <item msgid="9061144428113385092">"Desactivado"</item> + <item msgid="2984256114867200368">"Activado"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"No disponible"</item> <item msgid="8707481475312432575">"Desactivado"</item> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index d487ec1799ff..ec03f8dd982c 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activar"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activar"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, gracias"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Estándar"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extremo"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Girar pantalla automáticamente"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"¿Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"¿Quieres que <xliff:g id="APPLICATION">%1$s</xliff:g> pueda acceder a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta aplicación no tiene permisos para grabar, pero podría capturar audio a través de este dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Volver a activar automáticamente mañana"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funciones como Quick Share, Encontrar mi dispositivo y la ubicación del dispositivo usan Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca para activar la vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca para silenciar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de ruido"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar el modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta tu lápiz óptico a un cargador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Batería del lápiz óptico baja"</string> diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml index 83b4627897da..4cc0c6749a01 100644 --- a/packages/SystemUI/res/values-es/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desactivado"</item> <item msgid="578444932039713369">"Activado"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"No disponible"</item> + <item msgid="9061144428113385092">"Desactivado"</item> + <item msgid="2984256114867200368">"Activado"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"No disponible"</item> <item msgid="8707481475312432575">"Desactivado"</item> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 1ccc036635dc..dfbb1ee562d1 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Lülita sisse"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Lülita sisse"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Tänan, ei"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Tavaline"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstreemne"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Kuva automaatne pööramine"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Kas lubada rakendusele <xliff:g id="APPLICATION">%1$s</xliff:g> juurdepääs seadmele <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Kas lubada rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> seadmele <xliff:g id="USB_DEVICE">%2$s</xliff:g> juurde pääseda?\nSellele rakendusele pole antud salvestamise luba, kuid see saab heli jäädvustada selle USB-seadme kaudu."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkesta ühendus"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiveeri"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Lülita automaatselt homme uuesti sisse"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funktsioonid, nagu Kiirjagamine, Leia mu seade ja seadme asukoht, kasutavad Bluetoothi"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Heli"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Peakomplekt"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Puudutage vibreerimise määramiseks."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Puudutage vaigistamiseks."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Mürasummutus"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Puudutage telefonihelina režiimi muutmiseks"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vaigistamine"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vaigistuse tühistamine"</string> diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml index 4f0551d7af74..f16d55247099 100644 --- a/packages/SystemUI/res/values-et/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Väljas"</item> <item msgid="578444932039713369">"Sees"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Pole saadaval"</item> + <item msgid="9061144428113385092">"Väljas"</item> + <item msgid="2984256114867200368">"Sees"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Pole saadaval"</item> <item msgid="8707481475312432575">"Väljas"</item> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 5776e0914b23..e41333c1baab 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktibatu"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktibatu"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ez, eskerrik asko"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Arrunta"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Muturrekoa"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Biratu pantaila automatikoki"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?\nAplikazioak ez du grabatzeko baimenik, baina baliteke USB bidezko gailu horren bidez audioa grabatzea."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deskonektatu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktibatu"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Aktibatu automatikoki berriro bihar"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, Bilatu nire gailua, gailuaren kokapena eta beste eginbide batzuek Bluetootha darabilte"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audioa"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Entzungailua"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Sakatu hau dardara ezartzeko."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sakatu hau audioa desaktibatzeko."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Zarata-murrizketa"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Sakatu tonu-jotzailearen modua aldatzeko"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desaktibatu audioa"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktibatu audioa"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateriaren <xliff:g id="PERCENTAGE">%s</xliff:g> geratzen da"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Konektatu arkatza kargagailu batera"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Arkatzak bateria gutxi du"</string> diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml index accecacbe8dd..0f6570c39750 100644 --- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desaktibatuta"</item> <item msgid="578444932039713369">"Aktibatuta"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ez dago erabilgarri"</item> + <item msgid="9061144428113385092">"Desaktibatuta"</item> + <item msgid="2984256114867200368">"Aktibatuta"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Ez dago erabilgarri"</item> <item msgid="8707481475312432575">"Desaktibatuta"</item> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 60172098c6a0..6b5c4ccaefe6 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"روشن کردن"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"روشن کردن"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"نه متشکرم"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"استاندارد"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"نهایت"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"چرخش خودکار صفحه"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> اجازه داده شود؟"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"به <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه میدهید به <xliff:g id="USB_DEVICE">%2$s</xliff:g>دسترسی داشته باشد؟\nمجوز ضبط به این برنامه داده نشده است اما میتواند صدا را ازطریق این دستگاه USB ضبط کند."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"فردا دوباره بهطور خودکار روشن شود"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ویژگیهایی مثل «همرسانی سریع»، «پیدا کردن دستگاهم»، و مکان دستگاه از بلوتوث استفاده میکنند"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"شارژ باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"هدست"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. برای صامت کردن ضربه بزنید."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"کنترل صدای محیط"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، ضربه بزنید"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string> @@ -1220,7 +1233,7 @@ <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"باز کردن تلفن"</string> <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"صفحهها جابهجا شود؟"</string> <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"برای وضوح بیشتر، از دوربین پشت استفاده کنید"</string> - <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"برای وضوح بیشتر، تلفن را برگردانید"</string> + <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 quick_settings_rotation_posture_folded (2430280856312528289) --> diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml index 01a549ed70b3..6d6954eec79b 100644 --- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"خاموش"</item> <item msgid="578444932039713369">"روشن"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"دردسترس نیست"</item> + <item msgid="9061144428113385092">"خاموش"</item> + <item msgid="2984256114867200368">"روشن"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"دردسترس نیست"</item> <item msgid="8707481475312432575">"خاموش"</item> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 7872ef06b9ae..78f401fd9277 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Laita päälle"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Laita päälle"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ei kiitos"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Tavallinen"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Näytön automaattinen kääntö"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> käyttöoikeuden (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> tämän pääsyoikeuden: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nSovellus ei ole saanut tallennuslupaa, mutta voi tallentaa ääntä tämän USB-laitteen avulla."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"katkaise yhteys"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivoi"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Laita automaattisesti päälle taas huomenna"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Ominaisuudet (esim. Quick Share ja Paikanna laite) ja laitteen sijainti käyttävät Bluetoothia"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ääni"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Siirry värinätilaan napauttamalla."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Mykistä napauttamalla."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Melunvaimennus"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Vaihda soittoäänen tilaa napauttamalla"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mykistä"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"poista mykistys"</string> diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml index f7a8ec94f1bd..545abc9c5681 100644 --- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Poissa päältä"</item> <item msgid="578444932039713369">"Päällä"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ei saatavilla"</item> + <item msgid="9061144428113385092">"Pois päältä"</item> + <item msgid="2984256114867200368">"Päällä"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Ei saatavilla"</item> <item msgid="8707481475312432575">"Poissa päältä"</item> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index b1c8944e2343..4c4913e4a959 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activer"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activer"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Non merci"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrême"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation auto de l\'écran"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autorisé <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"Déconnecter"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"Activer"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Activer le Bluetooth automatiquement demain"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Les fonctionnalités comme le Partage rapide, Localiser mon appareil et la position de l\'appareil utilisent le Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Écouteurs"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Touchez pour activer les vibrations."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Touchez pour couper le son."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Contrôle du bruit"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Touchez pour modifier le mode de sonnerie"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"désactiver le son"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Charge restante de la pile : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Pile du stylet faible"</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 7b9708ef03f4..d89484dc8c4a 100644 --- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Désactivé"</item> <item msgid="578444932039713369">"Activé"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Non accessible"</item> + <item msgid="9061144428113385092">"Désactivé"</item> + <item msgid="2984256114867200368">"Activé"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Non disponible"</item> <item msgid="8707481475312432575">"Désactivé"</item> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 665e81d78336..5bd34d78eec6 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activer"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activer"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Non, merci"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ultra"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation automatique de l\'écran"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio via ce périphérique USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"dissocier"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activer"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Réactiver automatiquement demain"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Certaines fonctionnalités telles que Quick Share, Localiser mon appareil ou encore la position de l\'appareil utilisent le Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Casque"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Appuyez pour mettre en mode vibreur."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Appuyez pour ignorer."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Contrôle du bruit"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Appuyez pour changer le mode de la sonnerie"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"couper le son"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batterie restante"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"La batterie du stylet est faible"</string> diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml index af1d09d3db3d..a560ff0a2f26 100644 --- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Désactivé"</item> <item msgid="578444932039713369">"Activé"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Non disponible"</item> + <item msgid="9061144428113385092">"Désactivé"</item> + <item msgid="2984256114867200368">"Activé"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Indisponible"</item> <item msgid="8707481475312432575">"Désactivée"</item> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 3764b0fdaada..e694d14086a2 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activar"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activar"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Non, grazas"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Estándar"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"extremo"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Xirar pantalla automaticamente"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Queres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Queres permitir que a aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda ao dispositivo (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?\nEsta aplicación non está autorizada para realizar gravacións, pero podería capturar audio a través deste dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Volver activar automaticamente mañá"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"As funcións como Quick Share, Localizar o meu dispositivo ou a de localización do dispositivo utilizan o Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca para establecer a vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca para silenciar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de ruído"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar o modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activar o son"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta o lapis óptico a un cargador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"O lapis óptico ten pouca batería"</string> diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml index a963decd28e9..1cde1ab0cbb7 100644 --- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Non"</item> <item msgid="578444932039713369">"Si"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Opción non dispoñible"</item> + <item msgid="9061144428113385092">"Opción desactivada"</item> + <item msgid="2984256114867200368">"Opción activada"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Non dispoñible"</item> <item msgid="8707481475312432575">"Non"</item> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 52fb9ee730e3..5099773c360a 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ચાલુ કરો"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ચાલુ કરો"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ના, આભાર"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"સ્ટૅન્ડર્ડ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"એક્સ્ટ્રીમ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ઑટો રોટેટ સ્ક્રીન"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ના ઍક્સેસ માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને મંજૂરી આપીએ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>ને <xliff:g id="USB_DEVICE">%2$s</xliff:g> ઍક્સેસ કરવાની મંજૂરી આપીએ?\nઆ ઍપને રેકૉર્ડ કરવાની પરવાનગી આપવામાં આવી નથી પરંતુ તે આ USB ડિવાઇસ મારફત ઑડિયો કૅપ્ચર કરી શકે છે."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"આવતીકાલે ફરીથી ઑટોમૅટિક રીતે ચાલુ કરો"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ક્વિક શેર, Find My Device અને ડિવાઇસના લોકેશન જેવી સુવિધાઓ બ્લૂટૂથનો ઉપયોગ કરે છે"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> બૅટરી"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ઑડિયો"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"હૅડસેટ"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. કંપન પર સેટ કરવા માટે ટૅપ કરો."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"અવાજનું નિયંત્રણ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"રિંગર મોડ બદલવા માટે ટૅપ કરો"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string> diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml index 580ec104dfb4..65b6133c547c 100644 --- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"બંધ છે"</item> <item msgid="578444932039713369">"ચાલુ છે"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"અનુપલબ્ધ છે"</item> + <item msgid="9061144428113385092">"બંધ છે"</item> + <item msgid="2984256114867200368">"ચાલુ છે"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ઉપલબ્ધ નથી"</item> <item msgid="8707481475312432575">"બંધ છે"</item> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 892fa6233a66..ea4ccc02a947 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"चालू करें"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"चालू करें"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"रहने दें"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"स्टैंडर्ड मोड"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"एक्सट्रीम"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"स्क्रीन अपने आप घुमाना"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_DEVICE">%2$s</xliff:g> के ऐक्सेस की अनुमति दें?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_DEVICE">%2$s</xliff:g> ऐक्सेस करने की अनुमति देना चाहते हैं?\nइस ऐप्लिकेशन को रिकॉर्ड करने की अनुमति नहीं दी गई है. हालांकि, ऐप्लिकेशन इस यूएसबी डिवाइस से ऑडियो कैप्चर कर सकता है."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"कल फिर से अपने-आप चालू हो जाएगा"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"क्विक शेयर, Find My Device, और डिवाइस की जगह की जानकारी जैसी सुविधाएं ब्लूटूथ का इस्तेमाल करती हैं"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बैटरी"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडियो"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. कंपन (वाइब्रेशन) पर सेट करने के लिए छूएं."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करने के लिए टैप करें."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"शोर को कंट्रोल करने की सुविधा"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलने के लिए टैप करें"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बैटरी बची है"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"अपने स्टाइलस को चार्ज करें"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"स्टाइलस की बैटरी कम है"</string> diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml index 3fd0b30ea4a0..b49d3b94167d 100644 --- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"बंद है"</item> <item msgid="578444932039713369">"चालू है"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"उपलब्ध नहीं है"</item> + <item msgid="9061144428113385092">"बंद है"</item> + <item msgid="2984256114867200368">"चालू है"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"उपलब्ध नहीं है"</item> <item msgid="8707481475312432575">"बंद है"</item> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index f6414639996d..a6cfeb9f8d0a 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standardno"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstremno"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatski zakreni zaslon"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacija nema dopuštenje za snimanje, no mogla bi primati zvuk putem tog USB uređaja."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekini vezu"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviraj"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatski ponovo uključi sutra"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Značajke kao što su brzo dijeljenje, Pronađi moj uređaj i lokacija uređaja upotrebljavaju Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste postavili na vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola buke"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promijenili način softvera zvona"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključivanje zvuka"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je <xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Priključite pisaljku na punjač"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Slaba baterija pisaljke"</string> diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml index 217d99975d3f..75fb3259ba34 100644 --- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Isključeno"</item> <item msgid="578444932039713369">"Uključeno"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nedostupno"</item> + <item msgid="9061144428113385092">"Isključeno"</item> + <item msgid="2984256114867200368">"Uključeno"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nedostupno"</item> <item msgid="8707481475312432575">"Isključeno"</item> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index eadc7da50918..7a3af4fb3da4 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Bekapcsolás"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Bekapcsolás"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Most nem"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Normál"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrém"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Képernyő automatikus forgatása"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Engedélyezi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> számára, hogy hozzáférjen a következőhöz: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Lehetővé teszi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazásnak, hogy hozzáférjen a következőhöz: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEz az alkalmazás nem rendelkezik rögzítési engedéllyel, de ezzel az USB-eszközzel képes a hangfelvételre."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"leválasztás"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiválás"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatikus visszakapcsolás holnap"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Az olyan funkciók, mint a Quick Share, a Készülékkereső és az eszköz helyadatai Bluetootht használnak"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hang"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Koppintson a rezgés beállításához."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Koppintson a némításhoz."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Zajszabályozás"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Koppintson a csengés módjának módosításához"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"némítás"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"némítás feloldása"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkumulátor töltöttségi szintje: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Tegye töltőre az érintőceruzát"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Az érintőceruza töltöttsége alacsony"</string> diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml index fad2cd4e6d4b..3ca391499727 100644 --- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Ki"</item> <item msgid="578444932039713369">"Be"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nem áll rendelkezésre"</item> + <item msgid="9061144428113385092">"Kikapcsolva"</item> + <item msgid="2984256114867200368">"Bekapcsolva"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nem áll rendelkezésre"</item> <item msgid="8707481475312432575">"Ki"</item> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 032b57ba9de5..d3b50d708032 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Միացնել"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Միացնել"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ոչ, շնորհակալություն"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Ստանդարտ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Առավելագույն"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ինքնապտտվող էկրան"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_DEVICE">%2$s</xliff:g> լրասարքը։"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_DEVICE">%2$s</xliff:g>ը։\nՀավելվածը ձայնագրելու թույլտվություն չունի, սակայն կկարողանա գրանցել ձայնն այս USB սարքի միջոցով։"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Վաղը նորից ավտոմատ միացնել"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Գործառույթները, ինչպիսիք են Quick Share-ը, «Գտնել իմ սարքը» գործառույթը և սարքի տեղորոշումը, օգտագործում են Bluetooth-ը"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Աուդիո"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ականջակալ"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s։ Հպեք՝ թրթռոցը միացնելու համար։"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s։ Հպեք՝ ձայնը անջատելու համար։"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Աղմուկի կառավարում"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Հպեք՝ զանգակի ռեժիմը փոխելու համար"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"անջատել ձայնը"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"միացնել ձայնը"</string> diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml index 380d9d2d9a95..89a94e80b622 100644 --- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Անջատված է"</item> <item msgid="578444932039713369">"Միացված է"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Հասանելի չէ"</item> + <item msgid="9061144428113385092">"Անջատված է"</item> + <item msgid="2984256114867200368">"Միացված է"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Հասանելի չէ"</item> <item msgid="8707481475312432575">"Անջատված է"</item> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 5442499e1fc8..3e34e5f642e4 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktifkan"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktifkan"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Lain kali"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standar"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstrem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Putar layar otomatis"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAplikasi ini belum diberi izin merekam, tetapi dapat merekam audio melalui perangkat USB ini."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan koneksi"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Otomatis aktifkan lagi besok"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Fitur seperti Quick Share, Temukan Perangkat Saya, dan lokasi perangkat menggunakan Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -429,8 +434,7 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan widget lainnya"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string> - <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> - <skip /> + <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon aplikasi untuk widget yang dinonaktifkan"</string> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Hapus"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string> @@ -583,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ketuk untuk menyetel agar bergetar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ketuk untuk menonaktifkan."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrol Bising"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Ketuk untuk mengubah mode pendering"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Tanpa suara"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktifkan"</string> @@ -837,10 +849,8 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu daya"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Layar kunci"</string> - <!-- no translation found for finder_active (7907846989716941952) --> - <skip /> - <!-- no translation found for shutdown_progress (5464239146561542178) --> - <skip /> + <string name="finder_active" msgid="7907846989716941952">"Anda dapat menemukan lokasi ponsel ini dengan Temukan Perangkat Saya meskipun ponsel dimatikan"</string> + <string name="shutdown_progress" msgid="5464239146561542178">"Sedang mematikan…"</string> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Lihat langkah-langkah perawatan"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Lihat langkah-langkah perawatan"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cabut perangkat"</string> @@ -1226,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Baterai tersisa <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Hubungkan stilus ke pengisi daya"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Baterai stilus lemah"</string> diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml index 9be5d0276a24..e1d533876be2 100644 --- a/packages/SystemUI/res/values-in/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Nonaktif"</item> <item msgid="578444932039713369">"Aktif"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Tidak tersedia"</item> + <item msgid="9061144428113385092">"Nonaktif"</item> + <item msgid="2984256114867200368">"Aktif"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Tidak tersedia"</item> <item msgid="8707481475312432575">"Nonaktif"</item> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 077e4def6823..a707d364ee43 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Kveikja"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Kveikja"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nei, takk"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Staðlað"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Mikill"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Snúa skjá sjálfkrafa"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nÞetta forrit hefur ekki fengið heimild fyrir upptöku en gæti tekið upp hljóð í gegnum þetta USB-tæki."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"aftengja"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"virkja"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Kveikja sjálfkrafa aftur á morgun"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Eiginleikar á borð við flýtideilingu, „Finna tækið mitt“ og staðsetningu tækis nota Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> rafhlöðuhleðsla"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hljóð"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Höfuðtól"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ýttu til að stilla á titring."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ýttu til að þagga."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Hávaðavörn"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Ýta til að skipta um hringjarastillingu"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"þagga"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"hætta að þagga"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> hleðsla eftir á rafhlöðu"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Tengdu pennann við hleðslutæki"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Rafhlaða pennans er að tæmast"</string> diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml index 1ee6e471fad3..1bd38ba77cfb 100644 --- a/packages/SystemUI/res/values-is/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Slökkt"</item> <item msgid="578444932039713369">"Kveikt"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ekki tiltækt"</item> + <item msgid="9061144428113385092">"Slökkt"</item> + <item msgid="2984256114867200368">"Kveikt"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Ekki í boði"</item> <item msgid="8707481475312432575">"Slökkt"</item> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 102690aaf631..dc957175e749 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Attiva"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Attiva"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, grazie"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Estremo"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotazione automatica schermo"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vuoi consentire all\'app <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nA questa app non è stata concessa l\'autorizzazione di registrazione, ma l\'app potrebbe acquisire l\'audio tramite questo dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnetti"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"attiva"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Riattiva automaticamente domani"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funzionalità come Quick Share, Trova il mio dispositivo e la posizione del dispositivo usano il Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auricolare"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tocca per attivare la vibrazione."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tocca per disattivare l\'audio."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controllo del rumore"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tocca per cambiare la modalità della suoneria"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenzia"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteria rimanente"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connetti lo stilo a un caricabatterie"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Batteria stilo in esaurimento"</string> diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml index 28e28aed82b8..f7abea571f1b 100644 --- a/packages/SystemUI/res/values-it/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Off"</item> <item msgid="578444932039713369">"On"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Non disponibile"</item> + <item msgid="9061144428113385092">"Off"</item> + <item msgid="2984256114867200368">"On"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Non disponibile"</item> <item msgid="8707481475312432575">"Off"</item> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index daca4e34c718..f88b1049798d 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"הפעלה"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"הפעלה"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"לא תודה"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"רגיל"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"משמעותי"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"סיבוב אוטומטי של המסך"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"האם לאפשר לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nאפליקציה זו לא קיבלה הרשאה להקליט אך יכולה לתעד אודיו באמצעות מכשיר USB זה."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"החיבור יופעל שוב אוטומטית מחר"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"תכונות כמו \'שיתוף מהיר\', \'איפה המכשיר שלי\' ומיקום המכשיר משתמשות בחיבור Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> סוללה"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"אודיו"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"אוזניות"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. יש להקיש כדי להעביר למצב רטט."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. יש להקיש כדי להשתיק."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"בקרת הרעש"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"רמת הטעינה שנותרה בסוללה: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"כדאי לחבר את הסטיילוס למטען"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"הסוללה של הסטיילוס חלשה"</string> diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml index bb3eb10fd719..1948685a2c66 100644 --- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"כבוי"</item> <item msgid="578444932039713369">"פועל"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"לא זמין"</item> + <item msgid="9061144428113385092">"מצב מושבת"</item> + <item msgid="2984256114867200368">"מצב פעיל"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"לא זמין"</item> <item msgid="8707481475312432575">"כבוי"</item> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index a33b95b88a54..36fc26f84cfc 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ONにする"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ON にする"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"いいえ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"標準"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"スーパー"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動回転画面"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_DEVICE">%2$s</xliff:g> へのアクセスを許可しますか?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_DEVICE">%2$s</xliff:g>へのアクセスを許可しますか?\nこのアプリに録音権限は付与されていませんが、アクセスを許可すると、この USB デバイスから音声を収集できるようになります。"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"明日自動的に ON に戻す"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"クイック共有、デバイスを探す、デバイスの位置情報などの機能は Bluetooth を使用します"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"オーディオ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ヘッドセット"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。タップしてバイブレーションに設定します。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。タップしてミュートします。"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ノイズ コントロール"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"タップすると、着信音のモードを変更できます"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ミュート"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ミュートを解除"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"バッテリー残量 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"タッチペンを充電器に接続してください"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"タッチペンのバッテリー残量が少なくなっています"</string> diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml index ebadf3b385ce..dd78c5e4d786 100644 --- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"OFF"</item> <item msgid="578444932039713369">"ON"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"使用不可"</item> + <item msgid="9061144428113385092">"OFF"</item> + <item msgid="2984256114867200368">"ON"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"使用不可"</item> <item msgid="8707481475312432575">"OFF"</item> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 7e3afd9b1669..e77d13705369 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ჩართვა"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ჩართვა"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"არა, გმადლობთ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"სტანდარტული"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"უკიდურესი"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ეკრანის ავტოროტაცია"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"მიეცეს <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ზე წვდომის უფლება?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"დართავთ <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ზე წვდომის ნებას?\nამ აპს არ აქვს მინიჭებული ჩაწერის ნებართვა, მაგრამ შეუძლია ჩაიწეროს აუდიო ამ USB მოწყობილობის მეშვეობით."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"ხელახლა ავტომატურად ჩართვა ხვალ"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ფუნქციები, როგორებიცაა „სწრაფი გაზიარება“, „ჩემი მოწყობილობის პოვნა“ და „მოწყობილობის მდებარეობა“ იყენებენ Bluetooth-ს"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ბატარეა"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"აუდიო"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ყურსაცვამი"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. შეეხეთ დასადუმებლად."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ხმაურის კონტროლი"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"შეეხეთ მრეკავის რეჟიმის შესაცვლელად"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"დარჩენილია ბატარეის <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"დააკავშირეთ თქვენი სტილუსი დამტენს"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"სტილუსის ბატარეა დაცლის პირასაა"</string> diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml index 07a8a76b8c97..2691b69154a9 100644 --- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"გამორთულია"</item> <item msgid="578444932039713369">"ჩართულია"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"მიუწვდომელია"</item> + <item msgid="9061144428113385092">"გამორთული"</item> + <item msgid="2984256114867200368">"ჩართული"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"მიუწვდომელია"</item> <item msgid="8707481475312432575">"გამორთულია"</item> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 58c37677e5a9..6daba135cd65 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Қосу"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Қосу"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Жоқ, рақмет"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартты"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Барынша"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Авто айналатын экран"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысына кіруге рұқсат берілсін бе?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысын пайдалануға рұқсат етілсін бе?\nҚолданбаның жазу рұқсаты жоқ, бірақ осы USB құрылғысы арқылы аудио жаза алады."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Ертең автоматты түрде қосылсын"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, Find My Device сияқты функциялар мен құрылғы локациясы Bluetooth пайдаланады."</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Aудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Діріл режимін орнату үшін түртіңіз."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дыбысын өшіру үшін түртіңіз."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Шуды реттеу"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Қоңырау режимін өзгерту үшін түртіңіз."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дыбысын өшіру"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дыбысын қосу"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Қалған батарея заряды: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусты зарядтағышқа жалғаңыз."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Стилус батареясының заряды аз"</string> diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml index f5b094855618..b37e98299b1f 100644 --- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Өшірулі"</item> <item msgid="578444932039713369">"Қосулы"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Қолжетімді емес"</item> + <item msgid="9061144428113385092">"Өшірулі"</item> + <item msgid="2984256114867200368">"Қосулы"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Қолжетімсіз"</item> <item msgid="8707481475312432575">"Өшірулі"</item> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 7a2291dfff4c..69adb22d810e 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"បើក"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"បើក"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ទេ អរគុណ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"ស្តង់ដារ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"ខ្លាំងបំផុត"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"អនុញ្ញាត <xliff:g id="APPLICATION">%1$s</xliff:g> ឱ្យចូលប្រើ <xliff:g id="USB_DEVICE">%2$s</xliff:g> មែនទេ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"អនុញ្ញាតឱ្យ <xliff:g id="APPLICATION">%1$s</xliff:g> ចូលប្រើ <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nកម្មវិធីនេះមិនទាន់បានទទួលសិទ្ធិថតសំឡេងនៅឡើយទេ ប៉ុន្តែអាចថតសំឡេងតាមរយៈឧបករណ៍ USB នេះបាន។"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"បើកដោយស្វ័យប្រវត្តិម្ដងទៀតនៅថ្ងៃស្អែក"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"មុខងារដូចជា Quick Share, រកឧបករណ៍របស់ខ្ញុំ និងប៊្លូធូសប្រើប្រាស់ទីតាំងឧបករណ៍"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"សំឡេង"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"កាស"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s ។ ចុចដើម្បីកំណត់ឲ្យញ័រ។"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s ។ ចុចដើម្បីបិទសំឡេង។"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ការគ្រប់គ្រងសំឡេងរំខាន"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ចុចដើម្បីប្ដូរមុខងាររោទ៍"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"បិទសំឡេង"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"បើកសំឡេង"</string> diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml index a2031b070a0c..0b2d5b3816ee 100644 --- a/packages/SystemUI/res/values-km/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"បិទ"</item> <item msgid="578444932039713369">"បើក"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"មិនអាចប្រើបាន"</item> + <item msgid="9061144428113385092">"បិទ"</item> + <item msgid="2984256114867200368">"បើក"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"មិនមានទេ"</item> <item msgid="8707481475312432575">"បិទ"</item> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 46442ee37164..f62c2a6daf5c 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ಆನ್ ಮಾಡಿ"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ಆನ್ ಮಾಡಿ"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ಬೇಡ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"ಪ್ರಮಾಣಿತ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"ತೀವ್ರ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಅನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?\nಈ ಆ್ಯಪ್ಗೆ ರೆಕಾರ್ಡ್ ಅನುಮತಿಯನ್ನು ನೀಡಲಾಗಿಲ್ಲ, ಆದರೆ ಈ USB ಸಾಧನದ ಮೂಲಕ ಆಡಿಯೊವನ್ನು ಸೆರೆಹಿಡಿಯಬಹುದು."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"ನಾಳೆ ಪುನಃ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಮಾಡಿ"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ಕ್ವಿಕ್ ಶೇರ್, Find My Device ನಂತಹ ಫೀಚರ್ಗಳು ಮತ್ತು ಸಾಧನದ ಸ್ಥಳ ಬ್ಲೂಟೂತ್ ಬಳಸುತ್ತವೆ"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ಆಡಿಯೋ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ಹೆಡ್ಸೆಟ್"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. ವೈಬ್ರೇಟ್ ಮಾಡಲು ಹೊಂದಿಸುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ಗದ್ದಲ ನಿಯಂತ್ರಣ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ರಿಂಗರ್ ಮೋಡ್ ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ"</string> diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml index de0fcae601cd..3ae65785784f 100644 --- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ಆಫ್"</item> <item msgid="578444932039713369">"ಆನ್"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"ಲಭ್ಯವಿಲ್ಲ"</item> + <item msgid="9061144428113385092">"ಆಫ್"</item> + <item msgid="2984256114867200368">"ಆನ್"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ಲಭ್ಯವಿಲ್ಲ"</item> <item msgid="8707481475312432575">"ಆಫ್"</item> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ffca4bc19d2e..40fb618795b5 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"사용"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"사용"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"사용 안함"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"표준"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"긴급"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"화면 자동 회전"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 <xliff:g id="USB_DEVICE">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>에서 <xliff:g id="USB_DEVICE">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?\n이 앱에는 녹음 권한이 부여되지 않았지만, 이 USB 기기를 통해 오디오를 녹음할 수 있습니다."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"내일 다시 자동으로 사용 설정"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, 내 기기 찾기, 기기 위치 등의 기능에서 블루투스를 사용합니다."</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"오디오"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"헤드셋"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. 탭하여 진동으로 설정하세요."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. 탭하여 음소거로 설정하세요."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"소음 제어"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"음소거"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"배터리 <xliff:g id="PERCENTAGE">%s</xliff:g> 남음"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"스타일러스를 충전기에 연결하세요"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"스타일러스 배터리 부족"</string> diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml index c9b2846ad9e1..002efb2b693b 100644 --- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"꺼짐"</item> <item msgid="578444932039713369">"켜짐"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"사용 불가"</item> + <item msgid="9061144428113385092">"사용 안함"</item> + <item msgid="2984256114867200368">"사용"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"이용 불가"</item> <item msgid="8707481475312432575">"꺼짐"</item> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 9de6b6685bf3..ef213caec594 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Күйгүзүү"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Күйгүзүү"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Жок, рахмат"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Кадимки"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Кескин"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Экранды авто буруу"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдоно берсинби?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдоно берсинби?\nБул колдонмого жаздырууга уруксат берилген эмес, бирок ушул USB түзмөгү аркылуу үндөрдү жаза алат."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Эртең автоматтык түрдө кайра күйгүзүү"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Тез Бөлүшүү, \"Түзмөгүм кайда?\" жана түзмөктүн турган жерин аныктоо сыяктуу функциялар Bluetooth\'ду колдонот"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Дирилдөөгө коюу үчүн басыңыз."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Үнүн өчүрүү үчүн басыңыз."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ызы-чууну көзөмөлдөө"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Коңгуроо режимин өзгөртүү үчүн басыңыз"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"үнсүз"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"үнүн чыгаруу"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Батареянын кубаты: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусту кубаттаңыз"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Стилустун батареясы отурайын деп калды"</string> diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml index bc47e5aea38f..bb03d0acc04d 100644 --- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Өчүк"</item> <item msgid="578444932039713369">"Күйүк"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Жеткиликсиз"</item> + <item msgid="9061144428113385092">"Өчүк"</item> + <item msgid="2984256114867200368">"Күйүк"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Жеткиликсиз"</item> <item msgid="8707481475312432575">"Өчүк"</item> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 18ca935ab6fd..94685028f9a3 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ເປີດໃຊ້"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ເປີດໃຊ້"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ບໍ່, ຂອບໃຈ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"ມາດຕະຖານ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"ສຸດຂີດ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ໄດ້ບໍ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ໄດ້ບໍ?\nແອັບນີ້ບໍ່ໄດ້ຮັບອະນຸາດໃຫ້ບັນທຶກໄດ້ແຕ່ສາມາດບັນທຶກສຽງໄດ້ຜ່ານອຸປະກອນ USB ນີ້."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"ເປີດໃຊ້ໂດຍອັດຕະໂນມັດອີກຄັ້ງມື້ອື່ນ"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ຄຸນສົມບັດຕ່າງໆເຊັ່ນ: ການແຊຣ໌ດ່ວນ, ຊອກຫາອຸປະກອນຂອງຂ້ອຍ ແລະ ສະຖານທີ່ອຸປະກອນໃຊ້ Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ສຽງ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ຊຸດຫູຟັງ"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. ແຕະເພື່ອຕັ້ງເປັນສັ່ນເຕືອນ."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ແຕະເພື່ອປິດສຽງ."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ການຄວບຄຸມສຽງລົບກວນ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ແຕະເພື່ອປ່ຽນໂໝດຣິງເກີ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ປິດສຽງ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ເຊົາປິດສຽງ"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ແບັດເຕີຣີເຫຼືອ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ເຊື່ອມຕໍ່ປາກກາຂອງທ່ານກັບສາຍສາກ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ແບັດເຕີຣີປາກກາເຫຼືອໜ້ອຍ"</string> diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml index 75958972cdce..3c288fce5d5a 100644 --- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ປິດ"</item> <item msgid="578444932039713369">"ເປີດ"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</item> + <item msgid="9061144428113385092">"ປິດ"</item> + <item msgid="2984256114867200368">"ເປີດ"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ບໍ່ສາມາດໃຊ້ໄດ້"</item> <item msgid="8707481475312432575">"ປິດ"</item> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 4ea218744931..3fc0dcb36750 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Įjungti"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Įjungti"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, ačiū"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Įprasta"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstremalus"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatiškai sukti ekraną"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?\nŠiai programai nebuvo suteiktas leidimas įrašyti, bet ji gali užfiksuoti garsą per šį USB įrenginį."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atjungti"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"suaktyvinti"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatiškai vėl įjungti rytoj"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Tokioms funkcijoms kaip „Spartusis bendrinimas“, „Rasti įrenginį“ ir įrenginio vietovė naudojamas „Bluetooth“ ryšys"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Garsas"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Virtualiosios realybės įrenginys"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Palieskite, kad nustatytumėte vibravimą."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Palieskite, kad nutildytumėte."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Triukšmo valdymas"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Palieskite, kad pakeistumėte skambučio režimą"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"nutildyti"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"įjungti garsą"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Liko akumuliatoriaus įkrovos: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Prijunkite rašiklį prie kroviklio"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Senka rašiklio akumuliatorius"</string> diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml index 94343bac9ff8..8c4515bf513c 100644 --- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Išjungta"</item> <item msgid="578444932039713369">"Įjungta"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nepasiekiama"</item> + <item msgid="9061144428113385092">"Išjungta"</item> + <item msgid="2984256114867200368">"Įjungta"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nepasiekiama"</item> <item msgid="8707481475312432575">"Išjungta"</item> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 82911ee683ca..1a2f8ba98996 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ieslēgt"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Ieslēgt"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nē, paldies"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standarta"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Maks. taupīšana"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automātiska ekrāna pagriešana"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai ierīcei: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt ierīcei “<xliff:g id="USB_DEVICE">%2$s</xliff:g>”?\nŠai lietotnei nav piešķirta ierakstīšanas atļauja, taču tā varētu tvert audio, izmantojot šo USB ierīci."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"atvienot"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizēt"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automātiski atkal ieslēgt rīt"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Tādas funkcijas kā “Ātrā kopīgošana”, “Atrast ierīci” un ierīces atrašanās vietas noteikšana izmanto tehnoloģiju Bluetooth."</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Austiņas"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Pieskarieties, lai iestatītu vibrozvanu."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Pieskarieties, lai izslēgtu skaņu."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Trokšņu kontrole"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Pieskarieties, lai mainītu zvanītāja režīmu."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izslēgt skaņu"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ieslēgt skaņu"</string> diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml index d8b24676ea27..a75e9d858afb 100644 --- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Izslēgta"</item> <item msgid="578444932039713369">"Ieslēgta"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nav pieejams"</item> + <item msgid="9061144428113385092">"Izslēgts"</item> + <item msgid="2984256114867200368">"Ieslēgts"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nav pieejama"</item> <item msgid="8707481475312432575">"Izslēgta"</item> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 64959bfdfe6d..b6651ad78510 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Вклучи"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Вклучи"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, фала"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандарден"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Екстремен"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Автоматско ротирање на екранот"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Ќе дозволите <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапува до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Дали дозволувате <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапи до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nНа апликацијава не ѝ е доделена дозвола за снимање, но може да снима аудио преку овој USB-уред."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Автоматски вклучи повторно утре"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Функциите како „Брзо споделување“, „Најди го мојот уред“ и локација на уредот користат Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерија"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Допрете за да се постави на вибрации."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Допрете за да се исклучи звукот."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола на бучавата"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Допрете за да го промените режимот на ѕвончето"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"исклучен звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"вклучен звук"</string> diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml index 8b0faf7d966e..4dd9e7328f88 100644 --- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Исклучено"</item> <item msgid="578444932039713369">"Вклучено"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Недостапно"</item> + <item msgid="9061144428113385092">"Исклучено"</item> + <item msgid="2984256114867200368">"Вклучено"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Недостапно"</item> <item msgid="8707481475312432575">"Исклучено"</item> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index aa351714caf6..a48d530374af 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ഓൺ ചെയ്യുക"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ഓണാക്കുക"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"വേണ്ട"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"സ്റ്റാൻഡേർഡ്"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"എക്സ്ട്രീം"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"സ്ക്രീൻ സ്വയമേ തിരിയുക"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ആക്സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g>-നെ അനുവദിക്കണോ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ആക്സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?\nഈ ആപ്പിന് റെക്കോർഡ് അനുമതി നൽകിയിട്ടില്ല, എന്നാൽ ഈ USB ഉപകരണത്തിലൂടെ ഓഡിയോ ക്യാപ്ചർ ചെയ്യാനാവും."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"നാളെ വീണ്ടും സ്വയമേവ ഓണാക്കുക"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ക്വിക്ക് ഷെയർ, Find My Device, ഉപകരണ ലൊക്കേഷൻ എന്നിവ പോലുള്ള ഫീച്ചറുകൾ Bluetooth ഉപയോഗിക്കുന്നു"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ബാറ്ററി"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ഓഡിയോ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ഹെഡ്സെറ്റ്"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"നോയ്സ് നിയന്ത്രണം"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"റിംഗർ മോഡ് മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"മ്യൂട്ട് ചെയ്യുക"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"അൺമ്യൂട്ട് ചെയ്യുക"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ബാറ്ററി ചാർജ് ശേഷിക്കുന്നു"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"നിങ്ങളുടെ സ്റ്റൈലസ് ചാർജറുമായി കണക്റ്റ് ചെയ്യുക"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"സ്റ്റൈലസിന്റെ ബാറ്ററി ചാർജ് കുറവാണ്"</string> diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml index 529d0def3e27..18e7b29b5d3d 100644 --- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ഓഫാണ്"</item> <item msgid="578444932039713369">"ഓണാണ്"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"ലഭ്യമല്ല"</item> + <item msgid="9061144428113385092">"ഓഫാണ്"</item> + <item msgid="2984256114867200368">"ഓണാണ്"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ലഭ്യമല്ല"</item> <item msgid="8707481475312432575">"ഓഫാണ്"</item> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 4ee598cb22e7..625b8b7d3a8f 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Асаах"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Асаах"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Үгүй, баярлалаа"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандарт"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Экстрим"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Дэлгэцийг автоматаар эргүүлэх"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>-д <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?\nЭнэ аппад бичих зөвшөөрөл олгогдоогүй ч USB төхөөрөмжөөр дамжуулан аудио бичиж чадсан."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Маргааш автоматаар дахин асаах"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Түргэн хуваалцах, Миний төхөөрөмжийг олох зэрэг онцлогууд болон төхөөрөмжийн байршил Bluetooth-г ашигладаг"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батарей"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Чихэвч"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Чичиргээнд тохируулахын тулд товшино уу."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дууг хаахын тулд товшино уу."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Шуугианы хяналт"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Хонхны горимыг өөрчлөхийн тулд товшино уу"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дууг хаах"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дууг нээх"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> батарей үлдлээ"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Мэдрэгч үзгээ цэнэглэгчтэй холбоорой"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Мэдрэгч үзэгний батарей бага байна"</string> diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml index 0db122904755..95f835ed0789 100644 --- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Унтраалттай"</item> <item msgid="578444932039713369">"Асаалттай"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Боломжгүй"</item> + <item msgid="9061144428113385092">"Унтраалттай"</item> + <item msgid="2984256114867200368">"Асаалттай"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Боломжгүй"</item> <item msgid="8707481475312432575">"Унтраалттай"</item> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 326c479de105..b5c0dc76b8dd 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"सुरू करा"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"सुरू करा"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"नाही, नको"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"साधारण"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"एक्स्ट्रीम"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ऑटो-रोटेट स्क्रीन"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अॅक्सेस करण्याची अनुमती द्यायची का?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अॅक्सेस करण्याची अनुमती द्यायची का?\nया अॅपला रेकॉर्ड करण्याची परवानगी दिलेली नाही पण या USB डिव्हाइसद्वारे ऑडिओ कॅप्चर केला जाऊ शकतो."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"उद्या पुन्हा आपोआप सुरू करा"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, Find My Device आणि डिव्हाइस स्थान यांसारखी वैशिष्ट्ये ब्लूटूथ वापरतात"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बॅटरी"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडिओ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करण्यासाठी टॅप करा."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"नॉइझ कंट्रोल"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलण्यासाठी टॅप करा"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string> diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml index b70a5cc671a7..6902a2fda8e2 100644 --- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"बंद आहे"</item> <item msgid="578444932039713369">"सुरू आहे"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"उपलब्ध नाही"</item> + <item msgid="9061144428113385092">"बंद आहे"</item> + <item msgid="2984256114867200368">"सुरू आहे"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"उपलब्ध नाही"</item> <item msgid="8707481475312432575">"बंद आहे"</item> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index b2afce9cfdd0..3419e6307a96 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Hidupkan"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Hidupkan"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Tidak perlu"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstrem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Autoputar skrin"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nApl ini belum diberikan kebenaran merakam tetapi dapat merakam audio melalui peranti USB ini."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"putuskan sambungan"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktifkan"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Dihidupkan sekali lagi esok secara automatik"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Ciri seperti Quick Share, Find My Device dan lokasi peranti menggunakan Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Set Kepala"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ketik untuk menetapkan pada getar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ketik untuk meredam."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kawalan Hingar"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Ketik untuk menukar mod pendering"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"redam"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"nyahredam"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateri tinggal <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Sambungkan stilus anda kepada pengecas"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateri stilus lemah"</string> diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml index b72a3756ccaa..a280916c7415 100644 --- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Mati"</item> <item msgid="578444932039713369">"Hidup"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Tidak tersedia"</item> + <item msgid="9061144428113385092">"Mati"</item> + <item msgid="2984256114867200368">"Hidup"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Tidak tersedia"</item> <item msgid="8707481475312432575">"Mati"</item> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index a4f91fa3cf10..36984fc5e4c6 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ဖွင့်ရန်"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ဖွင့်ရန်"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"မလိုပါ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"ပုံမှန်"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"လွန်ကဲ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ဖန်သားပြင် အလိုအလျောက်လှည့်ရန်"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> အား ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုပါသလား။"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> အား <xliff:g id="USB_DEVICE">%2$s</xliff:g> ကို သုံးခွင့်ပြုမလား။\nဤအက်ပ်ကို အသံဖမ်းခွင့် ပေးမထားသော်လည်း ၎င်းသည် ဤ USB စက်ပစ္စည်းမှတစ်ဆင့် အသံများကို ဖမ်းယူနိုင်ပါသည်။"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"မနက်ဖြန် အလိုအလျောက် ထပ်ဖွင့်ရန်"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"‘အမြန် မျှဝေပါ’၊ Find My Device နှင့် စက်ပစ္စည်းတည်နေရာကဲ့သို့ တူးလ်များသည် ဘလူးတုသ်သုံးသည်"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ဘက်ထရီ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"အသံ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"မိုက်ခွက်ပါနားကြပ်"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s။ တုန်ခါခြင်းသို့ သတ်မှတ်ရန်တို့ပါ။"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s။ အသံပိတ်ရန် တို့ပါ။"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ဆူညံသံ ထိန်းချုပ်ရန်"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်သေးသည်"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"စတိုင်လပ်စ်ကို အားသွင်းကိရိယာနှင့် ချိတ်ဆက်ခြင်း"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"စတိုင်လပ်စ် ဘက်ထရီ အားနည်းနေသည်"</string> diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml index d223dc9d0bed..ce10c422d6e1 100644 --- a/packages/SystemUI/res/values-my/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ပိတ်"</item> <item msgid="578444932039713369">"ဖွင့်"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"မရနိုင်ပါ"</item> + <item msgid="9061144428113385092">"ပိတ်"</item> + <item msgid="2984256114867200368">"ဖွင့်"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"မရနိုင်ပါ"</item> <item msgid="8707481475312432575">"ပိတ်"</item> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index e968fb5789dd..e126deaaa38f 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Slå på"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Slå på"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nei takk"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Ekstrem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotér skjermen automatisk"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDenne appen har ikke fått tillatelse til å spille inn, men kan ta opp lyd med denne USB-enheten."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koble fra"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiver"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Slå på igjen i morgen automatisk"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funksjoner som Quick Share, Finn enheten min og enhetsposisjon bruker Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Hodetelefoner"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Trykk for å angi vibrasjon."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Trykk for å slå av lyden."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Støykontroll"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Trykk for å endre ringemodus"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"kutt lyden"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på lyden"</string> @@ -1223,12 +1236,9 @@ <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 sammenleggbar enhet blir brettet ut"</string> <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string> - <!-- no translation found for quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri gjenstår"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koble pekepennen til en lader"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Det er lite batteri i pekepennen"</string> diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml index 2ed00960fdfd..71160d030629 100644 --- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Av"</item> <item msgid="578444932039713369">"På"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ikke tilgjengelig"</item> + <item msgid="9061144428113385092">"Av"</item> + <item msgid="2984256114867200368">"På"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Utilgjengelig"</item> <item msgid="8707481475312432575">"Av"</item> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index f12bd709fcfe..a06c1607342c 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"अन गर्नुहोस्"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"अन गर्नुहोस्"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"पर्दैन"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"डिफल्ट"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"चरम"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"स्वत:घुम्ने स्क्रिन"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> माथि पहुँच राख्ने अनुमति दिने हो?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> माथि पहुँच राख्न अनुमति दिने हो?\nयो एपलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"भोलि फेरि स्वतः अन गरियोस्"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"क्विक सेयर, Find My Device र डिभाइसको लोकेसन जस्ता सुविधाहरूले ब्लुटुथ प्रयोग गर्छन्"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ब्याट्री"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"अडियो"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। कम्पन मोडमा सेट गर्न ट्याप गर्नुहोस्।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। म्यूट गर्न ट्याप गर्नुहोस्।"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"नोइज कन्ट्रोल"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"रिङ्गर मोड बदल्न ट्याप गर्नुहोस्"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्युट गर्नुहोस्"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्युट गर्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml index 40159fb17279..19777063a49a 100644 --- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"अफ छ"</item> <item msgid="578444932039713369">"अन छ"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"उपलब्ध छैन"</item> + <item msgid="9061144428113385092">"अफ छ"</item> + <item msgid="2984256114867200368">"अन छ"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"उपलब्ध छैन"</item> <item msgid="8707481475312432575">"अफ छ"</item> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 01aa8db62445..86b2ebe460a0 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aanzetten"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aanzetten"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nee, bedankt"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standaard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreem"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Scherm automatisch draaien"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nDeze app heeft geen opnamerechten gekregen, maar zou audio kunnen vastleggen via dit USB-apparaat."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"loskoppelen"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activeren"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Morgen weer automatisch aanzetten"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Functies zoals Quick Share, Vind mijn apparaat en apparaatlocatie maken gebruik van bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om in te stellen op trillen."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om geluid uit te zetten."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ruisonderdrukking"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om de beltoonmodus te wijzigen"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Nog <xliff:g id="PERCENTAGE">%s</xliff:g> batterijlading"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Verbind je stylus met een oplader"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Batterij van stylus bijna leeg"</string> diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml index 60e35da7611b..7737794fbd9c 100644 --- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Uit"</item> <item msgid="578444932039713369">"Aan"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Niet beschikbaar"</item> + <item msgid="9061144428113385092">"Uit"</item> + <item msgid="2984256114867200368">"Aan"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Niet beschikbaar"</item> <item msgid="8707481475312432575">"Uit"</item> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 9b46c20b4ea6..afe1e662f94d 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ଚାଲୁ କରନ୍ତୁ"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ଚାଲୁ କରନ୍ତୁ"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ନା, ଧନ୍ୟବାଦ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"ଷ୍ଟାଣ୍ଡାର୍ଡ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"ଏକ୍ସଟ୍ରିମ୍"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ଅଟୋ-ରୋଟେଟ ସ୍କ୍ରିନ"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ କି?\nଏହି ଆପ୍କୁ ରେକର୍ଡ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ କିନ୍ତୁ ଏହି USB ଡିଭାଇସ୍ ଜରିଆରେ ଅଡିଓ କ୍ୟାପ୍ଟର୍ କରିପାରିବ।"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"ଆସନ୍ତାକାଲି ସ୍ୱତଃ ପୁଣି ଚାଲୁ ହେବ"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, Find My Device ଏବଂ ଡିଭାଇସ ଲୋକେସନ ପରି ଫିଚରଗୁଡ଼ିକ ବ୍ଲୁଟୁଥ ବ୍ୟବହାର କରେ"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ବ୍ୟାଟେରୀ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ଅଡିଓ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ହେଡସେଟ୍"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ଭାଇବ୍ରେଟରେ ସେଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ମ୍ୟୁଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ନଏଜ କଣ୍ଟ୍ରୋଲ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ମ୍ୟୁଟ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ଅନ୍-ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml index 43bddbf9f49b..046db2fbb30a 100644 --- a/packages/SystemUI/res/values-or/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ବନ୍ଦ ଅଛି"</item> <item msgid="578444932039713369">"ଚାଲୁ ଅଛି"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"ଅନୁପଲବ୍ଧ"</item> + <item msgid="9061144428113385092">"ବନ୍ଦ ଅଛି"</item> + <item msgid="2984256114867200368">"ଚାଲୁ ଅଛି"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ଉପଲବ୍ଧ ନାହିଁ"</item> <item msgid="8707481475312432575">"ବନ୍ଦ ଅଛି"</item> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index ac2badc5885f..8fda667fa95c 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ਚਾਲੂ ਕਰੋ"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ਚਾਲੂ ਕਰੋ"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ਨਹੀਂ ਧੰਨਵਾਦ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"ਮਿਆਰੀ"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"ਐਕਸਟ੍ਰੀਮ"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ਸਕ੍ਰੀਨ ਸਵੈ-ਘੁਮਾਓ"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"ਕੀ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਤੱਕ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"ਕੀ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?\nਇਸ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਪਰ ਇਹ USB ਡੀਵਾਈਸ ਰਾਹੀਂ ਆਡੀਓ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"ਕੱਲ੍ਹ ਨੂੰ ਆਪਣੇ ਆਪ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ਕਵਿੱਕ ਸ਼ੇਅਰ, Find My Device ਅਤੇ ਡੀਵਾਈਸ ਦਾ ਟਿਕਾਣਾ ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਬਲੂਟੁੱਥ ਦੀ ਵਰਤੋਂ ਕਰਦੀਆਂ ਹਨ"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ਆਡੀਓ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ਹੈੱਡਸੈੱਟ"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ਥਰਥਰਾਹਟ \'ਤੇ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ਸ਼ੋਰ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ਰਿੰਗਰ ਮੋਡ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ਮਿਊਟ ਕਰੋ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ਅਣਮਿਊਟ ਕਰੋ"</string> diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml index 5f0ca172dca9..df870cd145f5 100644 --- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ਬੰਦ ਹੈ"</item> <item msgid="578444932039713369">"ਚਾਲੂ ਹੈ"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"ਉਪਲਬਧ ਨਹੀਂ"</item> + <item msgid="9061144428113385092">"ਬੰਦ"</item> + <item msgid="2984256114867200368">"ਚਾਲੂ"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ਅਣਉਪਲਬਧ ਹੈ"</item> <item msgid="8707481475312432575">"ਬੰਦ ਹੈ"</item> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index a7d2b0ae8bca..cfbfa8a3fee0 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Włącz"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Włącz"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nie, dziękuję"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standardowe"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Intensywne"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Autoobracanie ekranu"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacja nie ma uprawnień do nagrywania, ale może rejestrować dźwięk za pomocą tego urządzenia USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"rozłącz"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktywuj"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automatycznie włącz ponownie jutro"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkcje takie jak Szybkie udostępnianie, Znajdź moje urządzenie i dotyczące lokalizacji urządzenia używają Bluetootha"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> naładowania baterii"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Dźwięk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Zestaw słuchawkowy"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Kliknij, by włączyć wibracje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Kliknij, by wyciszyć."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Tłumienie szumów"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Kliknij, aby zmienić tryb dzwonka"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g> baterii"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Podłącz rysik do ładowarki"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Słaba bateria w rysiku"</string> diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml index 5e3a1189c940..c667b99042ed 100644 --- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Wyłączony"</item> <item msgid="578444932039713369">"Włączony"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Niedostępne"</item> + <item msgid="9061144428113385092">"Wyłączono"</item> + <item msgid="2984256114867200368">"Włączono"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Niedostępne"</item> <item msgid="8707481475312432575">"Wyłączone"</item> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 8a4ce33f69fc..381c3bdc9cb3 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ativar"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Ativar"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Agora não"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Padrão"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrema"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Giro automático da tela"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Ativar automaticamente de novo amanhã"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Recursos como o Quick Share, o Encontre Meu Dispositivo e a localização do dispositivo usam o Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para configurar para vibrar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para silenciar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controle de ruído"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecte sua stylus a um carregador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da stylus fraca"</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 d4fd83803ba7..ae2bd051d223 100644 --- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desativada"</item> <item msgid="578444932039713369">"Ativada"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Indisponível"</item> + <item msgid="9061144428113385092">"Desativado"</item> + <item msgid="2984256114867200368">"Ativado"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Indisponível"</item> <item msgid="8707481475312432575">"Desativado"</item> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 011776c8d4a1..607a4aa1e760 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ativar"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Ativar"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Não"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Padrão"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrema"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rodar ecrã automaticamente"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permitir que a app <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao dispositivo <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> aceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desassociar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Reativar amanhã automaticamente"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"As funcionalidades como Partilha rápida, Localizar o meu dispositivo e localização do dispositivo usam o Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ausc. c/ mic. integ."</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para ativar a vibração."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para desativar o som."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controlo de ruído"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para alterar o modo de campainha"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de bateria restante"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ligue a caneta stylus a um carregador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da caneta stylus fraca"</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 e94b1ec6b0fd..666963b697cf 100644 --- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desligado"</item> <item msgid="578444932039713369">"Ligado"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Indisponível"</item> + <item msgid="9061144428113385092">"Desativado"</item> + <item msgid="2984256114867200368">"Ativado"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Indisponível"</item> <item msgid="8707481475312432575">"Desligado"</item> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 8a4ce33f69fc..381c3bdc9cb3 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ativar"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Ativar"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Agora não"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Padrão"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrema"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Giro automático da tela"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nEsse app não tem permissão de gravação, mas pode capturar áudio pelo dispositivo USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Ativar automaticamente de novo amanhã"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Recursos como o Quick Share, o Encontre Meu Dispositivo e a localização do dispositivo usam o Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para configurar para vibrar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para silenciar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controle de ruído"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecte sua stylus a um carregador"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da stylus fraca"</string> diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml index d4fd83803ba7..ae2bd051d223 100644 --- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Desativada"</item> <item msgid="578444932039713369">"Ativada"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Indisponível"</item> + <item msgid="9061144428113385092">"Desativado"</item> + <item msgid="2984256114867200368">"Ativado"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Indisponível"</item> <item msgid="8707481475312432575">"Desativado"</item> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 589b76833c78..857a167cfad8 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activează"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Activează"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nu, mulțumesc"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extremă"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotire automată a ecranului"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Permiți ca <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Permiți accesul aplicației <xliff:g id="APPLICATION">%1$s</xliff:g> la <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nPermisiunea de înregistrare nu a fost acordată aplicației, dar aceasta poate să înregistreze conținut audio prin intermediul acestui dispozitiv USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"deconectează"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activează"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Activează din nou automat mâine"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funcții precum Quick Share, Găsește-mi dispozitivul și locația dispozitivului folosesc Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Căști"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Atinge pentru a seta pe vibrații."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Atinge pentru a dezactiva sunetul."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controlul zgomotului"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Atinge pentru a schimba modul soneriei"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dezactivează sunetul"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activează sunetul"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterie rămasă"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conectează-ți creionul la un încărcător"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Nivelul bateriei creionului este scăzut"</string> diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml index 75565f942ac4..ed8285daa7a2 100644 --- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Dezactivată"</item> <item msgid="578444932039713369">"Activată"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Indisponibil"</item> + <item msgid="9061144428113385092">"Dezactivat"</item> + <item msgid="2984256114867200368">"Activat"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Indisponibilă"</item> <item msgid="8707481475312432575">"Dezactivată"</item> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 5b16bc5ed36b..87150cf6baea 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Включить"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Включить"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Нет"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартный режим"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Предельное"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Автоповорот экрана"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nПриложению не разрешено вести запись, однако с помощью этого USB-устройства оно может записывать звук."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Включить завтра автоматически"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Bluetooth используется в сервисе \"Найти устройство\", таких функциях, как Быстрая отправка, и при определении местоположения устройства"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудиоустройство"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Нажмите, чтобы включить вибрацию."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Нажмите, чтобы выключить звук."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контроль уровня шума"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Нажмите, чтобы изменить режим звонка."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"включить звук"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Уровень заряда батареи: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Поставьте стилус на зарядку."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Низкий заряд батареи стилуса"</string> diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml index 3099e008c93a..48ecf26fa3a0 100644 --- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Откл."</item> <item msgid="578444932039713369">"Вкл."</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Недоступно"</item> + <item msgid="9061144428113385092">"Отключено"</item> + <item msgid="2984256114867200368">"Включено"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Функция недоступна"</item> <item msgid="8707481475312432575">"Откл."</item> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index e240c4002bb2..e72f1ce015e9 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ක්රියාත්මක කරන්න"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ක්රියාත්මක කරන්න"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"එපා ස්තුතියි"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"සම්මත"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"අතිශය"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ස්වයංක්රීයව-භ්රමණය වන තිරය"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> හට <xliff:g id="USB_DEVICE">%2$s</xliff:g> වෙත පිවිසීමට ඉඩ දෙන්නද?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> වෙත ප්රවේශ වීමට <xliff:g id="USB_DEVICE">%2$s</xliff:g> හට ඉඩ දෙන්නද?\n මෙම යෙදුමට පටිගත කිරීම් අවසරයක් ලබා දී නොමැති නමුත් මෙම USB උපාංගය හරහා ශ්රව්ය ග්රහණය කර ගත හැකිය."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"හෙට ස්වයංක්රීයව නැවත ක්රියාත්මක කරන්න"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ඉක්මන් බෙදා ගැනීම, මගේ උපාංගය සෙවීම, සහ උපාංග ස්ථානය වැනි විශේෂාංග බ්ලූටූත් භාවිත කරයි"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ශ්රව්ය"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"හෙඩ්සෙටය"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. කම්පනය කිරීමට සකස් කිරීමට තට්ටු කරන්න."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ඝෝෂාව පාලනය"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"නාදකය වෙනස් කිරීමට තට්ටු කරන්න"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"නිහඬ කරන්න"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"නිශ්ශබ්දතාවය ඉවත් කරන්න"</string> diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml index 48e8cc4af507..cbbc0e783515 100644 --- a/packages/SystemUI/res/values-si/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"අක්රියයි"</item> <item msgid="578444932039713369">"සක්රියයි"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"නොමැත"</item> + <item msgid="9061144428113385092">"ක්රියාවිරහිතයි"</item> + <item msgid="2984256114867200368">"ක්රියාත්මකයි"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"නොමැත"</item> <item msgid="8707481475312432575">"අක්රියයි"</item> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 943adb1dde8b..6614c0d37fe6 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Zapnúť"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Zapnúť"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nie, vďaka"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Štandardný"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Super"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Automatické otočenie obrazovky"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> pristupovať k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTejto aplikácii nebolo udelené povolenie na nahrávanie, môže však snímať zvuk cez toto zariadenie USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"odpojiť"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivovať"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Automaticky zajtra znova zapnúť"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkcie, ako sú Quick Share, Nájdi moje zariadenie a poloha zariadenia, používajú Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Náhlavná súprava"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Klepnutím nastavíte vibrovanie."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Klepnutím vypnete zvuk."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ovládanie šumu"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g> batérie"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Pripojte dotykové pero k nabíjačke"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stav batérie dotykového pera je nízky"</string> diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml index fdfcd27db263..50f5c253bffe 100644 --- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Vypnuté"</item> <item msgid="578444932039713369">"Zapnuté"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nedostupné"</item> + <item msgid="9061144428113385092">"Vypnuté"</item> + <item msgid="2984256114867200368">"Zapnuté"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nie je k dispozícii"</item> <item msgid="8707481475312432575">"Vypnuté"</item> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index e4b33aa9fe6b..4a46742369c7 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Vklopi"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Vklopi"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standardno"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Strogo"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Samodejno zasukaj zaslon"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do dodatka USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do naprave <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nTa aplikacija sicer nima dovoljenja za snemanje, vendar bi lahko zajemala zvok prek te naprave USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekinitev povezave"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktiviranje"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Samodejno znova vklopi jutri"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funkcije, kot sta Hitro deljenje in Poišči mojo napravo, ter lokacija naprave, uporabljajo Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvok"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalke z mikrofonom"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dotaknite se, če želite nastaviti vibriranje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dotaknite se, če želite izklopiti zvok."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Omejevanje hrupa"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vklop zvoka"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostanek energije baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisalo s polnilnikom."</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Skoraj prazna baterija pisala"</string> diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml index 3804d639bb52..33ba21603e32 100644 --- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Izklopljeno"</item> <item msgid="578444932039713369">"Vklopljeno"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ni na voljo"</item> + <item msgid="9061144428113385092">"Izklopljeno"</item> + <item msgid="2984256114867200368">"Vklopljeno"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Ni na voljo"</item> <item msgid="8707481475312432575">"Izklopljeno"</item> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 3248a96a08f7..1fb6251adf9b 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktivizo"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktivizo"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Jo, faleminderit"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Në kushte ekstreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rrotullimi automatik i ekranit"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Të lejohet <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Dëshiron të lejosh që <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nKëtij aplikacioni nuk i është dhënë leje për regjistrim, por mund të regjistrojë audio përmes kësaj pajisjeje USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"shkëput"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivizo"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Aktivizoje automatikisht nesër"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Veçoritë si \"Ndarja e shpejtë\", \"Gjej pajisjen time\" dhe vendndodhja e pajisjes përdorin Bluetooth-in"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kufje me mikrofon"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Trokit për ta vendosur në dridhje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Trokit për ta çaktivizuar."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrolli i zhurmës"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Trokit për të ndryshuar modalitetin e ziles"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"çaktivizo audion"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktivizo audion"</string> diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml index 6318700bf6f2..fa06795e3ae8 100644 --- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Joaktive"</item> <item msgid="578444932039713369">"Aktiv"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Nuk ofrohet"</item> + <item msgid="9061144428113385092">"Joaktiv"</item> + <item msgid="2984256114867200368">"Aktiv"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Nuk ofrohet"</item> <item msgid="8707481475312432575">"Joaktive"</item> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index a80aee3874d6..3444c8085f44 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Укључи"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Укључи"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, хвала"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандардно"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Екстремно"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аутоматско ротирање екрана"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дозвољавате да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nОва апликација нема дозволу за снимање, али би могла да снима звук помоћу овог USB уређаја."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Аутоматски поново укључи сутра"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Функције као што су Quick Share, Пронађи мој уређај и локација уређаја користе Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалице"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Додирните да бисте подесили на вибрацију."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Додирните да бисте искључили звук."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола шума"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостало је још<xliff:g id="PERCENTAGE">%s</xliff:g> батерије"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Повежите писаљку са пуњачем"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Низак ниво батерије писаљке"</string> diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml index e4cf0b6cd2c0..55f5a3f5a45c 100644 --- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Искључено"</item> <item msgid="578444932039713369">"Укључено"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Недоступно"</item> + <item msgid="9061144428113385092">"Искључено"</item> + <item msgid="2984256114867200368">"Укључено"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Недоступно"</item> <item msgid="8707481475312432575">"Искључено"</item> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 49ddff030f9f..2ca3d5d03651 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aktivera"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktivera"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Nej tack"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Effektivare läget"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotera skärmen automatiskt"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nAppen har inte fått inspelningsbehörighet men kan spela in ljud via denna USB-enhet."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"koppla från"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"aktivera"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Aktivera automatiskt igen i morgon"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Funktioner som Snabbdelning, Hitta min enhet och enhetens plats använder Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ljud"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tryck här om du vill aktivera vibrationsläget."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tryck här om du vill stänga av ljudet."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Bruskontroll"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Tryck för att ändra ringsignalens läge"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stänga av ljudet"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på ljudet"</string> diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml index 8981ac775e50..f921f277dcec 100644 --- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Av"</item> <item msgid="578444932039713369">"På"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Inte tillgängligt"</item> + <item msgid="9061144428113385092">"Av"</item> + <item msgid="2984256114867200368">"På"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Inte tillgängligt"</item> <item msgid="8707481475312432575">"Av"</item> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 7fcdc079fe8b..b48a0f57d4ce 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Washa"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Washa"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Hapana"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Kawaida"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Kwa kina"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Skrini ijizungushe kiotomatiki"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nProgramu hii haijapewa ruhusa ya kurekodi lakini inaweza kurekodi sauti kupitia kifaa hiki cha USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ondoa"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"anza kutumia"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Iwashe tena kesho kiotomatiki"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Vipengele kama vile Kutuma Haraka, Tafuta Kifaa Changu na mahali kifaa kilipo hutumia Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Sauti"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Vifaa vya sauti"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Gusa ili uweke mtetemo."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Gusa ili usitishe."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kidhibiti cha Kelele"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Gusa ili ubadilishe hali ya programu inayotoa milio ya simu"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"zima sauti"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"washa sauti"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Chaji ya betri imesalia <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Unganisha stylus yako kwenye chaja"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Chaji ya betri ya Stylus imepungua"</string> diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml index 08a1f149264c..227eee882fe4 100644 --- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Kimezimwa"</item> <item msgid="578444932039713369">"Kimewashwa"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Haipatikani"</item> + <item msgid="9061144428113385092">"Imezimwa"</item> + <item msgid="2984256114867200368">"Imewashwa"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Hakipatikani"</item> <item msgid="8707481475312432575">"Kimezimwa"</item> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index cf2b3ee3b139..b95406425bcc 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"இயக்கு"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"இயக்கு"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"வேண்டாம்"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"நிலையானது"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"மேம்பட்டது"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"திரையைத் தானாகச் சுழற்று"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐ அணுக, <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐப் பயன்படுத்த <xliff:g id="APPLICATION">%1$s</xliff:g>ஐ அனுமதிக்கவா?\nஇந்த ஆப்ஸிற்கு ரெக்கார்டு செய்வதற்கான அனுமதி வழங்கப்படவில்லை, எனினும் இந்த USB சாதனம் மூலம் ஆடியோவைப் பதிவுசெய்யும்."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"நாளைக்குத் தானாகவே மீண்டும் இயக்கப்படும்"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்களும் சாதன இருப்பிடமும் புளூடூத்தைப் பயன்படுத்துகின்றன"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> பேட்டரி"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ஆடியோ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ஹெட்செட்"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும்."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ஒலியடக்க, தட்டவும்."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"இரைச்சல் கட்டுப்பாடு"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"ரிங்கர் பயன்முறையை மாற்ற தட்டவும்"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ஒலியடக்கும்"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ஒலி இயக்கும்"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> பேட்டரி மீதமுள்ளது"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"உங்கள் ஸ்டைலஸைச் சார்ஜருடன் இணையுங்கள்"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"ஸ்டைலஸின் பேட்டரி குறைவாக உள்ளது"</string> diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml index 741d6dea191f..6043cf25c7fa 100644 --- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"முடக்கப்பட்டுள்ளது"</item> <item msgid="578444932039713369">"இயக்கப்பட்டுள்ளது"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"இல்லை"</item> + <item msgid="9061144428113385092">"முடக்கப்பட்டுள்ளது"</item> + <item msgid="2984256114867200368">"இயக்கப்பட்டுள்ளது"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"கிடைக்கவில்லை"</item> <item msgid="8707481475312432575">"முடக்கப்பட்டுள்ளது"</item> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index e63ed1f9479b..75f872f0c602 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ఆన్ చేయి"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"ఆన్ చేయండి"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"వద్దు, ధన్యవాదాలు"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"స్టాండర్డ్"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"ఎక్స్ట్రీమ్"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"స్క్రీన్ ఆటో-రొటేట్"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ని యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని అనుమతించాలా?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ను అనుమతించాలా?\nఈ యాప్నకు రికార్డ్ చేసే అనుమతి మంజూరు చేయబడలేదు, కానీ ఈ USB పరికరం ద్వారా ఆడియోను క్యాప్చర్ చేయగలదు."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"రేపు మళ్లీ ఆటోమేటిక్గా ఆన్ చేస్తుంది"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"క్విక్ షేర్, Find My Device, పరికర లొకేషన్ వంటి ఫీచర్లు బ్లూటూత్ను ఉపయోగిస్తాయి"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> బ్యాటరీ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ఆడియో"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"హెడ్సెట్"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. వైబ్రేట్ అయ్యేలా సెట్ చేయడం కోసం నొక్కండి."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. మ్యూట్ చేయడానికి నొక్కండి."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"నాయిస్ కంట్రోల్"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"రింగర్ మోడ్ను మార్చడానికి ట్యాప్ చేయండి"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"అన్మ్యూట్ చేయి"</string> diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml index 6ff293479860..370aeb0d307c 100644 --- a/packages/SystemUI/res/values-te/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ఆఫ్లో ఉంది"</item> <item msgid="578444932039713369">"ఆన్లో ఉంది"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"అందుబాటులో లేదు"</item> + <item msgid="9061144428113385092">"ఆఫ్లో ఉంది"</item> + <item msgid="2984256114867200368">"ఆన్లో ఉంది"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"అందుబాటులో లేదు"</item> <item msgid="8707481475312432575">"ఆఫ్లో ఉంది"</item> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 9d3683e94a04..94243b0329e2 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"เปิด"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"เปิด"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"ไม่เป็นไร"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"มาตรฐาน"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"สูงสุด"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"หมุนหน้าจออัตโนมัติ"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม\nแอปนี้ไม่ได้รับอนุญาตให้อัดเสียงแต่อาจเก็บเสียงผ่านอุปกรณ์ USB นี้ได้"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"เปิดอีกครั้งโดยอัตโนมัติในวันพรุ่งนี้"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"ฟีเจอร์ต่างๆ เช่น Quick Share, หาอุปกรณ์ของฉัน และตำแหน่งของอุปกรณ์ ใช้บลูทูธ"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"เสียง"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ชุดหูฟัง"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s แตะเพื่อตั้งค่าให้สั่น"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s แตะเพื่อปิดเสียง"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"การควบคุมเสียง"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"แตะเพื่อเปลี่ยนโหมดเสียงเรียกเข้า"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ปิดเสียง"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"เปิดเสียง"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"เหลือแบตเตอรี่ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"เชื่อมต่อสไตลัสกับที่ชาร์จ"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"แบตเตอรี่สไตลัสเหลือน้อย"</string> diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml index d961385ba72e..acaf9f0f77fe 100644 --- a/packages/SystemUI/res/values-th/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"ปิด"</item> <item msgid="578444932039713369">"เปิด"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"ไม่พร้อมใช้งาน"</item> + <item msgid="9061144428113385092">"ปิด"</item> + <item msgid="2984256114867200368">"เปิด"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"ไม่พร้อมใช้งาน"</item> <item msgid="8707481475312432575">"ปิด"</item> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 5098f55b0d41..99b61e97579e 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"I-on"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"I-on"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Huwag na lang"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standard"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extreme"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"I-auto rotate ang screen"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na ma-access ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nHindi nabigyan ng pahintulot ang app na ito para mag-record pero nakakapag-capture ito ng audio sa pamamagitan ng USB device na ito."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"idiskonekta"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"i-activate"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Awtomatikong i-on ulit bukas"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Guamgamit ng Bluetooth ang mga feature tulad ng Quick Share, Hanapin ang Aking Device, at lokasyon ng device"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. I-tap upang itakda na mag-vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. I-tap upang i-mute."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Pagkontrol sa Ingay"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"I-tap para baguhin ang ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"i-mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"i-unmute"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterya na lang ang natitira"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ikonekta sa charger ang iyong stylus"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Paubos na ang baterya ng stylus"</string> diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml index a12c010f766a..6de62dff6e74 100644 --- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Naka-off"</item> <item msgid="578444932039713369">"Naka-on"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Hindi available"</item> + <item msgid="9061144428113385092">"Naka-off"</item> + <item msgid="2984256114867200368">"Naka-on"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Hindi available"</item> <item msgid="8707481475312432575">"Naka-off"</item> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 71de31beba9a..c20c62aad2d3 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Aç"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Aç"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Hayır, teşekkürler"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standart"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Yüksek"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranı otomatik döndür"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına erişmesine izin verilsin mi?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına erişmesine izin verilsin mi?\nBu uygulamaya kayıt izni verilmemiş ancak bu USB cihazı aracılığıyla sesleri yakalayabilir."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Yarın otomatik olarak tekrar aç"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Quick Share, Cihazımı Bul ve cihaz konumu gibi özellikler Bluetooth\'u kullanır"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ses"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Mikrofonlu kulaklık"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Titreşime ayarlamak için dokunun."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sesi kapatmak için dokunun."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Gürültü Kontrolü"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Telefon zili modunu değiştirmek için dokunun"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"sesi kapat"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"sesi aç"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> pil kaldı"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ekran kaleminizi bir şarj cihazına bağlayın"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Ekran kaleminin pil seviyesi düşük"</string> diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml index c6a8aecf0da1..0c086f839cad 100644 --- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Kapalı"</item> <item msgid="578444932039713369">"Açık"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Yok"</item> + <item msgid="9061144428113385092">"Kapalı"</item> + <item msgid="2984256114867200368">"Açık"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Kullanılamıyor"</item> <item msgid="8707481475312432575">"Kapalı"</item> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index c82acb134ff8..3338bce79494 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Увімкнути"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Увімкнути"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ні, дякую"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартний режим"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Екстремальний режим"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Автообертання екрана"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до такого аксесуара: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nЦей додаток не має дозволу на записування звуку, але може фіксувати його через цей USB-пристрій."</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"Автоматично ввімкнути знову завтра"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Такі функції, як швидкий обмін, \"Знайти пристрій\" і визначення місцезнаходження пристрою, використовують Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудіопристрій"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Торкніться, щоб налаштувати вібросигнал."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Торкніться, щоб вимкнути звук."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контроль шуму"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Торкніться, щоб змінити режим дзвінка"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"вимкнути звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"увімкнути звук"</string> diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml index a8e1ab8f3f99..fd3fb083b244 100644 --- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Вимкнено"</item> <item msgid="578444932039713369">"Увімкнено"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Недоступно"</item> + <item msgid="9061144428113385092">"Вимкнено"</item> + <item msgid="2984256114867200368">"Увімкнено"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Недоступно"</item> <item msgid="8707481475312432575">"Вимкнено"</item> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 16f37bd98bcb..bbc77674207b 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"آن کریں"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"آن کریں"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"نہیں شکریہ"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"معیاری"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"انتہائی"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"سکرین کو خودکار طور پر گھمائیں"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_DEVICE">%2$s</xliff:g> تک رسائی حاصل کرنے کی اجازت دیں؟"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_DEVICE">%2$s</xliff:g> تک رسائی دیں؟\nاس ایپ کو ریکارڈ کی اجازت عطا نہیں کی گئی ہے مگر اس USB آلہ سے کیپچر کر سکتے ہیں۔"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"کل دوبارہ خودکار طور پر آن ہوگا"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"فوری اشتراک، میرا آلہ ڈھونڈیں، اور آلہ کے مقام جیسی خصوصیات بلوٹوتھ کا استعمال کرتی ہیں"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> بیٹری"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"آڈیو"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ہیڈ سیٹ"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"شور کنٹرول"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"رنگر وضع تبدیل کرنے کیلئے تھپتھپائیں"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"خاموش کریں"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"غیر خاموش کریں"</string> diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml index 6d1e7076da40..4957e5924a54 100644 --- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"آف ہے"</item> <item msgid="578444932039713369">"آن ہے"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"دستیاب نہیں ہے"</item> + <item msgid="9061144428113385092">"آف ہے"</item> + <item msgid="2984256114867200368">"آن ہے"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"دستیاب نہیں ہے"</item> <item msgid="8707481475312432575">"آف ہے"</item> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 5a5ac38a989a..4967115f7ee4 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Yoqish"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Yoqish"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Kerak emas"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Standart"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Qattiq tejash"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ekranning avtomatik burilishi"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanishga ruxsat berilsinmi?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanish uchun ruxsat berilsinmi?\nBu ilovaga yozib olish ruxsati berilmagan, lekin shu USB orqali ovozlarni yozib olishi mumkin."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"uzish"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"faollashtirish"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Ertaga yana avtomatik yoqilsin"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Tezkor ulashuv, Qurilmamni top va qurilma geolokatsiyasi kabi funksiyalar Bluetooth ishlatadi"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Garnitura"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tebranishni yoqish uchun ustiga bosing."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ovozsiz qilish uchun ustiga bosing."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Shovqin boshqaruvi"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Jiringlagich rejimini oʻzgartirish uchun bosing"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ovozsiz qilish"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ovozni yoqish"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batareya quvvati: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Stilusni quvvat manbaiga ulang"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Stilus batareyasi kam"</string> diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml index 0558c4a91794..670c56ca517a 100644 --- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Oʻchiq"</item> <item msgid="578444932039713369">"Yoniq"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Mavjud emas"</item> + <item msgid="9061144428113385092">"Oʻchiq"</item> + <item msgid="2984256114867200368">"Yoniq"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Ishlamaydi"</item> <item msgid="8707481475312432575">"Oʻchiq"</item> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 8c174c019422..0b411b5d1925 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Bật"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Bật"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Không, cảm ơn"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Tiêu chuẩn"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Siêu tiết kiệm"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Tự động xoay màn hình"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập vào <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nỨng dụng này chưa được cấp quyền ghi âm nhưng vẫn có thể ghi âm thông qua thiết bị USB này."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"ngắt kết nối"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"kích hoạt"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Tự động bật lại vào ngày mai"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Các tính năng như Chia sẻ nhanh, Tìm thiết bị của tôi và dịch vụ vị trí trên thiết bị có sử dụng Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Âm thanh"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Tai nghe"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Nhấn để đặt chế độ rung."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Nhấn để tắt tiếng."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kiểm soát tiếng ồn"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Nhấn để thay đổi chế độ chuông"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"tắt tiếng"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"bật tiếng"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Còn <xliff:g id="PERCENTAGE">%s</xliff:g> pin"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Hãy kết nối bút cảm ứng với bộ sạc"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Bút cảm ứng bị yếu pin"</string> diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml index eee10d330258..4df2d910da28 100644 --- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Đang tắt"</item> <item msgid="578444932039713369">"Đang bật"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Không có"</item> + <item msgid="9061144428113385092">"Đang tắt"</item> + <item msgid="2984256114867200368">"Đang bật"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Không hoạt động"</item> <item msgid="8707481475312432575">"Đang tắt"</item> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index c0cdb766c09d..9a7588496fc7 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"开启"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"开启"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"不用了"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"标准"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"超级"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自动旋转屏幕"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"要允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"是否允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_DEVICE">%2$s</xliff:g>?\n此应用未获得录音权限,但能通过此 USB 设备录制音频。"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"明天自动重新开启"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"快速分享、查找我的设备、设备位置信息等功能会使用蓝牙"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> 的电量"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音频"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳机"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。点按即可设为振动。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。点按即可设为静音。"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪声控制"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"点按即可更改振铃器模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"静音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消静音"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"电池还剩 <xliff:g id="PERCENTAGE">%s</xliff:g> 的电量"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"请将触控笔连接充电器"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"触控笔电池电量低"</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 82ab6710729d..08a155183839 100644 --- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"已关闭"</item> <item msgid="578444932039713369">"已开启"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"不可用"</item> + <item msgid="9061144428113385092">"已停用"</item> + <item msgid="2984256114867200368">"已启用"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"不可用"</item> <item msgid="8707481475312432575">"已关闭"</item> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index f26324000b8f..2cf6da461f41 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"開啟"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"開啟"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"不用了,謝謝"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"標準"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"超級"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動旋轉螢幕"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n此應用程式尚未獲授予錄音權限,但可透過此 USB 裝置記錄音訊。"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"明天自動重新開啟"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"「快速共享」、「尋找我的裝置」和裝置位置等功能都會使用藍牙"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音訊"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳機"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。輕按即可設為震動。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。輕按即可設為靜音。"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪音控制"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"輕按即可變更響鈴模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"剩餘電量:<xliff:g id="PERCENTAGE">%s</xliff:g>"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"將觸控筆連接充電器"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"觸控筆電量不足"</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 6bac27502583..e29d23004bce 100644 --- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"已關閉"</item> <item msgid="578444932039713369">"已開啟"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"未有提供"</item> + <item msgid="9061144428113385092">"關閉"</item> + <item msgid="2984256114867200368">"開啟"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"無法使用"</item> <item msgid="8707481475312432575">"已關閉"</item> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 35af972b0fa6..12ca94c458b5 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"開啟"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"開啟"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"不用了,謝謝"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"標準"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"超級"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動旋轉螢幕"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?\n這個應用程式未取得錄製權限,但可以透過這部 USB 裝置錄製音訊。"</string> @@ -269,7 +271,10 @@ <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="414836329962473906">"明天自動重新開啟"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"快速分享、尋找我的裝置和裝置位置資訊等功能都會使用藍牙"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音訊"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳機"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。輕觸即可設為震動。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。輕觸即可設為靜音。"</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪音控制"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"輕觸即可變更鈴聲模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</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 5794bf1703f9..85e179661bbd 100644 --- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"已關閉"</item> <item msgid="578444932039713369">"已開啟"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"無法使用"</item> + <item msgid="9061144428113385092">"已關閉"</item> + <item msgid="2984256114867200368">"已開啟"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"無法使用"</item> <item msgid="8707481475312432575">"已關閉"</item> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 906996476c4e..b6f4a1959553 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -31,6 +31,8 @@ <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Vula"</string> <string name="battery_saver_start_action" msgid="8353766979886287140">"Vula"</string> <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Cha ngiyabonga"</string> + <string name="standard_battery_saver_text" msgid="6855876746552374119">"Okujwayelekile"</string> + <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Kakhulu"</string> <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Ukuzulazula kweskrini okuzenzakalelayo"</string> <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukufinyelela i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string> <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ifinyelele ku-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nLolu hlelo lokusebenza alunikeziwe imvume yokurekhoda kodwa lingathatha umsindo ngale divayisi ye-USB."</string> @@ -269,7 +271,10 @@ <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"nqamula"</string> <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"yenza kusebenze"</string> <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"Vula ngokuzenzekela futhi kusasa"</string> - <string name="turn_on_bluetooth_auto_info" msgid="8831410009251539988">"Izakhi ezifana Nokwabelana Ngokushesha, okuthi Thola Idivayisi Yami, kanye nendawo yedivayisi zisebenzisa i-Bluetooth"</string> + <!-- no translation found for turn_on_bluetooth_auto_info_disabled (8267380591344023327) --> + <skip /> + <!-- no translation found for turn_on_bluetooth_auto_info_enabled (4802071533678400330) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Umsindo"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ihedisethi"</string> @@ -582,6 +587,14 @@ <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Thepha ukuze usethele ekudlidlizeni."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Thepha ukuze uthulise."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ulawulo Lomsindo"</string> + <!-- no translation found for volume_panel_spatial_audio_title (3367048857932040660) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_off (4177490084606772989) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_fixed (3136080137827746046) --> + <skip /> + <!-- no translation found for volume_panel_spatial_audio_tracking (5711115234001762974) --> + <skip /> <string name="volume_ringer_change" msgid="3574969197796055532">"Thepha ukuze ushintshe imodi yokukhala"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"thulisa"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"susa ukuthula"</string> @@ -1223,12 +1236,9 @@ <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 quick_settings_rotation_posture_folded (2430280856312528289) --> - <skip /> - <!-- no translation found for quick_settings_rotation_posture_unfolded (6372316273574167114) --> - <skip /> - <!-- no translation found for rotation_tile_with_posture_secondary_label_template (7648496484163318886) --> - <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> <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ibhethri elisele"</string> <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Xhuma i-stylus yakho kushaja"</string> <string name="stylus_battery_low" msgid="7134370101603167096">"Ibhethri le-stylus liphansi"</string> diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml index 8c7b652cdfe0..5c5a67ca0eff 100644 --- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml +++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml @@ -126,9 +126,11 @@ <item msgid="8259411607272330225">"Valiwe"</item> <item msgid="578444932039713369">"Vuliwe"</item> </string-array> - <!-- no translation found for tile_states_record_issue:0 (1727196795383575383) --> - <!-- no translation found for tile_states_record_issue:1 (9061144428113385092) --> - <!-- no translation found for tile_states_record_issue:2 (2984256114867200368) --> + <string-array name="tile_states_record_issue"> + <item msgid="1727196795383575383">"Ayitholakali"</item> + <item msgid="9061144428113385092">"Kuvaliwe"</item> + <item msgid="2984256114867200368">"Kuvuliwe"</item> + </string-array> <string-array name="tile_states_reverse"> <item msgid="3574611556622963971">"Akutholakali"</item> <item msgid="8707481475312432575">"Valiwe"</item> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 517f88b7f571..25596cce3b97 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1135,6 +1135,14 @@ <string name="hub_mode_add_widget_button_text">Add widget</string> <!-- Text for the button that exits the hub mode editing mode. [CHAR LIMIT=50] --> <string name="hub_mode_editing_exit_button_text">Done</string> + <!-- Title for the dialog that redirects users to change allowed widget category in settings. [CHAR LIMIT=NONE] --> + <string name="dialog_title_to_allow_any_widget">Allow any widget on lock screen?</string> + <!-- Text for the button in the dialog that opens when tapping on disabled widgets. [CHAR LIMIT=NONE] --> + <string name="button_text_to_open_settings">Open settings</string> + <!-- Title of a dialog. This text is confirming that the user wants to turn on access to their work apps, which the user had previously paused. "Work" is an adjective. [CHAR LIMIT=30] --> + <string name="work_mode_off_title">Unpause work apps?</string> + <!-- Title for button to unpause on work profile. [CHAR LIMIT=NONE] --> + <string name="work_mode_turn_on">Unpause</string> <!-- Related to user switcher --><skip/> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt index aab0b1e99e09..e88aaf015f87 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt +++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt @@ -22,6 +22,7 @@ import android.content.BroadcastReceiver import android.content.ContentProvider import android.content.Context import android.content.Intent +import android.util.Log import androidx.core.app.AppComponentFactory import com.android.systemui.dagger.ContextComponentHelper import com.android.systemui.dagger.SysUIComponent @@ -90,8 +91,7 @@ abstract class SystemUIAppComponentFactoryBase : AppComponentFactory() { return app } - @UsesReflection( - KeepTarget(instanceOfClassConstant = SysUIComponent::class, methodName = "inject")) + @UsesReflection(KeepTarget(instanceOfClassConstant = SysUIComponent::class, methodName = "inject")) override fun instantiateProviderCompat(cl: ClassLoader, className: String): ContentProvider { val contentProvider = super.instantiateProviderCompat(cl, className) if (contentProvider is ContextInitializer) { @@ -103,12 +103,11 @@ abstract class SystemUIAppComponentFactoryBase : AppComponentFactory() { .getMethod("inject", contentProvider.javaClass) injectMethod.invoke(rootComponent, contentProvider) } catch (e: NoSuchMethodException) { - throw RuntimeException("No injector for class: " + contentProvider.javaClass, e) + Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e) } catch (e: IllegalAccessException) { - throw RuntimeException("Injector inaccessible for class: " + - contentProvider.javaClass, e) + Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e) } catch (e: InvocationTargetException) { - throw RuntimeException("Error while injecting: " + contentProvider.javaClass, e) + Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e) } initializer } diff --git a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt index b5a93b6635c6..9f13e6d32131 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt +++ b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt @@ -97,8 +97,8 @@ sealed interface BatteryColors { // 18% alpha black override val fill = Color.valueOf(0f, 0f, 0f, 0.18f).toArgb() - // GM Gray 500 - override val fillOnly = Color.parseColor("#9AA0A6") + // GM Gray 700 + override val fillOnly = Color.parseColor("#5F6368") // GM Red 600 override val errorForeground = Color.parseColor("#D93025") @@ -117,8 +117,8 @@ sealed interface BatteryColors { // 22% alpha white override val fill = Color.valueOf(1f, 1f, 1f, 0.22f).toArgb() - // GM Gray 600 - override val fillOnly = Color.parseColor("#80868B") + // GM Gray 400 + override val fillOnly = Color.parseColor("#BDC1C6") // GM Red 600 override val errorForeground = Color.parseColor("#D93025") diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt new file mode 100644 index 000000000000..9e7fb4e73a29 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.communal + +import android.annotation.SuppressLint +import android.app.DreamManager +import com.android.systemui.CoreStartable +import com.android.systemui.Flags.communalHub +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.util.kotlin.Utils.Companion.sample +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +/** + * A [CoreStartable] responsible for automatically starting the dream when the communal hub is + * shown, to support the user swiping away the hub to enter the dream. + */ +@SysUISingleton +class CommunalDreamStartable +@Inject +constructor( + private val powerInteractor: PowerInteractor, + private val keyguardInteractor: KeyguardInteractor, + private val keyguardTransitionInteractor: KeyguardTransitionInteractor, + private val dreamManager: DreamManager, + @Background private val bgScope: CoroutineScope, +) : CoreStartable { + @SuppressLint("MissingPermission") + override fun start() { + if (!communalHub()) { + return + } + + // Restart the dream underneath the hub in order to support the ability to swipe + // away the hub to enter the dream. + keyguardTransitionInteractor.finishedKeyguardState + .sample(powerInteractor.isAwake, keyguardInteractor.isDreaming) + .onEach { (finishedState, isAwake, dreaming) -> + if ( + finishedState == KeyguardState.GLANCEABLE_HUB && + !dreaming && + dreamManager.canStartDreaming(isAwake) + ) { + dreamManager.startDream() + } + } + .launchIn(bgScope) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt index 814295787b6c..940b48cc94c9 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt @@ -18,9 +18,14 @@ package com.android.systemui.communal.domain.interactor import android.app.smartspace.SmartspaceTarget import android.content.ComponentName +import android.content.Intent +import android.content.IntentFilter import android.os.UserHandle +import android.os.UserManager +import android.provider.Settings import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey +import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.communal.data.repository.CommunalMediaRepository import com.android.systemui.communal.data.repository.CommunalPrefsRepository import com.android.systemui.communal.data.repository.CommunalRepository @@ -45,6 +50,7 @@ import com.android.systemui.log.dagger.CommunalLog import com.android.systemui.log.dagger.CommunalTableLog import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable +import com.android.systemui.plugins.ActivityStarter import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.scene.shared.model.Scenes @@ -53,6 +59,7 @@ import com.android.systemui.smartspace.data.repository.SmartspaceRepository import com.android.systemui.util.kotlin.BooleanFlowOperators.and import com.android.systemui.util.kotlin.BooleanFlowOperators.not import com.android.systemui.util.kotlin.BooleanFlowOperators.or +import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -78,6 +85,7 @@ class CommunalInteractor @Inject constructor( @Application applicationScope: CoroutineScope, + broadcastDispatcher: BroadcastDispatcher, private val communalRepository: CommunalRepository, private val widgetRepository: CommunalWidgetRepository, private val communalPrefsRepository: CommunalPrefsRepository, @@ -88,6 +96,8 @@ constructor( private val appWidgetHost: CommunalAppWidgetHost, private val editWidgetsActivityStarter: EditWidgetsActivityStarter, private val userTracker: UserTracker, + private val activityStarter: ActivityStarter, + private val userManager: UserManager, sceneInteractor: SceneInteractor, sceneContainerFlags: SceneContainerFlags, @CommunalLog logBuffer: LogBuffer, @@ -247,6 +257,18 @@ constructor( editWidgetsActivityStarter.startActivity(preselectedKey) } + /** + * Navigates to communal widget setting after user has unlocked the device. Currently, this + * setting resides within the Hub Mode settings screen. + */ + fun navigateToCommunalWidgetSettings() { + activityStarter.postStartActivityDismissingKeyguard( + Intent(Settings.ACTION_COMMUNAL_SETTING) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP), + /* delay= */ 0, + ) + } + /** Dismiss the CTA tile from the hub in view mode. */ suspend fun dismissCtaTile() = communalPrefsRepository.setCtaDismissedForCurrentUser() @@ -272,6 +294,33 @@ constructor( fun updateWidgetOrder(widgetIdToPriorityMap: Map<Int, Int>) = widgetRepository.updateWidgetOrder(widgetIdToPriorityMap) + /** Request to unpause work profile that is currently in quiet mode. */ + fun unpauseWorkProfile() { + userTracker.userProfiles + .find { it.isManagedProfile } + ?.userHandle + ?.let { userHandle -> + userManager.requestQuietModeEnabled(/* enableQuietMode */ false, userHandle) + } + } + + /** Returns true if work profile is in quiet mode (disabled) for user handle. */ + private fun isQuietModeEnabled(userHandle: UserHandle): Boolean = + userManager.isManagedProfile(userHandle.identifier) && + userManager.isQuietModeEnabled(userHandle) + + /** Emits whenever a work profile pause or unpause broadcast is received. */ + private val updateOnWorkProfileBroadcastReceived: Flow<Unit> = + broadcastDispatcher + .broadcastFlow( + filter = + IntentFilter().apply { + addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) + addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) + }, + ) + .emitOnStart() + /** All widgets present in db. */ val communalWidgets: Flow<List<CommunalWidgetContentModel>> = isCommunalAvailable.flatMapLatest { available -> @@ -282,8 +331,9 @@ constructor( val widgetContent: Flow<List<WidgetContent>> = combine( widgetRepository.communalWidgets.map { filterWidgetsByExistingUsers(it) }, - communalSettingsInteractor.communalWidgetCategories - ) { widgets, allowedCategories -> + communalSettingsInteractor.communalWidgetCategories, + updateOnWorkProfileBroadcastReceived, + ) { widgets, allowedCategories, _ -> widgets.map { widget -> if (widget.providerInfo.widgetCategory and allowedCategories != 0) { // At least one category this widget specified is allowed, so show it @@ -291,6 +341,7 @@ constructor( appWidgetId = widget.appWidgetId, providerInfo = widget.providerInfo, appWidgetHost = appWidgetHost, + inQuietMode = isQuietModeEnabled(widget.providerInfo.profile) ) } else { WidgetContent.DisabledWidget( diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt index 12576d466823..5fabd3c9bed8 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt @@ -51,6 +51,7 @@ sealed interface CommunalContentModel { override val appWidgetId: Int, override val providerInfo: AppWidgetProviderInfo, val appWidgetHost: CommunalAppWidgetHost, + val inQuietMode: Boolean, ) : WidgetContent { override val key = KEY.widget(appWidgetId) // Widget size is always half. diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt index 35372cd28c15..85f3c202f10f 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt @@ -70,6 +70,10 @@ abstract class BaseCommunalViewModel( communalInteractor.addWidget(componentName, user, priority, configurator) } + open fun onOpenEnableWidgetDialog() {} + + open fun onOpenEnableWorkProfileDialog() {} + /** A list of all the communal content to be displayed in the communal hub. */ abstract val communalContent: Flow<List<CommunalContentModel>> diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt index 35b27aaeb6bc..6e69ed7c3267 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt @@ -87,6 +87,14 @@ constructor( override val isPopupOnDismissCtaShowing: Flow<Boolean> = _isPopupOnDismissCtaShowing.asStateFlow() + private val _isEnableWidgetDialogShowing: MutableStateFlow<Boolean> = MutableStateFlow(false) + val isEnableWidgetDialogShowing: Flow<Boolean> = _isEnableWidgetDialogShowing.asStateFlow() + + private val _isEnableWorkProfileDialogShowing: MutableStateFlow<Boolean> = + MutableStateFlow(false) + val isEnableWorkProfileDialogShowing: Flow<Boolean> = + _isEnableWorkProfileDialogShowing.asStateFlow() + /** Whether touches should be disabled in communal */ val touchesAllowed: Flow<Boolean> = not(shadeInteractor.isAnyFullyExpanded) @@ -120,6 +128,40 @@ constructor( setPopupOnDismissCtaVisibility(false) } + override fun onOpenEnableWidgetDialog() { + setIsEnableWidgetDialogShowing(true) + } + + fun onEnableWidgetDialogConfirm() { + communalInteractor.navigateToCommunalWidgetSettings() + setIsEnableWidgetDialogShowing(false) + } + + fun onEnableWidgetDialogCancel() { + setIsEnableWidgetDialogShowing(false) + } + + override fun onOpenEnableWorkProfileDialog() { + setIsEnableWorkProfileDialogShowing(true) + } + + fun onEnableWorkProfileDialogConfirm() { + communalInteractor.unpauseWorkProfile() + setIsEnableWorkProfileDialogShowing(false) + } + + fun onEnableWorkProfileDialogCancel() { + setIsEnableWorkProfileDialogShowing(false) + } + + private fun setIsEnableWidgetDialogShowing(isVisible: Boolean) { + _isEnableWidgetDialogShowing.value = isVisible + } + + private fun setIsEnableWorkProfileDialogShowing(isVisible: Boolean) { + _isEnableWorkProfileDialogShowing.value = isVisible + } + private fun setPopupOnDismissCtaVisibility(isVisible: Boolean) { _isPopupOnDismissCtaShowing.value = isVisible } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index ce24259bbc1e..9fa3e5fb155d 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -643,6 +643,7 @@ public class FrameworkServicesModule { @Provides @Singleton + @Nullable static CarrierConfigManager provideCarrierConfigManager(Context context) { return context.getSystemService(CarrierConfigManager.class); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index a3d6ad456e54..21ee5bd92328 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -24,6 +24,7 @@ import com.android.systemui.accessibility.Magnification import com.android.systemui.back.domain.interactor.BackActionInteractor import com.android.systemui.biometrics.BiometricNotificationService import com.android.systemui.clipboardoverlay.ClipboardListener +import com.android.systemui.communal.CommunalDreamStartable import com.android.systemui.communal.CommunalSceneStartable import com.android.systemui.communal.log.CommunalLoggerStartable import com.android.systemui.communal.widgets.CommunalAppWidgetHostStartable @@ -328,6 +329,11 @@ abstract class SystemUICoreStartableModule { @Binds @IntoMap + @ClassKey(CommunalDreamStartable::class) + abstract fun bindCommunalDreamStartable(impl: CommunalDreamStartable): CoreStartable + + @Binds + @IntoMap @ClassKey(CommunalAppWidgetHostStartable::class) abstract fun bindCommunalAppWidgetHostStartable( impl: CommunalAppWidgetHostStartable diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt index b97bace9584f..f860893f800b 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt @@ -33,7 +33,7 @@ import com.android.systemui.complication.ComplicationLayoutParams.POSITION_BOTTO import com.android.systemui.complication.ComplicationLayoutParams.POSITION_TOP import com.android.systemui.complication.ComplicationLayoutParams.Position import com.android.systemui.dreams.dagger.DreamOverlayModule -import com.android.systemui.dreams.ui.viewmodel.DreamOverlayViewModel +import com.android.systemui.dreams.ui.viewmodel.DreamViewModel import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.Logger @@ -53,7 +53,7 @@ constructor( private val mStatusBarViewController: DreamOverlayStatusBarViewController, private val mOverlayStateController: DreamOverlayStateController, @Named(DreamOverlayModule.DREAM_BLUR_RADIUS) private val mDreamBlurRadius: Int, - private val dreamOverlayViewModel: DreamOverlayViewModel, + private val dreamViewModel: DreamViewModel, @Named(DreamOverlayModule.DREAM_IN_BLUR_ANIMATION_DURATION) private val mDreamInBlurAnimDurationMs: Long, @Named(DreamOverlayModule.DREAM_IN_COMPLICATIONS_ANIMATION_DURATION) @@ -87,7 +87,7 @@ constructor( view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { launch { - dreamOverlayViewModel.dreamOverlayTranslationY.collect { px -> + dreamViewModel.dreamOverlayTranslationY.collect { px -> ComplicationLayoutParams.iteratePositions( { position: Int -> setElementsTranslationYAtPosition(px, position) }, POSITION_TOP or POSITION_BOTTOM @@ -96,7 +96,7 @@ constructor( } launch { - dreamOverlayViewModel.dreamOverlayTranslationX.collect { px -> + dreamViewModel.dreamOverlayTranslationX.collect { px -> ComplicationLayoutParams.iteratePositions( { position: Int -> setElementsTranslationXAtPosition(px, position) }, POSITION_TOP or POSITION_BOTTOM @@ -105,7 +105,7 @@ constructor( } launch { - dreamOverlayViewModel.dreamOverlayAlpha.collect { alpha -> + dreamViewModel.dreamOverlayAlpha.collect { alpha -> ComplicationLayoutParams.iteratePositions( { position: Int -> setElementsAlphaAtPosition( @@ -120,7 +120,7 @@ constructor( } launch { - dreamOverlayViewModel.transitionEnded.collect { _ -> + dreamViewModel.transitionEnded.collect { _ -> mOverlayStateController.setExitAnimationsRunning(false) } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamOverlayViewModel.kt deleted file mode 100644 index bd99f4b8230e..000000000000 --- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamOverlayViewModel.kt +++ /dev/null @@ -1,63 +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.systemui.dreams.ui.viewmodel - -import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel -import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel -import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToDreamingTransitionViewModel -import com.android.systemui.res.R -import javax.inject.Inject -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.merge - -@OptIn(ExperimentalCoroutinesApi::class) -@SysUISingleton -class DreamOverlayViewModel -@Inject -constructor( - configurationInteractor: ConfigurationInteractor, - toGlanceableHubTransitionViewModel: DreamingToGlanceableHubTransitionViewModel, - fromGlanceableHubTransitionInteractor: GlanceableHubToDreamingTransitionViewModel, - private val toLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel, -) { - - val dreamOverlayTranslationX: Flow<Float> = - merge( - toGlanceableHubTransitionViewModel.dreamOverlayTranslationX, - fromGlanceableHubTransitionInteractor.dreamOverlayTranslationX, - ) - - val dreamOverlayTranslationY: Flow<Float> = - configurationInteractor - .dimensionPixelSize(R.dimen.dream_overlay_exit_y_offset) - .flatMapLatest { px: Int -> - toLockscreenTransitionViewModel.dreamOverlayTranslationY(px) - } - - val dreamOverlayAlpha: Flow<Float> = - merge( - toLockscreenTransitionViewModel.dreamOverlayAlpha, - toGlanceableHubTransitionViewModel.dreamOverlayAlpha, - fromGlanceableHubTransitionInteractor.dreamOverlayAlpha, - ) - - val transitionEnded = toLockscreenTransitionViewModel.transitionEnded -} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt new file mode 100644 index 000000000000..0cb57fb937d2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamViewModel.kt @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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.ui.viewmodel + +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor +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.dock.DockManager +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel +import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel +import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToDreamingTransitionViewModel +import com.android.systemui.res.R +import com.android.systemui.settings.UserTracker +import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.merge + +@OptIn(ExperimentalCoroutinesApi::class) +@SysUISingleton +class DreamViewModel +@Inject +constructor( + configurationInteractor: ConfigurationInteractor, + keyguardTransitionInteractor: KeyguardTransitionInteractor, + fromGlanceableHubTransitionInteractor: GlanceableHubToDreamingTransitionViewModel, + private val toGlanceableHubTransitionViewModel: DreamingToGlanceableHubTransitionViewModel, + private val toLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel, + private val dockManager: DockManager, + private val communalInteractor: CommunalInteractor, + private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + private val userTracker: UserTracker, +) { + + fun startTransitionFromDream() { + val showGlanceableHub = + dockManager.isDocked && + communalInteractor.isCommunalEnabled.value && + !keyguardUpdateMonitor.isEncryptedOrLockdown(userTracker.userId) + if (showGlanceableHub) { + toGlanceableHubTransitionViewModel.startTransition() + communalInteractor.onSceneChanged(CommunalScenes.Communal) + } else { + toLockscreenTransitionViewModel.startTransition() + } + } + + val dreamOverlayTranslationX: Flow<Float> = + merge( + toGlanceableHubTransitionViewModel.dreamOverlayTranslationX, + fromGlanceableHubTransitionInteractor.dreamOverlayTranslationX, + ) + .distinctUntilChanged() + + val dreamOverlayTranslationY: Flow<Float> = + configurationInteractor + .dimensionPixelSize(R.dimen.dream_overlay_exit_y_offset) + .flatMapLatest { px: Int -> + toLockscreenTransitionViewModel.dreamOverlayTranslationY(px) + } + + val dreamAlpha: Flow<Float> = + merge( + toLockscreenTransitionViewModel.dreamOverlayAlpha, + toGlanceableHubTransitionViewModel.dreamAlpha, + ) + .distinctUntilChanged() + + val dreamOverlayAlpha: Flow<Float> = + merge( + toLockscreenTransitionViewModel.dreamOverlayAlpha, + toGlanceableHubTransitionViewModel.dreamOverlayAlpha, + fromGlanceableHubTransitionInteractor.dreamOverlayAlpha, + ) + .distinctUntilChanged() + + val transitionEnded = + keyguardTransitionInteractor.fromDreamingTransition.filter { step -> + step.transitionState == TransitionState.FINISHED || + step.transitionState == TransitionState.CANCELED + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 106fdf1fbcbe..5565ee295786 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -42,6 +42,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.ComposeLockscreen import com.android.systemui.keyguard.shared.model.LockscreenSceneBlueprint import com.android.systemui.keyguard.ui.binder.KeyguardBlueprintViewBinder @@ -107,6 +108,7 @@ constructor( private val lockscreenContentViewModel: LockscreenContentViewModel, private val lockscreenSceneBlueprintsLazy: Lazy<Set<LockscreenSceneBlueprint>>, private val keyguardBlueprintViewBinder: KeyguardBlueprintViewBinder, + private val clockInteractor: KeyguardClockInteractor, ) : CoreStartable { private var rootViewHandle: DisposableHandle? = null @@ -220,7 +222,11 @@ constructor( blueprints.mapNotNull { it as? ComposableLockscreenSceneBlueprint }.toSet() return ComposeView(context).apply { setContent { - LockscreenContent(viewModel = viewModel, blueprints = sceneBlueprints) + LockscreenContent( + viewModel = viewModel, + blueprints = sceneBlueprints, + clockInteractor = clockInteractor + ) .Content(modifier = Modifier.fillMaxSize()) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index a37397db81f8..43a8b40a3150 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -140,13 +140,13 @@ import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.dreams.ui.viewmodel.DreamViewModel; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.SystemPropertiesHelper; import com.android.systemui.keyguard.dagger.KeyguardModule; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.shared.model.TransitionStep; -import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.log.SessionTracker; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -1229,9 +1229,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, if (isDream) { initAlphaForAnimationTargets(wallpapers); - getRemoteSurfaceAlphaApplier().accept(0.0f); - mDreamingToLockscreenTransitionViewModel.get() - .startTransition(); + mDreamViewModel.get().startTransitionFromDream(); mUnoccludeFromDreamFinishedCallback = finishedCallback; return; } @@ -1359,8 +1357,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private final UiEventLogger mUiEventLogger; private final SessionTracker mSessionTracker; private final CoroutineDispatcher mMainDispatcher; - private final Lazy<DreamingToLockscreenTransitionViewModel> - mDreamingToLockscreenTransitionViewModel; + private final Lazy<DreamViewModel> mDreamViewModel; private RemoteAnimationTarget mRemoteAnimationTarget; private final Lazy<WindowManagerLockscreenVisibilityManager> mWmLockscreenVisibilityManager; @@ -1409,7 +1406,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, SystemSettings systemSettings, SystemClock systemClock, @Main CoroutineDispatcher mainDispatcher, - Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel, + Lazy<DreamViewModel> dreamViewModel, SystemPropertiesHelper systemPropertiesHelper, Lazy<WindowManagerLockscreenVisibilityManager> wmLockscreenVisibilityManager, SelectedUserInteractor selectedUserInteractor, @@ -1480,7 +1477,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, mUiEventLogger = uiEventLogger; mSessionTracker = sessionTracker; - mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel; + mDreamViewModel = dreamViewModel; mWmLockscreenVisibilityManager = wmLockscreenVisibilityManager; mMainDispatcher = mainDispatcher; @@ -1611,9 +1608,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, ViewRootImpl viewRootImpl = mKeyguardViewControllerLazy.get().getViewRootImpl(); if (viewRootImpl != null) { - DreamingToLockscreenTransitionViewModel viewModel = - mDreamingToLockscreenTransitionViewModel.get(); - collectFlow(viewRootImpl.getView(), viewModel.getDreamOverlayAlpha(), + final DreamViewModel viewModel = mDreamViewModel.get(); + collectFlow(viewRootImpl.getView(), viewModel.getDreamAlpha(), getRemoteSurfaceAlphaApplier(), mMainDispatcher); collectFlow(viewRootImpl.getView(), viewModel.getTransitionEnded(), getFinishedCallbackConsumer(), mMainDispatcher); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index 5306645bf69f..a243b8eec264 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -43,6 +43,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.dreams.ui.viewmodel.DreamViewModel; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.SystemPropertiesHelper; @@ -59,7 +60,6 @@ import com.android.systemui.keyguard.domain.interactor.StartKeyguardTransitionMo import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLogger; import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancesMetricsLoggerImpl; import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransitionModule; -import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.log.SessionTracker; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.settings.UserTracker; @@ -160,7 +160,7 @@ public interface KeyguardModule { SystemSettings systemSettings, SystemClock systemClock, @Main CoroutineDispatcher mainDispatcher, - Lazy<DreamingToLockscreenTransitionViewModel> dreamingToLockscreenTransitionViewModel, + Lazy<DreamViewModel> dreamViewModel, SystemPropertiesHelper systemPropertiesHelper, Lazy<WindowManagerLockscreenVisibilityManager> wmLockscreenVisibilityManager, SelectedUserInteractor selectedUserInteractor, @@ -207,7 +207,7 @@ public interface KeyguardModule { systemSettings, systemClock, mainDispatcher, - dreamingToLockscreenTransitionViewModel, + dreamViewModel, systemPropertiesHelper, wmLockscreenVisibilityManager, selectedUserInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt index 31371384e338..9a6088de110e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt @@ -35,6 +35,7 @@ import com.android.systemui.util.kotlin.Utils.Companion.toTriple import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.combine @@ -97,6 +98,18 @@ constructor( } } + fun startToGlanceableHubTransition() { + scope.launch { + KeyguardWmStateRefactor.isUnexpectedlyInLegacyMode() + if ( + transitionInteractor.startedKeyguardState.replayCache.last() == + KeyguardState.DREAMING + ) { + startTransitionTo(KeyguardState.GLANCEABLE_HUB) + } + } + } + private fun listenForDreamingToOccluded() { if (KeyguardWmStateRefactor.isEnabled) { scope.launch { @@ -205,14 +218,18 @@ constructor( return ValueAnimator().apply { interpolator = Interpolators.LINEAR duration = - if (toState == KeyguardState.LOCKSCREEN) TO_LOCKSCREEN_DURATION.inWholeMilliseconds - else DEFAULT_DURATION.inWholeMilliseconds + when (toState) { + KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION + KeyguardState.GLANCEABLE_HUB -> TO_GLANCEABLE_HUB_DURATION + else -> DEFAULT_DURATION + }.inWholeMilliseconds } } companion object { const val TAG = "FromDreamingTransitionInteractor" private val DEFAULT_DURATION = 500.milliseconds + val TO_GLANCEABLE_HUB_DURATION = 1.seconds val TO_LOCKSCREEN_DURATION = 1167.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt index 744301019dfc..197221a7b5b3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitions.kt @@ -21,7 +21,6 @@ import com.android.app.animation.Interpolators import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.interactor.CommunalTransitionProgress import com.android.systemui.communal.shared.model.CommunalScenes -import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionInfo @@ -29,13 +28,10 @@ import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.util.kotlin.sample import java.util.UUID import javax.inject.Inject -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.flow.flowOn class GlanceableHubTransitions @Inject constructor( - @Background private val bgDispatcher: CoroutineDispatcher, private val transitionInteractor: KeyguardTransitionInteractor, private val transitionRepository: KeyguardTransitionRepository, private val communalInteractor: CommunalInteractor, @@ -64,16 +60,16 @@ constructor( communalInteractor .transitionProgressToScene(toScene) .sample( - transitionInteractor.startedKeyguardTransitionStep.flowOn(bgDispatcher), + transitionInteractor.startedKeyguardState, ::Pair, ) - .collect { (transitionProgress, lastStartedStep) -> + .collect { (transitionProgress, lastStartedState) -> val id = transitionId if (id == null) { // No transition started. if ( transitionProgress is CommunalTransitionProgress.Transition && - lastStartedStep.to == fromState + lastStartedState == fromState ) { transitionId = transitionRepository.startTransition( @@ -86,7 +82,7 @@ constructor( ) } } else { - if (lastStartedStep.to != toState) { + if (lastStartedState != toState) { return@collect } // An existing `id` means a transition is started, and calls to diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt index c64f277b519a..789e4fbd46c2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.app.animation.Interpolators.EMPHASIZED import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow import com.android.systemui.res.R @@ -36,7 +37,9 @@ class DreamingToGlanceableHubTransitionViewModel constructor( animationFlow: KeyguardTransitionAnimationFlow, configurationInteractor: ConfigurationInteractor, + private val fromDreamingTransitionInteractor: FromDreamingTransitionInteractor, ) { + fun startTransition() = fromDreamingTransitionInteractor.startToGlanceableHubTransition() private val transitionAnimation = animationFlow.setup( @@ -58,6 +61,9 @@ constructor( ) } + // Keep the dream visible while the hub swipes in over the dream. + val dreamAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(1f) + val dreamOverlayAlpha: Flow<Float> = transitionAnimation.sharedFlow( duration = 167.milliseconds, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt index d3277cd295ac..f191aa7d7e4e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModel.kt @@ -20,16 +20,13 @@ import com.android.app.animation.Interpolators.EMPHASIZED import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor import com.android.systemui.keyguard.domain.interactor.FromDreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.filter /** * Breaks down DREAMING->LOCKSCREEN transition into discrete steps for corresponding views to @@ -40,7 +37,6 @@ import kotlinx.coroutines.flow.filter class DreamingToLockscreenTransitionViewModel @Inject constructor( - keyguardTransitionInteractor: KeyguardTransitionInteractor, private val fromDreamingTransitionInteractor: FromDreamingTransitionInteractor, animationFlow: KeyguardTransitionAnimationFlow, ) : DeviceEntryIconTransition { @@ -53,12 +49,6 @@ constructor( to = KeyguardState.LOCKSCREEN, ) - val transitionEnded = - keyguardTransitionInteractor.fromDreamingTransition.filter { step -> - step.transitionState == TransitionState.FINISHED || - step.transitionState == TransitionState.CANCELED - } - /** Dream overlay y-translation on exit */ fun dreamOverlayTranslationY(translatePx: Int): Flow<Float> { return transitionAnimation.sharedFlow( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt index f981fd50dc04..58c45c74815c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt @@ -36,6 +36,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn @SysUISingleton @@ -67,7 +68,16 @@ constructor( .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), - initialValue = LARGE + initialValue = LARGE, + ) + + val isLargeClockVisible = + clockSize + .map { it == LARGE } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = false, ) val currentClock = keyguardClockInteractor.currentClock diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt index b60e99973348..288ef3c52e21 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt @@ -22,6 +22,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -38,6 +40,7 @@ constructor( @Application applicationScope: CoroutineScope, deviceEntryInteractor: DeviceEntryInteractor, communalInteractor: CommunalInteractor, + shadeInteractor: ShadeInteractor, val longPress: KeyguardLongPressViewModel, val notifications: NotificationsPlaceholderViewModel, ) { @@ -64,4 +67,14 @@ constructor( started = SharingStarted.WhileSubscribed(), initialValue = null, ) + + /** The key of the scene we should switch to when swiping down from the top edge. */ + val downFromTopEdgeDestinationSceneKey: StateFlow<SceneKey?> = + shadeInteractor.shadeMode + .map { shadeMode -> Scenes.QuickSettings.takeIf { shadeMode is ShadeMode.Single } } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = null, + ) } diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt index 55d7f8e0f740..0d9b702b49ec 100644 --- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt +++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt @@ -23,6 +23,8 @@ import android.content.res.Resources import android.net.Uri import android.os.Handler import android.os.UserHandle +import android.util.Log +import androidx.core.content.FileProvider import com.android.internal.logging.UiEventLogger import com.android.systemui.dagger.qualifiers.LongRunning import com.android.systemui.dagger.qualifiers.Main @@ -34,7 +36,12 @@ import com.android.systemui.settings.UserContextProvider import com.android.systemui.statusbar.phone.KeyguardDismissUtil import com.android.traceur.FileSender import com.android.traceur.TraceUtils +import java.io.File +import java.io.FileOutputStream +import java.nio.file.Files import java.util.concurrent.Executor +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream import javax.inject.Inject class IssueRecordingService @@ -102,21 +109,22 @@ constructor( } private fun shareRecording(intent: Intent) { - val files = TraceUtils.traceDump(contentResolver, TRACE_FILE_NAME).get() - val traceUris: MutableList<Uri> = FileSender.getUriForFiles(this, files, AUTHORITY) - - if ( - intent.hasExtra(EXTRA_PATH) && intent.getStringExtra(EXTRA_PATH)?.isNotEmpty() == true - ) { - traceUris.add(Uri.parse(intent.getStringExtra(EXTRA_PATH))) - } - + val sharableUri: Uri = + zipAndPackageRecordings( + TraceUtils.traceDump(contentResolver, TRACE_FILE_NAME).get(), + intent.getStringExtra(EXTRA_PATH) + ) + ?: return val sendIntent = - FileSender.buildSendIntent(this, traceUris).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + FileSender.buildSendIntent(this, listOf(sharableUri)) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) if (mNotificationId != NOTIF_BASE_ID) { - val currentUserId = mUserContextTracker.userContext.userId - mNotificationManager.cancelAsUser(null, mNotificationId, UserHandle(currentUserId)) + mNotificationManager.cancelAsUser( + null, + mNotificationId, + UserHandle(mUserContextTracker.userContext.userId) + ) } // TODO: Debug why the notification shade isn't closing upon starting the BetterBug activity @@ -130,11 +138,39 @@ constructor( ) } + private fun zipAndPackageRecordings(traceFiles: List<File>, screenRecordingUri: String?): Uri? { + try { + externalCacheDir?.mkdirs() + val outZip: File = File.createTempFile(TEMP_FILE_PREFIX, ZIP_SUFFIX, externalCacheDir) + ZipOutputStream(FileOutputStream(outZip)).use { os -> + traceFiles.forEach { file -> + os.putNextEntry(ZipEntry(file.name)) + Files.copy(file.toPath(), os) + os.closeEntry() + } + if (screenRecordingUri != null) { + contentResolver.openInputStream(Uri.parse(screenRecordingUri))?.use { + os.putNextEntry(ZipEntry(SCREEN_RECORDING_ZIP_LABEL)) + it.transferTo(os) + os.closeEntry() + } + } + } + return FileProvider.getUriForFile(this, AUTHORITY, outZip) + } catch (e: Exception) { + Log.e(TAG, "Failed to zip and package Recordings. Cannot share with BetterBug.", e) + return null + } + } + companion object { private const val TAG = "IssueRecordingService" private const val CHANNEL_ID = "issue_record" private const val EXTRA_SCREEN_RECORD = "extra_screenRecord" private const val EXTRA_WINSCOPE_TRACING = "extra_winscopeTracing" + private const val ZIP_SUFFIX = ".zip" + private const val TEMP_FILE_PREFIX = "issue_recording" + private const val SCREEN_RECORDING_ZIP_LABEL = "screen-recording.mp4" private val DEFAULT_TRACE_TAGS = listOf<String>() private const val DEFAULT_BUFFER_SIZE = 16384 diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt new file mode 100644 index 000000000000..451fd679969a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.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.scene.ui.viewmodel + +import com.android.compose.animation.scene.Edge +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.SwipeDirection +import com.android.compose.animation.scene.UserAction +import com.android.compose.animation.scene.UserActionResult +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.shade.shared.model.ShadeMode +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn + +@SysUISingleton +class GoneSceneViewModel +@Inject +constructor( + @Application private val applicationScope: CoroutineScope, + shadeInteractor: ShadeInteractor, +) { + val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = + shadeInteractor.shadeMode + .map { shadeMode -> destinationScenes(shadeMode = shadeMode) } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = destinationScenes(shadeMode = shadeInteractor.shadeMode.value) + ) + + private fun destinationScenes(shadeMode: ShadeMode): Map<UserAction, UserActionResult> { + return buildMap { + if (shadeMode == ShadeMode.Single) { + this[ + Swipe( + pointerCount = 2, + fromSource = Edge.Top, + direction = SwipeDirection.Down, + )] = UserActionResult(Scenes.QuickSettings) + } + + this[Swipe(direction = SwipeDirection.Down)] = UserActionResult(Scenes.Shade) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt index d8c38503dbaf..f01e9bea1372 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt @@ -24,6 +24,7 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.util.Log import android.view.Display +import android.view.KeyEvent import android.view.LayoutInflater import android.view.ScrollCaptureResponse import android.view.View @@ -34,12 +35,15 @@ import android.window.OnBackInvokedDispatcher import com.android.internal.logging.UiEventLogger import com.android.systemui.flags.FeatureFlags import com.android.systemui.res.R +import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS +import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER /** * Legacy implementation of screenshot view methods. Just proxies the calls down into the original * ScreenshotView. */ -class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy { +class LegacyScreenshotViewProxy(context: Context, private val logger: UiEventLogger) : + ScreenshotViewProxy { override val view: ScreenshotView = LayoutInflater.from(context).inflate(R.layout.screenshot, null) as ScreenshotView override val screenshotPreview: View @@ -52,13 +56,6 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy { set(value) { view.setDefaultTimeoutMillis(value) } - override var onBackInvokedCallback: OnBackInvokedCallback = OnBackInvokedCallback { - Log.wtf(TAG, "OnBackInvoked called before being set!") - } - override var onKeyListener: View.OnKeyListener? = null - set(value) { - view.setOnKeyListener(value) - } override var flags: FeatureFlags? = null set(value) { view.setFlags(value) @@ -67,10 +64,6 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy { set(value) { view.setPackageName(value) } - override var logger: UiEventLogger? = null - set(value) { - view.setUiEventLogger(value) - } override var callbacks: ScreenshotView.ScreenshotViewCallback? = null set(value) { view.setCallbacks(value) @@ -88,31 +81,9 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy { get() = view.isPendingSharedTransition init { - - view.addOnAttachStateChangeListener( - object : View.OnAttachStateChangeListener { - override fun onViewAttachedToWindow(view: View) { - if (LogConfig.DEBUG_INPUT) { - Log.d(TAG, "Registering Predictive Back callback") - } - view - .findOnBackInvokedDispatcher() - ?.registerOnBackInvokedCallback( - OnBackInvokedDispatcher.PRIORITY_DEFAULT, - onBackInvokedCallback - ) - } - - override fun onViewDetachedFromWindow(view: View) { - if (LogConfig.DEBUG_INPUT) { - Log.d(TAG, "Unregistering Predictive Back callback") - } - view - .findOnBackInvokedDispatcher() - ?.unregisterOnBackInvokedCallback(onBackInvokedCallback) - } - } - ) + view.setUiEventLogger(logger) + addPredictiveBackListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) } + setOnKeyListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) } if (LogConfig.DEBUG_WINDOW) { Log.d(TAG, "adding OnComputeInternalInsetsListener") } @@ -135,7 +106,20 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy { override fun setChipIntents(imageData: ScreenshotController.SavedImageData) = view.setChipIntents(imageData) - override fun animateDismissal() = view.animateDismissal() + override fun requestDismissal(event: ScreenshotEvent) { + if (DEBUG_DISMISS) { + Log.d(TAG, "screenshot dismissal requested") + } + // If we're already animating out, don't restart the animation + if (view.isDismissing) { + if (DEBUG_DISMISS) { + Log.v(TAG, "Already dismissing, ignoring duplicate command $event") + } + return + } + logger.log(event, 0, packageName) + view.animateDismissal() + } override fun showScrollChip(packageName: String, onClick: Runnable) = view.showScrollChip(packageName, onClick) @@ -177,9 +161,58 @@ class LegacyScreenshotViewProxy(context: Context) : ScreenshotViewProxy { view.post(runnable) } + private fun addPredictiveBackListener(onDismissRequested: (ScreenshotEvent) -> Unit) { + val onBackInvokedCallback = OnBackInvokedCallback { + if (LogConfig.DEBUG_INPUT) { + Log.d(TAG, "Predictive Back callback dispatched") + } + onDismissRequested.invoke(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER) + } + view.addOnAttachStateChangeListener( + object : View.OnAttachStateChangeListener { + override fun onViewAttachedToWindow(v: View) { + if (LogConfig.DEBUG_INPUT) { + Log.d(TAG, "Registering Predictive Back callback") + } + view + .findOnBackInvokedDispatcher() + ?.registerOnBackInvokedCallback( + OnBackInvokedDispatcher.PRIORITY_DEFAULT, + onBackInvokedCallback + ) + } + + override fun onViewDetachedFromWindow(view: View) { + if (LogConfig.DEBUG_INPUT) { + Log.d(TAG, "Unregistering Predictive Back callback") + } + view + .findOnBackInvokedDispatcher() + ?.unregisterOnBackInvokedCallback(onBackInvokedCallback) + } + } + ) + } + private fun setOnKeyListener(onDismissRequested: (ScreenshotEvent) -> Unit) { + view.setOnKeyListener( + object : View.OnKeyListener { + override fun onKey(view: View, keyCode: Int, event: KeyEvent): Boolean { + if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) { + if (LogConfig.DEBUG_INPUT) { + Log.d(TAG, "onKeyEvent: $keyCode") + } + onDismissRequested.invoke(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER) + return true + } + return false + } + } + ) + } + class Factory : ScreenshotViewProxy.Factory { - override fun getProxy(context: Context): ScreenshotViewProxy { - return LegacyScreenshotViewProxy(context) + override fun getProxy(context: Context, logger: UiEventLogger): ScreenshotViewProxy { + return LegacyScreenshotViewProxy(context, logger) } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 1ca9b985b090..6bab956ca09a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -21,7 +21,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM; import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK; -import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS; import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT; import static com.android.systemui.screenshot.LogConfig.DEBUG_UI; import static com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW; @@ -64,7 +63,6 @@ import android.util.Pair; import android.view.Display; import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner; -import android.view.KeyEvent; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.ScrollCaptureResponse; @@ -333,12 +331,7 @@ public class ScreenshotController { mScreenshotHandler = timeoutHandler; mScreenshotHandler.setDefaultTimeoutMillis(SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS); - mScreenshotHandler.setOnTimeoutRunnable(() -> { - if (DEBUG_UI) { - Log.d(TAG, "Corner timeout hit"); - } - dismissScreenshot(SCREENSHOT_INTERACTION_TIMEOUT); - }); + mDisplayId = displayId; mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class)); @@ -351,7 +344,14 @@ public class ScreenshotController { mMessageContainerController = messageContainerController; mAssistContentRequester = assistContentRequester; - mViewProxy = viewProxyFactory.getProxy(mContext); + mViewProxy = viewProxyFactory.getProxy(mContext, mUiEventLogger); + + mScreenshotHandler.setOnTimeoutRunnable(() -> { + if (DEBUG_UI) { + Log.d(TAG, "Corner timeout hit"); + } + mViewProxy.requestDismissal(SCREENSHOT_INTERACTION_TIMEOUT); + }); mAccessibilityManager = AccessibilityManager.getInstance(mContext); @@ -376,7 +376,7 @@ public class ScreenshotController { @Override public void onReceive(Context context, Intent intent) { if (ClipboardOverlayController.COPY_OVERLAY_ACTION.equals(intent.getAction())) { - dismissScreenshot(SCREENSHOT_DISMISSED_OTHER); + mViewProxy.requestDismissal(SCREENSHOT_DISMISSED_OTHER); } } }; @@ -525,22 +525,11 @@ public class ScreenshotController { } /** - * Clears current screenshot + * Requests the view to dismiss the current screenshot (may be ignored, if screenshot is already + * being dismissed) */ - void dismissScreenshot(ScreenshotEvent event) { - if (DEBUG_DISMISS) { - Log.d(TAG, "dismissScreenshot"); - } - // If we're already animating out, don't restart the animation - if (mViewProxy.isDismissing()) { - if (DEBUG_DISMISS) { - Log.v(TAG, "Already dismissing, ignoring duplicate command"); - } - return; - } - mUiEventLogger.log(event, 0, mPackageName); - mScreenshotHandler.cancelTimeout(); - mViewProxy.animateDismissal(); + void requestDismissal(ScreenshotEvent event) { + mViewProxy.requestDismissal(event); } boolean isPendingSharedTransition() { @@ -572,10 +561,6 @@ public class ScreenshotController { mScreenshotSoundController.releaseScreenshotSoundAsync(); } - private void respondToKeyDismissal() { - dismissScreenshot(SCREENSHOT_DISMISSED_OTHER); - } - /** * Update resources on configuration change. Reinflate for theme/color changes. */ @@ -585,13 +570,6 @@ public class ScreenshotController { } mMessageContainerController.setView(mViewProxy.getView()); - mViewProxy.setLogger(mUiEventLogger); - mViewProxy.setOnBackInvokedCallback(() -> { - if (DEBUG_INPUT) { - Log.d(TAG, "Predictive Back callback dispatched"); - } - respondToKeyDismissal(); - }); mViewProxy.setCallbacks(new ScreenshotView.ScreenshotViewCallback() { @Override public void onUserInteraction() { @@ -622,17 +600,6 @@ public class ScreenshotController { mViewProxy.setDefaultDisplay(mDisplayId); mViewProxy.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis()); - mViewProxy.setOnKeyListener((v, keyCode, event) -> { - if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) { - if (DEBUG_INPUT) { - Log.d(TAG, "onKeyEvent: " + keyCode); - } - respondToKeyDismissal(); - return true; - } - return false; - }); - if (DEBUG_WINDOW) { Log.d(TAG, "setContentView: " + mViewProxy.getView()); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt index 381404a85587..d5c7f95ce289 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt @@ -24,11 +24,9 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.view.ScrollCaptureResponse import android.view.View -import android.view.View.OnKeyListener import android.view.ViewGroup import android.view.ViewTreeObserver import android.view.WindowInsets -import android.window.OnBackInvokedCallback import com.android.internal.logging.UiEventLogger import com.android.systemui.flags.FeatureFlags @@ -39,11 +37,8 @@ interface ScreenshotViewProxy { var defaultDisplay: Int var defaultTimeoutMillis: Long - var onBackInvokedCallback: OnBackInvokedCallback - var onKeyListener: OnKeyListener? var flags: FeatureFlags? var packageName: String - var logger: UiEventLogger? var callbacks: ScreenshotView.ScreenshotViewCallback? var screenshot: ScreenshotData? @@ -58,7 +53,7 @@ interface ScreenshotViewProxy { fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator fun addQuickShareChip(quickShareAction: Notification.Action) fun setChipIntents(imageData: ScreenshotController.SavedImageData) - fun animateDismissal() + fun requestDismissal(event: ScreenshotEvent) fun showScrollChip(packageName: String, onClick: Runnable) fun hideScrollChip() @@ -82,6 +77,6 @@ interface ScreenshotViewProxy { fun post(runnable: Runnable) interface Factory { - fun getProxy(context: Context): ScreenshotViewProxy + fun getProxy(context: Context, logger: UiEventLogger): ScreenshotViewProxy } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt index e464fd0c8e8e..bc3375502dd4 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt @@ -136,7 +136,7 @@ constructor( fun onCloseSystemDialogsReceived() { screenshotControllers.forEach { (_, screenshotController) -> if (!screenshotController.isPendingSharedTransition) { - screenshotController.dismissScreenshot(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER) + screenshotController.requestDismissal(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER) } } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 0991c9a326c8..9cf347bc8569 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -53,9 +53,9 @@ import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ScreenshotRequest; -import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.res.R; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -89,7 +89,7 @@ public class TakeScreenshotService extends Service { // TODO(b/295143676): move receiver inside executor when the flag is enabled. mTakeScreenshotExecutor.get().onCloseSystemDialogsReceived(); } else if (!mScreenshot.isPendingSharedTransition()) { - mScreenshot.dismissScreenshot(SCREENSHOT_DISMISSED_OTHER); + mScreenshot.requestDismissal(SCREENSHOT_DISMISSED_OTHER); } } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java index e92630fc67a2..92d6ec97ad83 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java @@ -63,7 +63,7 @@ import java.util.concurrent.Executor; public class BrightnessController implements ToggleSlider.Listener, MirroredBrightnessController { private static final String TAG = "CentralSurfaces.BrightnessController"; - private static final int SLIDER_ANIMATION_DURATION = 1000; + private static final int SLIDER_ANIMATION_DURATION = 3000; private static final int MSG_UPDATE_SLIDER = 1; private static final int MSG_ATTACH_LISTENER = 2; @@ -96,6 +96,7 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig }; private volatile boolean mAutomatic; // Brightness adjusted automatically using ambient light. + private boolean mTrackingTouch = false; // Brightness adjusted via touch events. private volatile boolean mIsVrModeEnabled; private boolean mListening; private boolean mExternalChange; @@ -330,6 +331,7 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig @Override public void onChanged(boolean tracking, int value, boolean stopTracking) { + mTrackingTouch = tracking; if (mExternalChange) return; if (mSliderAnimator != null) { @@ -396,6 +398,12 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig } } + private boolean triggeredByBrightnessKey() { + // When the brightness mode is manual and the user isn't changing the brightness via the + // brightness slider, assume changes are coming from a brightness key. + return !mAutomatic && !mTrackingTouch; + } + private void updateSlider(float brightnessValue, boolean inVrMode) { final float min = mBrightnessMin; final float max = mBrightnessMax; @@ -417,12 +425,13 @@ public class BrightnessController implements ToggleSlider.Listener, MirroredBrig } private void animateSliderTo(int target) { - if (!mControlValueInitialized || !mControl.isVisible()) { + if (!mControlValueInitialized || !mControl.isVisible() || triggeredByBrightnessKey()) { // Don't animate the first value since its default state isn't meaningful to users. // We also don't want to animate slider if it's not visible - especially important when // two sliders are active at the same time in split shade (one in QS and one in QQS), // as this negatively affects transition between them and they share mirror slider - - // animating it from two different sources causes janky motion + // animating it from two different sources causes janky motion. + // Don't animate if the value is changed via the brightness keys of a keyboard. mControl.setValue(target); mControlValueInitialized = true; } diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt index d3869baf16a2..3169e9ccbbcb 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.util.kotlin.collectFlow import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -47,6 +48,7 @@ class GlanceableHubContainerController constructor( private val communalInteractor: CommunalInteractor, private val communalViewModel: CommunalViewModel, + private val dialogFactory: SystemUIDialogFactory, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val shadeInteractor: ShadeInteractor, private val powerManager: PowerManager, @@ -119,7 +121,14 @@ constructor( ): View { return initView( ComposeView(context).apply { - setContent { PlatformTheme { CommunalContainer(viewModel = communalViewModel) } } + setContent { + PlatformTheme { + CommunalContainer( + viewModel = communalViewModel, + dialogFactory = dialogFactory, + ) + } + } } ) } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index fcd33279a2d6..ee561c4231bd 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -1198,7 +1198,8 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump /* excludeNotifications=*/ true), mMainDispatcher); collectFlow(mView, mPrimaryBouncerToGoneTransitionViewModel.getNotificationAlpha(), (Float alpha) -> { - mNotificationStackScrollLayoutController.setMaxAlphaForExpansion(alpha); + mNotificationStackScrollLayoutController.setMaxAlphaForKeyguard(alpha, + "mPrimaryBouncerToGoneTransitionViewModel.getNotificationAlpha()"); }, mMainDispatcher); } } @@ -1539,13 +1540,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mKeyguardBottomArea = keyguardBottomArea; } - @Override + /** Sets a listener to be notified when the shade starts opening or finishes closing. */ public void setOpenCloseListener(OpenCloseListener openCloseListener) { SceneContainerFlag.assertInLegacyMode(); mOpenCloseListener = openCloseListener; } - @Override + /** Sets a listener to be notified when touch tracking begins. */ public void setTrackingStartedListener(TrackingStartedListener trackingStartedListener) { mTrackingStartedListener = trackingStartedListener; } @@ -2718,7 +2719,8 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump && !mQsController.getFullyExpanded()) { alpha *= mClockPositionResult.clockAlpha; } - mNotificationStackScrollLayoutController.setMaxAlphaForExpansion(alpha); + mNotificationStackScrollLayoutController.setMaxAlphaForKeyguard(alpha, + "NPVC.updateNotificationTranslucency()"); } } @@ -2769,7 +2771,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } private void onExpandingFinished() { - mNotificationStackScrollLayoutController.onExpansionStopped(); + if (!SceneContainerFlag.isEnabled()) { + mNotificationStackScrollLayoutController.onExpansionStopped(); + } mHeadsUpManager.onExpandingFinished(); mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed()); mIsExpandingOrCollapsing = false; @@ -3084,7 +3088,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // The expandedHeight is always the full panel Height when bypassing expandedHeight = getMaxPanelHeight(); } - mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight); + if (!SceneContainerFlag.isEnabled()) { + mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight); + } updateKeyguardBottomAreaAlpha(); updateStatusBarIcons(); } @@ -4731,7 +4737,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump return (Float alpha) -> { mKeyguardStatusViewController.setAlpha(alpha); if (!excludeNotifications) { - stackScroller.setMaxAlphaForExpansion(alpha); + stackScroller.setMaxAlphaForKeyguard(alpha, "NPVC.setTransitionAlpha()"); } if (keyguardBottomAreaRefactor()) { diff --git a/packages/SystemUI/src/com/android/systemui/shade/OpenCloseListener.kt b/packages/SystemUI/src/com/android/systemui/shade/OpenCloseListener.kt new file mode 100644 index 000000000000..108dd47874c3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/OpenCloseListener.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade + +/** Listens for when shade begins opening or finishes closing. */ +interface OpenCloseListener { + /** Called when the shade finishes closing. */ + fun onClosingFinished() + + /** Called when the shade starts opening. */ + fun onOpenStarted() +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java index 19d98a0bb83c..fd68c56149db 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java @@ -76,6 +76,7 @@ import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QS; import com.android.systemui.res.R; +import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shade.data.repository.ShadeRepository; import com.android.systemui.shade.domain.interactor.ShadeInteractor; @@ -964,7 +965,9 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum // Reset scroll position and apply that position to the expanded height. float height = mExpansionHeight; setExpansionHeight(height); - mNotificationStackScrollLayoutController.checkSnoozeLeavebehind(); + if (!SceneContainerFlag.isEnabled()) { + mNotificationStackScrollLayoutController.checkSnoozeLeavebehind(); + } // When expanding QS, let's authenticate the user if possible, // this will speed up notification actions. @@ -1109,7 +1112,9 @@ public class QuickSettingsControllerImpl implements QuickSettingsController, Dum /** Called when shade starts expanding. */ void onExpandingStarted(boolean qsFullyExpanded) { - mNotificationStackScrollLayoutController.onExpansionStarted(); + if (!SceneContainerFlag.isEnabled()) { + mNotificationStackScrollLayoutController.onExpansionStarted(); + } mExpandedWhenExpandingStarted = qsFullyExpanded; mMediaHierarchyManager.setCollapsingShadeFromQS(mExpandedWhenExpandingStarted /* We also start expanding when flinging closed Qs. Let's exclude that */ diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt index 07236d1e5ab7..b595f866ec5a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt @@ -52,15 +52,9 @@ interface ShadeViewController { /** Returns whether the shade's top level view is enabled. */ val isViewEnabled: Boolean - /** Sets a listener to be notified when the shade starts opening or finishes closing. */ - fun setOpenCloseListener(openCloseListener: OpenCloseListener) - /** Returns whether status bar icons should be hidden when the shade is expanded. */ fun shouldHideStatusBarIconsWhenExpanded(): Boolean - /** Sets a listener to be notified when touch tracking begins. */ - fun setTrackingStartedListener(trackingStartedListener: TrackingStartedListener) - /** * Disables the shade header. * @@ -250,17 +244,3 @@ interface ShadeViewStateProvider { /** Return the fraction of the shade that's expanded, when in lockscreen. */ val lockscreenShadeDragProgress: Float } - -/** Listens for when touch tracking begins. */ -interface TrackingStartedListener { - fun onTrackingStarted() -} - -/** Listens for when shade begins opening or finishes closing. */ -interface OpenCloseListener { - /** Called when the shade finishes closing. */ - fun onClosingFinished() - - /** Called when the shade starts opening. */ - fun onOpenStarted() -} diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt index 6e036863216b..23680bb66086 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewControllerEmptyImpl.kt @@ -43,10 +43,8 @@ class ShadeViewControllerEmptyImpl @Inject constructor() : override val isFullyCollapsed: Boolean = false override val isTracking: Boolean = false override val isViewEnabled: Boolean = false - override fun setOpenCloseListener(openCloseListener: OpenCloseListener) {} override fun shouldHideStatusBarIconsWhenExpanded() = false override fun blockExpansionForCurrentTouch() {} - override fun setTrackingStartedListener(trackingStartedListener: TrackingStartedListener) {} override fun disableHeader(state1: Int, state2: Int, animated: Boolean) {} override fun startExpandLatencyTracking() {} override fun startBouncerPreHideAnimation() {} diff --git a/packages/SystemUI/src/com/android/systemui/shade/StartShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/StartShadeModule.kt index 15ec18c528b6..c4de78b8a28e 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/StartShadeModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/StartShadeModule.kt @@ -18,6 +18,7 @@ package com.android.systemui.shade import com.android.systemui.CoreStartable import com.android.systemui.biometrics.AuthRippleController +import com.android.systemui.shade.domain.startable.ShadeStartable import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey @@ -34,4 +35,9 @@ internal abstract class StartShadeModule { @IntoMap @ClassKey(AuthRippleController::class) abstract fun bindAuthRippleController(controller: AuthRippleController): CoreStartable + + @Binds + @IntoMap + @ClassKey(ShadeStartable::class) + abstract fun provideShadeStartable(startable: ShadeStartable): CoreStartable } diff --git a/packages/SystemUI/src/com/android/systemui/shade/TrackingStartedListener.kt b/packages/SystemUI/src/com/android/systemui/shade/TrackingStartedListener.kt new file mode 100644 index 000000000000..3803c27d5f37 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/TrackingStartedListener.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 com.android.systemui.shade + +/** Listens for when touch tracking begins. */ +interface TrackingStartedListener { + fun onTrackingStarted() +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt index e5ff9778fed4..5c79e1ee84f3 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt @@ -16,6 +16,7 @@ package com.android.systemui.shade.data.repository import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.shade.shared.model.ShadeMode import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -100,12 +101,16 @@ interface ShadeRepository { @Deprecated("Use ShadeInteractor.isQsBypassingShade instead") val legacyExpandImmediate: StateFlow<Boolean> + val shadeMode: StateFlow<ShadeMode> + /** True when QS is taking up the entire screen, i.e. fully expanded on a non-unfolded phone. */ @Deprecated("Use ShadeInteractor instead") val legacyQsFullscreen: StateFlow<Boolean> /** NPVC.mClosing as a flow. */ @Deprecated("Use ShadeAnimationInteractor instead") val legacyIsClosing: StateFlow<Boolean> + fun setShadeMode(mode: ShadeMode) + /** Sets whether a closing animation is happening. */ @Deprecated("Use ShadeAnimationInteractor instead") fun setLegacyIsClosing(isClosing: Boolean) @@ -214,6 +219,13 @@ class ShadeRepositoryImpl @Inject constructor() : ShadeRepository { @Deprecated("Use ShadeInteractor instead") override val legacyQsFullscreen: StateFlow<Boolean> = _legacyQsFullscreen.asStateFlow() + val _shadeMode = MutableStateFlow<ShadeMode>(ShadeMode.Single) + override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow() + + override fun setShadeMode(shadeMode: ShadeMode) { + _shadeMode.value = shadeMode + } + override fun setLegacyQsFullscreen(legacyQsFullscreen: Boolean) { _legacyQsFullscreen.value = legacyQsFullscreen } diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt index 43ede2aa288d..bc60c838b703 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt @@ -16,6 +16,7 @@ package com.android.systemui.shade.domain.interactor +import com.android.systemui.shade.shared.model.ShadeMode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted @@ -102,6 +103,8 @@ interface BaseShadeInteractor { * animating. */ val isUserInteractingWithQs: Flow<Boolean> + + val shadeMode: StateFlow<ShadeMode> } fun createAnyExpansionFlow( diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt index 55dd6744d44e..e9bb4c623013 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt @@ -17,6 +17,7 @@ package com.android.systemui.shade.domain.interactor import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.shade.shared.model.ShadeMode import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -42,4 +43,5 @@ class ShadeInteractorEmptyImpl @Inject constructor() : ShadeInteractor { override val isUserInteracting: StateFlow<Boolean> = inactiveFlowBoolean override val isShadeTouchable: Flow<Boolean> = inactiveFlowBoolean override val isExpandToQsEnabled: Flow<Boolean> = inactiveFlowBoolean + override val shadeMode: StateFlow<ShadeMode> = MutableStateFlow(ShadeMode.Single) } diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt index 2ac3193d1e8d..6414af36b4dd 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt @@ -21,6 +21,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.shade.data.repository.ShadeRepository +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -99,6 +100,8 @@ constructor( override val isUserInteractingWithQs: Flow<Boolean> = userInteractingFlow(repository.legacyQsTracking, repository.qsExpansion) + override val shadeMode: StateFlow<ShadeMode> = repository.shadeMode + /** * Return a flow for whether a user is interacting with an expandable shade component using * tracking and expansion flows. NOTE: expansion must be a `StateFlow` to guarantee that diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt index 67cac3d4111c..7785eda4bd6a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt @@ -22,6 +22,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.data.repository.ShadeRepository +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -45,6 +47,7 @@ constructor( @Application scope: CoroutineScope, sceneInteractor: SceneInteractor, sharedNotificationContainerInteractor: SharedNotificationContainerInteractor, + shadeRepository: ShadeRepository, ) : BaseShadeInteractor { override val shadeExpansion: Flow<Float> = sceneBasedExpansion(sceneInteractor, Scenes.Shade) @@ -106,6 +109,8 @@ constructor( override val isUserInteractingWithQs: Flow<Boolean> = sceneBasedInteracting(sceneInteractor, Scenes.QuickSettings) + override val shadeMode: StateFlow<ShadeMode> = shadeRepository.shadeMode + /** * Returns a flow that uses scene transition progress to and from a scene that is pulled down * from the top of the screen to a 0-1 expansion amount float. diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt new file mode 100644 index 000000000000..11ce818bbdeb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.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.shade.domain.startable + +import android.content.Context +import com.android.systemui.CoreStartable +import com.android.systemui.common.ui.data.repository.ConfigurationRepository +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.shade.data.repository.ShadeRepository +import com.android.systemui.shade.shared.model.ShadeMode +import com.android.systemui.statusbar.policy.SplitShadeStateController +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.launch + +@SysUISingleton +class ShadeStartable +@Inject +constructor( + @Application private val applicationScope: CoroutineScope, + @Application private val applicationContext: Context, + private val configurationRepository: ConfigurationRepository, + private val shadeRepository: ShadeRepository, + private val controller: SplitShadeStateController, +) : CoreStartable { + + override fun start() { + hydrateShadeMode() + } + + private fun hydrateShadeMode() { + applicationScope.launch { + configurationRepository.onAnyConfigurationChange + // Force initial collection. + .onStart { emit(Unit) } + .map { applicationContext.resources } + .map { resources -> controller.shouldUseSplitNotificationShade(resources) } + .collect { isSplitShade -> + shadeRepository.setShadeMode( + if (isSplitShade) { + ShadeMode.Split + } else { + ShadeMode.Single + } + ) + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt new file mode 100644 index 000000000000..3451eaf54063 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade.shared.model + +/** Enumerates all known modes of operation of the shade. */ +sealed interface ShadeMode { + + /** + * The single or "accordion" shade where the QS and notification parts are in two vertically + * stacked panels and the user can swipe up and down to expand or collapse between the two + * parts. + */ + data object Single : ShadeMode + + /** + * The split shade where, on large screens and unfolded foldables, the QS and notification parts + * are placed side-by-side and expand/collapse as a single panel. + */ + data object Split : ShadeMode + + /** + * The dual shade where the QS and notification parts each have their own independently + * expandable/collapsible panel on either side of the large screen / unfolded device or sharing + * a space on a small screen or folded device. + */ + data object Dual : ShadeMode +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt index c9aa51c31060..ea549f2b7e53 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt @@ -14,18 +14,32 @@ * limitations under the License. */ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.android.systemui.shade.ui.viewmodel +import androidx.lifecycle.LifecycleOwner import com.android.compose.animation.scene.SceneKey +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.SwipeDirection +import com.android.compose.animation.scene.UserAction +import com.android.compose.animation.scene.UserActionResult import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.media.controls.domain.pipeline.MediaDataManager +import com.android.systemui.qs.FooterActionsController +import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel +import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine @@ -43,28 +57,36 @@ constructor( val shadeHeaderViewModel: ShadeHeaderViewModel, val notifications: NotificationsPlaceholderViewModel, val mediaDataManager: MediaDataManager, + shadeInteractor: ShadeInteractor, + private val footerActionsViewModelFactory: FooterActionsViewModel.Factory, + private val footerActionsController: FooterActionsController, ) { - /** The key of the scene we should switch to when swiping up. */ - val upDestinationSceneKey: StateFlow<SceneKey> = + val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> = combine( deviceEntryInteractor.isUnlocked, deviceEntryInteractor.canSwipeToEnter, - ) { isUnlocked, canSwipeToDismiss -> - upDestinationSceneKey( + shadeInteractor.shadeMode, + ) { isUnlocked, canSwipeToDismiss, shadeMode -> + destinationScenes( isUnlocked = isUnlocked, canSwipeToDismiss = canSwipeToDismiss, + shadeMode = shadeMode, ) } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), initialValue = - upDestinationSceneKey( + destinationScenes( isUnlocked = deviceEntryInteractor.isUnlocked.value, canSwipeToDismiss = deviceEntryInteractor.canSwipeToEnter.value, + shadeMode = shadeInteractor.shadeMode.value, ), ) + private val upDestinationSceneKey: Flow<SceneKey?> = + destinationScenes.map { it[Swipe(SwipeDirection.Up)]?.toScene } + /** Whether or not the shade container should be clickable. */ val isClickable: StateFlow<Boolean> = upDestinationSceneKey @@ -75,22 +97,42 @@ constructor( initialValue = false ) + val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode + /** Notifies that some content in the shade was clicked. */ fun onContentClicked() = deviceEntryInteractor.attemptDeviceEntry() - private fun upDestinationSceneKey( - isUnlocked: Boolean, - canSwipeToDismiss: Boolean?, - ): SceneKey { - return when { - canSwipeToDismiss == true -> Scenes.Lockscreen - isUnlocked -> Scenes.Gone - else -> Scenes.Lockscreen - } - } - fun isMediaVisible(): Boolean { // TODO(b/296122467): handle updates to carousel visibility while scene is still visible return mediaDataManager.hasActiveMediaOrRecommendation() } + + private val footerActionsControllerInitialized = AtomicBoolean(false) + + fun getFooterActionsViewModel(lifecycleOwner: LifecycleOwner): FooterActionsViewModel { + if (footerActionsControllerInitialized.compareAndSet(false, true)) { + footerActionsController.init() + } + return footerActionsViewModelFactory.create(lifecycleOwner) + } + + private fun destinationScenes( + isUnlocked: Boolean, + canSwipeToDismiss: Boolean?, + shadeMode: ShadeMode, + ): Map<UserAction, UserActionResult> { + val up = + when { + canSwipeToDismiss == true -> Scenes.Lockscreen + isUnlocked -> Scenes.Gone + else -> Scenes.Lockscreen + } + + val down = Scenes.QuickSettings.takeIf { shadeMode is ShadeMode.Single } + + return buildMap { + this[Swipe(SwipeDirection.Up)] = UserActionResult(up) + down?.let { this[Swipe(SwipeDirection.Down)] = UserActionResult(down) } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java index deaf1d1bc764..dfb0f9bb2a87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java @@ -367,7 +367,8 @@ public class PreparationCoordinator implements Coordinator { /* reason = */ reason, /* showSnooze = */ adjustment.isSnoozeEnabled(), /* isChildInGroup = */ adjustment.isChildInGroup(), - /* isGroupSummary = */ adjustment.isGroupSummary() + /* isGroupSummary = */ adjustment.isGroupSummary(), + /* needsRedaction = */ adjustment.getNeedsRedaction() ); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt index 18460c3e3766..7b8a062ec446 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt @@ -61,5 +61,6 @@ interface NotifInflater { val showSnooze: Boolean, val isChildInGroup: Boolean = false, val isGroupSummary: Boolean = false, + val needsRedaction: Boolean, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt index 0b9d19df3a75..e0e5a3578c31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt @@ -22,6 +22,7 @@ import android.os.Handler import android.os.HandlerExecutor import android.os.UserHandle import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE +import com.android.server.notification.Flags.screenshareNotificationHiding import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.settings.UserTracker @@ -30,6 +31,7 @@ import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager +import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.util.ListenerSet import com.android.systemui.util.settings.SecureSettings import javax.inject.Inject @@ -43,6 +45,7 @@ class NotifUiAdjustmentProvider @Inject constructor( @Main private val handler: Handler, private val secureSettings: SecureSettings, private val lockscreenUserManager: NotificationLockscreenUserManager, + private val sensitiveNotifProtectionController: SensitiveNotificationProtectionController, private val sectionStyleProvider: SectionStyleProvider, private val userTracker: UserTracker, private val groupMembershipManager: GroupMembershipManager, @@ -66,6 +69,11 @@ class NotifUiAdjustmentProvider @Inject constructor( fun addDirtyListener(listener: Runnable) { if (dirtyListeners.isEmpty()) { lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener) + if (screenshareNotificationHiding()) { + sensitiveNotifProtectionController.registerSensitiveStateListener( + onSensitiveStateChangedListener + ) + } updateSnoozeEnabled() secureSettings.registerContentObserverForUser( SHOW_NOTIFICATION_SNOOZE, @@ -80,6 +88,11 @@ class NotifUiAdjustmentProvider @Inject constructor( dirtyListeners.remove(listener) if (dirtyListeners.isEmpty()) { lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener) + if (screenshareNotificationHiding()) { + sensitiveNotifProtectionController.unregisterSensitiveStateListener( + onSensitiveStateChangedListener + ) + } secureSettings.unregisterContentObserver(settingsObserver) } } @@ -89,6 +102,8 @@ class NotifUiAdjustmentProvider @Inject constructor( dirtyListeners.forEach(Runnable::run) } + private val onSensitiveStateChangedListener = Runnable { dirtyListeners.forEach(Runnable::run) } + private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean) { updateSnoozeEnabled() @@ -122,7 +137,10 @@ class NotifUiAdjustmentProvider @Inject constructor( isConversation = entry.ranking.isConversation, isSnoozeEnabled = isSnoozeSettingsEnabled && !entry.isCanceled, isMinimized = isEntryMinimized(entry), - needsRedaction = lockscreenUserManager.needsRedaction(entry), + needsRedaction = + lockscreenUserManager.needsRedaction(entry) || + (screenshareNotificationHiding() && + sensitiveNotifProtectionController.shouldProtectNotification(entry)), isChildInGroup = entry.sbn.isAppOrSystemGroupChild, isGroupSummary = entry.sbn.isAppOrSystemGroupSummary, ) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index c5b55c7b1d9b..6400ff6b5c24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -254,11 +254,9 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight); params.setUseLowPriority(isLowPriority); - // If screenshareNotificationHiding is enabled, both public and private views should be - // inflated to avoid any latency associated with reinflating all notification views when - // screen share starts and stops if (screenshareNotificationHiding() - || mNotificationLockscreenUserManager.needsRedaction(entry)) { + ? inflaterParams.getNeedsRedaction() + : mNotificationLockscreenUserManager.needsRedaction(entry)) { params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC); } else { params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 38f21eebea41..b20507117558 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -928,12 +928,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } void updateSidePadding(int viewWidth) { - final boolean portrait = - getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; + final int orientation = getResources().getConfiguration().orientation; mLastUpdateSidePaddingDumpString = "viewWidth=" + viewWidth + " skinnyNotifsInLandscape=" + mSkinnyNotifsInLandscape - + " portrait=" + portrait; + + " orientation=" + orientation; if (DEBUG_UPDATE_SIDE_PADDING) { Log.v(TAG, "updateSidePadding: " + mLastUpdateSidePaddingDumpString); @@ -945,7 +944,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } // Portrait is easy, just use the dimen for paddings - if (portrait) { + if (orientation == Configuration.ORIENTATION_PORTRAIT) { mSidePaddings = mMinimumPaddings; return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 382de3fd6dac..6553193fc980 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -363,7 +363,8 @@ public class NotificationStackScrollLayoutController implements Dumpable { }; private NotifStats mNotifStats = NotifStats.getEmpty(); - private float mMaxAlphaForExpansion = 1.0f; + private float mMaxAlphaForKeyguard = 1.0f; + private String mMaxAlphaForKeyguardSource = "constructor"; private float mMaxAlphaForUnhide = 1.0f; /** @@ -1320,9 +1321,14 @@ public class NotificationStackScrollLayoutController implements Dumpable { return mView.getEmptyShadeViewHeight(); } - public void setMaxAlphaForExpansion(float alpha) { - mMaxAlphaForExpansion = alpha; + /** Set the max alpha for keyguard */ + public void setMaxAlphaForKeyguard(float alpha, String source) { + mMaxAlphaForKeyguard = alpha; + mMaxAlphaForKeyguardSource = source; updateAlpha(); + if (DEBUG) { + Log.d(TAG, "setMaxAlphaForKeyguard=" + alpha + " --- from: " + source); + } } private void setMaxAlphaForUnhide(float alpha) { @@ -1341,7 +1347,7 @@ public class NotificationStackScrollLayoutController implements Dumpable { private void updateAlpha() { if (mView != null) { - mView.setAlpha(Math.min(mMaxAlphaForExpansion, + mView.setAlpha(Math.min(mMaxAlphaForKeyguard, Math.min(mMaxAlphaForUnhide, mMaxAlphaForGlanceableHub))); } } @@ -1831,9 +1837,10 @@ public class NotificationStackScrollLayoutController implements Dumpable { @Override public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { - pw.println("mMaxAlphaForExpansion=" + mMaxAlphaForExpansion); pw.println("mMaxAlphaForUnhide=" + mMaxAlphaForUnhide); pw.println("mMaxAlphaForGlanceableHub=" + mMaxAlphaForGlanceableHub); + pw.println("mMaxAlphaForKeyguard=" + mMaxAlphaForKeyguard); + pw.println("mMaxAlphaForKeyguardSource=" + mMaxAlphaForKeyguardSource); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt index 76495cb23947..8b1b06eb1453 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt @@ -66,15 +66,18 @@ object NotificationStackAppearanceViewBinder { } launch { + var wasExpanding = false viewModel.expandFraction.collect { expandFraction -> + val nowExpanding = expandFraction != 0f && expandFraction != 1f + if (nowExpanding && !wasExpanding) { + controller.onExpansionStarted() + } ambientState.expansionFraction = expandFraction controller.expandedHeight = expandFraction * controller.view.height - controller.setMaxAlphaForExpansion( - ((expandFraction - 0.5f) / 0.5f).coerceAtLeast(0f) - ) - if (expandFraction == 0f || expandFraction == 1f) { + if (!nowExpanding && wasExpanding) { controller.onExpansionStopped() } + wasExpanding = nowExpanding } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt index 566c0303b286..ece7a7fccc66 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt @@ -106,27 +106,26 @@ object SharedNotificationContainerBinder { val disposableHandleMainImmediate = view.repeatWhenAttached(mainImmediateDispatcher) { repeatOnLifecycle(Lifecycle.State.CREATED) { - if (!sceneContainerFlags.flexiNotifsEnabled()) { - launch { - // Only temporarily needed, until flexi notifs go live - viewModel.shadeCollapseFadeIn.collect { fadeIn -> - if (fadeIn) { - android.animation.ValueAnimator.ofFloat(0f, 1f).apply { - duration = 250 - addUpdateListener { animation -> - controller.setMaxAlphaForExpansion( - animation.getAnimatedFraction() - ) - } - addListener( - object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator) { - viewModel.setShadeCollapseFadeInComplete(true) - } - } + launch { + // Only temporarily needed, until flexi notifs go live + viewModel.shadeCollapseFadeIn.collect { fadeIn -> + if (fadeIn) { + android.animation.ValueAnimator.ofFloat(0f, 1f).apply { + duration = 250 + addUpdateListener { animation -> + controller.setMaxAlphaForKeyguard( + animation.animatedFraction, + "SharedNotificationContainerVB (collapseFadeIn)" ) - start() } + addListener( + object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + viewModel.setShadeCollapseFadeInComplete(true) + } + } + ) + start() } } } @@ -164,13 +163,12 @@ object SharedNotificationContainerBinder { launch { viewModel.translationX.collect { x -> controller.translationX = x } } - if (!sceneContainerFlags.isEnabled()) { - launch { - viewModel.expansionAlpha(viewState).collect { - controller.setMaxAlphaForExpansion(it) - } + launch { + viewModel.keyguardAlpha(viewState).collect { + controller.setMaxAlphaForKeyguard(it, "SharedNotificationContainerVB") } } + launch { viewModel.glanceableHubAlpha.collect { controller.setMaxAlphaForGlanceableHub(it) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt index 3a9cdd2d852e..2745817d6d40 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt @@ -20,7 +20,6 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import com.android.systemui.common.shared.model.NotificationContainerBounds -import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dump.DumpManager @@ -37,8 +36,6 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED -import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING -import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel @@ -97,7 +94,6 @@ constructor( private val keyguardInteractor: KeyguardInteractor, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val shadeInteractor: ShadeInteractor, - communalInteractor: CommunalInteractor, private val alternateBouncerToGoneTransitionViewModel: AlternateBouncerToGoneTransitionViewModel, private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel, @@ -127,22 +123,6 @@ constructor( private val statesForConstrainedNotifications: Set<KeyguardState> = setOf(AOD, LOCKSCREEN, DOZING, ALTERNATE_BOUNCER, PRIMARY_BOUNCER) - private val lockscreenToGlanceableHubRunning = - keyguardTransitionInteractor - .transition(LOCKSCREEN, GLANCEABLE_HUB) - .map { it.transitionState == STARTED || it.transitionState == RUNNING } - .distinctUntilChanged() - .onStart { emit(false) } - .dumpWhileCollecting("lockscreenToGlanceableHubRunning") - - private val glanceableHubToLockscreenRunning = - keyguardTransitionInteractor - .transition(GLANCEABLE_HUB, LOCKSCREEN) - .map { it.transitionState == STARTED || it.transitionState == RUNNING } - .distinctUntilChanged() - .onStart { emit(false) } - .dumpWhileCollecting("glanceableHubToLockscreenRunning") - /** * Shade locked is a legacy concept, but necessary to mimic current functionality. Listen for * both SHADE_LOCKED and shade/qs expansion in order to determine lock state, as one can arrive @@ -218,21 +198,38 @@ constructor( ) .dumpValue("isOnLockscreenWithoutShade") + /** If the user is visually on the glanceable hub or transitioning to/from it */ + private val isOnGlanceableHub: Flow<Boolean> = + combine( + keyguardTransitionInteractor.finishedKeyguardState.map { state -> + state == GLANCEABLE_HUB + }, + keyguardTransitionInteractor + .isInTransitionWhere { from, to -> + from == GLANCEABLE_HUB || to == GLANCEABLE_HUB + } + .onStart { emit(false) } + ) { isOnGlanceableHub, transitioningToOrFromHub -> + isOnGlanceableHub || transitioningToOrFromHub + } + .distinctUntilChanged() + .dumpWhileCollecting("isOnGlanceableHub") + /** Are we purely on the glanceable hub without the shade/qs? */ val isOnGlanceableHubWithoutShade: Flow<Boolean> = combine( - communalInteractor.isIdleOnCommunal, + isOnGlanceableHub, // Shade with notifications shadeInteractor.shadeExpansion.map { it > 0f }, // Shade without notifications, quick settings only (pull down from very top on // lockscreen) shadeInteractor.qsExpansion.map { it > 0f }, - ) { isIdleOnCommunal, isShadeVisible, qsExpansion -> - isIdleOnCommunal && !(isShadeVisible || qsExpansion) + ) { isGlanceableHub, isShadeVisible, qsExpansion -> + isGlanceableHub && !(isShadeVisible || qsExpansion) } .stateIn( scope = applicationScope, - started = SharingStarted.WhileSubscribed(), + started = SharingStarted.Eagerly, initialValue = false, ) .dumpWhileCollecting("isOnGlanceableHubWithoutShade") @@ -376,7 +373,7 @@ constructor( } .dumpWhileCollecting("alphaWhenGoneAndShadeState") - fun expansionAlpha(viewState: ViewStateAccessor): Flow<Float> { + fun keyguardAlpha(viewState: ViewStateAccessor): Flow<Float> { // All transition view models are mututally exclusive, and safe to merge val alphaTransitions = merge( @@ -427,43 +424,39 @@ constructor( }, ) .distinctUntilChanged() - .dumpWhileCollecting("expansionAlpha") + .dumpWhileCollecting("keyguardAlpha") } /** - * Returns a flow of the expected alpha while running a LOCKSCREEN<->GLANCEABLE_HUB transition - * or idle on the glanceable hub. + * Returns a flow of the expected alpha while running a LOCKSCREEN<->GLANCEABLE_HUB or + * DREAMING<->GLANCEABLE_HUB transition or idle on the hub. * * Must return 1.0f when not controlling the alpha since notifications does a min of all the * alpha sources. */ val glanceableHubAlpha: Flow<Float> = - isOnGlanceableHubWithoutShade - .flatMapLatest { isOnGlanceableHubWithoutShade -> - combineTransform( - lockscreenToGlanceableHubRunning, - glanceableHubToLockscreenRunning, - merge( - lockscreenToGlanceableHubTransitionViewModel.notificationAlpha, - glanceableHubToLockscreenTransitionViewModel.notificationAlpha, - ) - ) { lockscreenToGlanceableHubRunning, glanceableHubToLockscreenRunning, alpha -> - if (isOnGlanceableHubWithoutShade) { - // Notifications should not be visible on the glanceable hub. - // TODO(b/321075734): implement a way to actually set the notifications to - // gone - // while on the hub instead of just adjusting alpha - emit(0f) - } else if ( - lockscreenToGlanceableHubRunning || glanceableHubToLockscreenRunning - ) { - emit(alpha) - } else { - // Not on the hub and no transitions running, return full visibility so we - // don't - // block the notifications from showing. - emit(1f) - } + combineTransform( + isOnGlanceableHubWithoutShade, + isOnLockscreen, + merge( + lockscreenToGlanceableHubTransitionViewModel.notificationAlpha, + glanceableHubToLockscreenTransitionViewModel.notificationAlpha, + ) + ) { isOnGlanceableHubWithoutShade, isOnLockscreen, alpha, + -> + if (isOnGlanceableHubWithoutShade && !isOnLockscreen) { + // Notifications should not be visible on the glanceable hub. + // TODO(b/321075734): implement a way to actually set the notifications to + // gone while on the hub instead of just adjusting alpha + emit(0f) + } else if (isOnGlanceableHubWithoutShade) { + // We are transitioning between hub and lockscreen, so set the alpha for the + // transition animation. + emit(alpha) + } else { + // Not on the hub and no transitions running, return full visibility so we + // don't block the notifications from showing. + emit(1f) } } .dumpWhileCollecting("glanceableHubAlpha") diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt index 23a080b7b931..a55de251314f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt @@ -648,6 +648,10 @@ constructor( } if (intent.isActivity) { assistManagerLazy.get().hideAssist() + // This activity could have started while the device is dreaming, in which case + // the dream would occlude the activity. In order to show the newly started + // activity, we wake from the dream. + keyguardUpdateMonitor.awakenFromDream() } intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt index efdce062bb37..016ba5fddcbd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt @@ -55,7 +55,7 @@ class CarrierConfigRepository @Inject constructor( broadcastDispatcher: BroadcastDispatcher, - private val carrierConfigManager: CarrierConfigManager, + private val carrierConfigManager: CarrierConfigManager?, dumpManager: DumpManager, logger: MobileInputLogger, @Application scope: CoroutineScope, @@ -87,7 +87,7 @@ constructor( .onEach { logger.logCarrierConfigChanged(it) } .filter { SubscriptionManager.isValidSubscriptionId(it) } .mapNotNull { subId -> - val config = carrierConfigManager.getConfigForSubId(subId) + val config = carrierConfigManager?.getConfigForSubId(subId) config?.let { subId to it } } .shareIn(scope, SharingStarted.WhileSubscribed()) @@ -111,7 +111,7 @@ constructor( fun getOrCreateConfigForSubId(subId: Int): SystemUiCarrierConfig { return configs.getOrElse(subId) { val config = SystemUiCarrierConfig(subId, defaultConfig) - val carrierConfig = carrierConfigManager.getConfigForSubId(subId) + val carrierConfig = carrierConfigManager?.getConfigForSubId(subId) if (carrierConfig != null) config.processNewCarrierConfig(carrierConfig) configs.put(subId, config) config diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt index 859e636a7714..213324a81db3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt @@ -26,6 +26,15 @@ import javax.inject.Inject * based solely on resources, no extra flag logic. */ class ResourcesSplitShadeStateController @Inject constructor() : SplitShadeStateController { + + @Deprecated( + message = "This is deprecated, please use ShadeInteractor#isSplitShade instead", + replaceWith = + ReplaceWith( + "shadeInteractor.isSplitShade", + "com.android.systemui.shade.domain.interactor.ShadeInteractor", + ), + ) override fun shouldUseSplitNotificationShade(resources: Resources): Boolean { return resources.getBoolean(R.bool.config_use_split_notification_shade) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt index f64d4c67ea23..d120a1bd3840 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateController.kt @@ -19,6 +19,15 @@ import android.content.res.Resources /** Source of truth for split shade state: should or should not use split shade. */ interface SplitShadeStateController { + /** Returns true if the device should use the split notification shade. */ + @Deprecated( + message = "This is deprecated, please use ShadeInteractor#isSplitShade instead", + replaceWith = + ReplaceWith( + "shadeInteractor.isSplitShade", + "com.android.systemui.shade.domain.interactor.ShadeInteractor", + ), + ) fun shouldUseSplitNotificationShade(resources: Resources): Boolean } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt index 43905c593bdc..5c5b17e6af42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt @@ -16,10 +16,10 @@ package com.android.systemui.statusbar.policy import android.content.res.Resources -import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.res.R import javax.inject.Inject /** @@ -29,10 +29,15 @@ import javax.inject.Inject @SysUISingleton class SplitShadeStateControllerImpl @Inject constructor(private val featureFlags: FeatureFlags) : SplitShadeStateController { - /** - * Returns true if the device should use the split notification shade. Based on orientation, - * screen width, and flags. - */ + + @Deprecated( + message = "This is deprecated, please use ShadeInteractor#isSplitShade instead", + replaceWith = + ReplaceWith( + "shadeInteractor.isSplitShade", + "com.android.systemui.shade.domain.interactor.ShadeInteractor", + ), + ) override fun shouldUseSplitNotificationShade(resources: Resources): Boolean { return (resources.getBoolean(R.bool.config_use_split_notification_shade) || (featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE) && diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt index 5c53ff98b777..ac1d2803835a 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt @@ -16,6 +16,8 @@ package com.android.systemui.unfold +import android.animation.Animator +import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.annotation.BinderThread import android.content.Context @@ -23,7 +25,6 @@ import android.os.Handler import android.os.SystemProperties import android.util.Log import android.view.animation.DecelerateInterpolator -import androidx.core.animation.addListener import com.android.internal.foldables.FoldLockSettingAvailabilityProvider import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.display.data.repository.DeviceStateRepository @@ -36,17 +37,25 @@ import com.android.systemui.unfold.FullscreenLightRevealAnimationController.Comp import com.android.systemui.unfold.dagger.UnfoldBg import com.android.systemui.util.animation.data.repository.AnimationStatusRepository import javax.inject.Inject +import kotlin.coroutines.resume import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.android.asCoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withTimeout +@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) class FoldLightRevealOverlayAnimation @Inject constructor( @@ -61,6 +70,9 @@ constructor( private val revealProgressValueAnimator: ValueAnimator = ValueAnimator.ofFloat(ALPHA_OPAQUE, ALPHA_TRANSPARENT) + private val areAnimationEnabled: Flow<Boolean> + get() = animationStatusRepository.areAnimationsEnabled() + private lateinit var controller: FullscreenLightRevealAnimationController @Volatile private var readyCallback: CompletableDeferred<Runnable>? = null @@ -89,33 +101,31 @@ constructor( applicationScope.launch(bgHandler.asCoroutineDispatcher()) { deviceStateRepository.state - .map { it != DeviceStateRepository.DeviceState.FOLDED } + .map { it == DeviceStateRepository.DeviceState.FOLDED } .distinctUntilChanged() - .filter { isUnfolded -> isUnfolded } - .collect { controller.ensureOverlayRemoved() } - } - - applicationScope.launch(bgHandler.asCoroutineDispatcher()) { - deviceStateRepository.state - .filter { - animationStatusRepository.areAnimationsEnabled().first() && - it == DeviceStateRepository.DeviceState.FOLDED - } - .collect { - try { - withTimeout(WAIT_FOR_ANIMATION_TIMEOUT_MS) { - readyCallback = CompletableDeferred() - val onReady = readyCallback?.await() - readyCallback = null - controller.addOverlay(ALPHA_OPAQUE, onReady) - waitForScreenTurnedOn() + .flatMapLatest { isFolded -> + flow<Nothing> { + if (!areAnimationEnabled.first() || !isFolded) { + return@flow + } + withTimeout(WAIT_FOR_ANIMATION_TIMEOUT_MS) { + readyCallback = CompletableDeferred() + val onReady = readyCallback?.await() + readyCallback = null + controller.addOverlay(ALPHA_OPAQUE, onReady) + waitForScreenTurnedOn() + } playFoldLightRevealOverlayAnimation() } - } catch (e: TimeoutCancellationException) { - Log.e(TAG, "Fold light reveal animation timed out") - ensureOverlayRemovedInternal() - } + .catchTimeoutAndLog() + .onCompletion { + controller.ensureOverlayRemoved() + val onReady = readyCallback?.takeIf { it.isCompleted }?.getCompleted() + onReady?.run() + readyCallback = null + } } + .collect {} } } @@ -128,19 +138,34 @@ constructor( powerInteractor.screenPowerState.filter { it == ScreenPowerState.SCREEN_ON }.first() } - private fun ensureOverlayRemovedInternal() { - revealProgressValueAnimator.cancel() - controller.ensureOverlayRemoved() - } - - private fun playFoldLightRevealOverlayAnimation() { + private suspend fun playFoldLightRevealOverlayAnimation() { revealProgressValueAnimator.duration = ANIMATION_DURATION revealProgressValueAnimator.interpolator = DecelerateInterpolator() revealProgressValueAnimator.addUpdateListener { animation -> controller.updateRevealAmount(animation.animatedFraction) } - revealProgressValueAnimator.addListener(onEnd = { controller.ensureOverlayRemoved() }) - revealProgressValueAnimator.start() + revealProgressValueAnimator.startAndAwaitCompletion() + } + + private suspend fun ValueAnimator.startAndAwaitCompletion(): Unit = + suspendCancellableCoroutine { continuation -> + val listener = + object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + continuation.resume(Unit) + removeListener(this) + } + } + addListener(listener) + continuation.invokeOnCancellation { removeListener(listener) } + start() + } + + private fun <T> Flow<T>.catchTimeoutAndLog() = catch { exception -> + when (exception) { + is TimeoutCancellationException -> Log.e(TAG, "Fold light reveal animation timed out") + else -> throw exception + } } private companion object { diff --git a/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java b/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java index a925e384d3be..f755feb7aa44 100644 --- a/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java +++ b/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java @@ -27,6 +27,7 @@ import android.util.ArraySet; import android.util.SparseBooleanArray; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.internal.telephony.TelephonyIntents; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -72,7 +73,7 @@ public class CarrierConfigTracker @Inject public CarrierConfigTracker( - CarrierConfigManager carrierConfigManager, + @Nullable CarrierConfigManager carrierConfigManager, BroadcastDispatcher broadcastDispatcher) { mCarrierConfigManager = carrierConfigManager; IntentFilter filter = new IntentFilter(); @@ -95,6 +96,9 @@ public class CarrierConfigTracker final int subId = intent.getIntExtra( CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.INVALID_SUBSCRIPTION_ID); + if (mCarrierConfigManager == null) { + return; + } if (!SubscriptionManager.isValidSubscriptionId(subId)) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index deec215865b2..c3274477862a 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -173,6 +173,9 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, private static final String TYPE_DISMISS = "dismiss"; /** Volume dialog slider animation. */ private static final String TYPE_UPDATE = "update"; + static final short PROGRESS_HAPTICS_DISABLED = 0; + static final short PROGRESS_HAPTICS_EAGER = 1; + static final short PROGRESS_HAPTICS_ANIMATED = 2; /** * TODO(b/290612381): remove lingering animations or tolerate them @@ -2077,14 +2080,17 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, if (row.anim == null) { row.anim = ObjectAnimator.ofInt(row.slider, "progress", progress, newProgress); row.anim.setInterpolator(new DecelerateInterpolator()); - row.anim.addListener( - getJankListener(row.view, TYPE_UPDATE, UPDATE_ANIMATION_DURATION)); + Animator.AnimatorListener listener = + getJankListener(row.view, TYPE_UPDATE, UPDATE_ANIMATION_DURATION); + if (listener != null) { + row.anim.addListener(listener); + } } else { row.anim.cancel(); row.anim.setIntValues(progress, newProgress); // The animator can't keep up with the volume changes so haptics need to be // triggered here. This happens when the volume keys are continuously pressed. - row.deliverOnProgressChangedHaptics(false, newProgress); + row.deliverOnProgressChangedHaptics(false, newProgress, PROGRESS_HAPTICS_EAGER); } row.animTargetProgress = newProgress; row.anim.setDuration(UPDATE_ANIMATION_DURATION); @@ -2099,6 +2105,15 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, } } + @VisibleForTesting short progressHapticsForStream(int stream) { + for (VolumeRow row: mRows) { + if (row.stream == stream) { + return row.mProgressHapticsType; + } + } + return PROGRESS_HAPTICS_DISABLED; + } + private void recheckH(VolumeRow row) { if (row == null) { if (D.BUG) Log.d(TAG, "recheckH ALL"); @@ -2486,13 +2501,12 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mRow.ss == null) return; - if (getActiveRow().equals(mRow) - && mRow.slider.getVisibility() == VISIBLE - && mRow.mHapticPlugin != null) { + if (getActiveRow().equals(mRow) && mRow.slider.getVisibility() == VISIBLE) { if (fromUser || mRow.animTargetProgress == progress) { - // Deliver user-generated slider changes immediately, or when the animation + // Deliver user-generated slider haptics immediately, or when the animation // completes - mRow.deliverOnProgressChangedHaptics(fromUser, progress); + mRow.deliverOnProgressChangedHaptics( + fromUser, progress, PROGRESS_HAPTICS_ANIMATED); } } if (D.BUG) Log.d(TAG, AudioSystem.streamToString(mRow.stream) @@ -2605,6 +2619,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, private int animTargetProgress; private int lastAudibleLevel = 1; private SeekableSliderHapticPlugin mHapticPlugin; + private short mProgressHapticsType = PROGRESS_HAPTICS_DISABLED; void setIcon(int iconRes, Resources.Theme theme) { if (icon != null) { @@ -2646,12 +2661,15 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable, slider.setOnTouchListener(null); } - void deliverOnProgressChangedHaptics(boolean fromUser, int progress) { + void deliverOnProgressChangedHaptics(boolean fromUser, int progress, short hapticsType) { + if (mHapticPlugin == null) return; + mHapticPlugin.onProgressChanged(slider, progress, fromUser); if (!fromUser) { // Consider a change from program as the volume key being continuously pressed mHapticPlugin.onKeyDown(); } + mProgressHapticsType = hapticsType; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 0bd4cbec64dd..184924596341 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -93,11 +93,11 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.dreams.ui.viewmodel.DreamViewModel; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.SystemPropertiesHelper; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; -import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.log.SessionTracker; import com.android.systemui.navigationbar.NavigationModeController; @@ -220,7 +220,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private boolean mKeyguardGoingAway = false; private @Mock CoroutineDispatcher mDispatcher; - private @Mock DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel; + private @Mock DreamViewModel mDreamViewModel; private @Mock SystemPropertiesHelper mSystemPropertiesHelper; private @Mock SceneContainerFlags mSceneContainerFlags; @@ -241,9 +241,9 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { final ViewRootImpl testViewRoot = mock(ViewRootImpl.class); when(testViewRoot.getView()).thenReturn(mock(View.class)); when(mStatusBarKeyguardViewManager.getViewRootImpl()).thenReturn(testViewRoot); - when(mDreamingToLockscreenTransitionViewModel.getDreamOverlayAlpha()) + when(mDreamViewModel.getDreamAlpha()) .thenReturn(mock(Flow.class)); - when(mDreamingToLockscreenTransitionViewModel.getTransitionEnded()) + when(mDreamViewModel.getTransitionEnded()) .thenReturn(mock(Flow.class)); when(mSelectedUserInteractor.getSelectedUserId()).thenReturn(mDefaultUserId); when(mSelectedUserInteractor.getSelectedUserId(anyBoolean())).thenReturn(mDefaultUserId); @@ -1259,7 +1259,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mSystemSettings, mSystemClock, mDispatcher, - () -> mDreamingToLockscreenTransitionViewModel, + () -> mDreamViewModel, mSystemPropertiesHelper, () -> mock(WindowManagerLockscreenVisibilityManager.class), mSelectedUserInteractor, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt index 22a2e93eb10d..f252163ee332 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt @@ -130,6 +130,24 @@ class KeyguardClockViewModelTest : SysuiTestCase() { assertThat(value()).isEqualTo(LARGE) } + @Test + fun isLargeClockVisible_whenLargeClockSize_isTrue() = + scope.runTest { + fakeSettings.putInt(LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1) + keyguardClockRepository.setClockSize(LARGE) + var value = collectLastValue(underTest.isLargeClockVisible) + assertThat(value()).isEqualTo(true) + } + + @Test + fun isLargeClockVisible_whenSmallClockSize_isFalse() = + scope.runTest { + fakeSettings.putInt(LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1) + keyguardClockRepository.setClockSize(SMALL) + var value = collectLastValue(underTest.isLargeClockVisible) + assertThat(value()).isEqualTo(false) + } + private fun setupMockClock() { whenever(clock.largeClock).thenReturn(largeClock) whenever(largeClock.config).thenReturn(clockFaceConfig) diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt index 3dc90374206a..0baee5dd0e9d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt @@ -274,8 +274,8 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback) screenshotExecutor.onCloseSystemDialogsReceived() - verify(controller0).dismissScreenshot(any()) - verify(controller1).dismissScreenshot(any()) + verify(controller0).requestDismissal(any()) + verify(controller1).requestDismissal(any()) screenshotExecutor.onDestroy() } @@ -290,8 +290,8 @@ class TakeScreenshotExecutorTest : SysuiTestCase() { screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback) screenshotExecutor.onCloseSystemDialogsReceived() - verify(controller0, never()).dismissScreenshot(any()) - verify(controller1).dismissScreenshot(any()) + verify(controller0, never()).requestDismissal(any()) + verify(controller1).requestDismissal(any()) screenshotExecutor.onDestroy() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt index 62d2d0efe24c..07d93508228e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt @@ -42,6 +42,7 @@ import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever @@ -76,6 +77,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor @Mock private lateinit var shadeInteractor: ShadeInteractor @Mock private lateinit var powerManager: PowerManager + @Mock private lateinit var dialogFactory: SystemUIDialogFactory private lateinit var parentView: FrameLayout private lateinit var containerView: View @@ -99,6 +101,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { GlanceableHubContainerController( communalInteractor, communalViewModel, + dialogFactory, keyguardTransitionInteractor, shadeInteractor, powerManager @@ -138,6 +141,7 @@ class GlanceableHubContainerControllerTest : SysuiTestCase() { GlanceableHubContainerController( communalInteractor, communalViewModel, + dialogFactory, keyguardTransitionInteractor, shadeInteractor, powerManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index d24fe1b16ef9..6d5d5be8ae57 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -854,7 +854,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo // We are interested in the last value of the stack alpha. ArgumentCaptor<Float> alphaCaptor = ArgumentCaptor.forClass(Float.class); verify(mNotificationStackScrollLayoutController, atLeastOnce()) - .setMaxAlphaForExpansion(alphaCaptor.capture()); + .setMaxAlphaForKeyguard(alphaCaptor.capture(), any()); assertThat(alphaCaptor.getValue()).isEqualTo(1.0f); } @@ -875,7 +875,7 @@ public class NotificationPanelViewControllerTest extends NotificationPanelViewCo // We are interested in the last value of the stack alpha. ArgumentCaptor<Float> alphaCaptor = ArgumentCaptor.forClass(Float.class); verify(mNotificationStackScrollLayoutController, atLeastOnce()) - .setMaxAlphaForExpansion(alphaCaptor.capture()); + .setMaxAlphaForKeyguard(alphaCaptor.capture(), any()); assertThat(alphaCaptor.getValue()).isEqualTo(0.0f); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java index 4519ba6d3590..419b0fd2f89b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java @@ -68,6 +68,7 @@ import com.android.systemui.statusbar.notification.collection.provider.SectionSt import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn; import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager; +import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController; import com.android.systemui.util.settings.SecureSettings; import org.junit.Before; @@ -107,6 +108,7 @@ public class PreparationCoordinatorTest extends SysuiTestCase { @Mock private IStatusBarService mService; @Mock private BindEventManagerImpl mBindEventManagerImpl; @Mock private NotificationLockscreenUserManager mLockscreenUserManager; + @Mock private SensitiveNotificationProtectionController mSensitiveNotifProtectionController; @Mock private Handler mHandler; @Mock private SecureSettings mSecureSettings; @Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater(); @@ -128,6 +130,7 @@ public class PreparationCoordinatorTest extends SysuiTestCase { mHandler, mSecureSettings, mLockscreenUserManager, + mSensitiveNotifProtectionController, mSectionStyleProvider, mUserTracker, mGroupMembershipManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt index 115a0d367e87..34eeba05906a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt @@ -23,6 +23,7 @@ import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest +import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING import com.android.systemui.SysuiTestCase import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.NotificationLockscreenUserManager @@ -33,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.provider.SectionSt import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation +import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock @@ -57,6 +59,8 @@ import org.mockito.Mockito.`when` as whenever @RunWithLooper class NotifUiAdjustmentProviderTest : SysuiTestCase() { private val lockscreenUserManager: NotificationLockscreenUserManager = mock() + private val sensitiveNotifProtectionController: SensitiveNotificationProtectionController = + mock() private val sectionStyleProvider: SectionStyleProvider = mock() private val handler: Handler = mock() private val secureSettings: SecureSettings = mock() @@ -77,6 +81,7 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { handler, secureSettings, lockscreenUserManager, + sensitiveNotifProtectionController, sectionStyleProvider, userTracker, groupMembershipManager, @@ -108,6 +113,19 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { } @Test + @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) + fun sensitiveNotifProtectionStateChangeWillNotifDirty() { + val dirtyListener = mock<Runnable>() + adjustmentProvider.addDirtyListener(dirtyListener) + val sensitiveStateChangedListener = + withArgCaptor<Runnable> { + verify(sensitiveNotifProtectionController).registerSensitiveStateListener(capture()) + } + sensitiveStateChangedListener.run() + verify(dirtyListener).run() + } + + @Test fun additionalAddDoesNotRegisterAgain() { clearInvocations(secureSettings) adjustmentProvider.addDirtyListener(mock()) @@ -199,4 +217,38 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { // Then: Need re-inflation assertTrue(NotifUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) } + + @Test + @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) + fun changeSensitiveNotifProtection_screenshareNotificationHidingEnabled_needReinflate() { + whenever(sensitiveNotifProtectionController.shouldProtectNotification(entry)) + .thenReturn(false) + val oldAdjustment: NotifUiAdjustment = adjustmentProvider.calculateAdjustment(entry) + assertFalse(oldAdjustment.needsRedaction) + + whenever(sensitiveNotifProtectionController.shouldProtectNotification(entry)) + .thenReturn(true) + val newAdjustment = adjustmentProvider.calculateAdjustment(entry) + assertTrue(newAdjustment.needsRedaction) + + // Then: need re-inflation + assertTrue(NotifUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) + } + + @Test + @DisableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) + fun changeSensitiveNotifProtection_screenshareNotificationHidingDisabled_noNeedReinflate() { + whenever(sensitiveNotifProtectionController.shouldProtectNotification(entry)) + .thenReturn(false) + val oldAdjustment = adjustmentProvider.calculateAdjustment(entry) + assertFalse(oldAdjustment.needsRedaction) + + whenever(sensitiveNotifProtectionController.shouldProtectNotification(entry)) + .thenReturn(true) + val newAdjustment = adjustmentProvider.calculateAdjustment(entry) + assertFalse(newAdjustment.needsRedaction) + + // Then: need no re-inflation + assertFalse(NotifUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java index 56fc7b9d818f..1748cffcddda 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java @@ -22,6 +22,7 @@ import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; +import static com.android.systemui.Flags.FLAG_UPDATE_USER_SWITCHER_BACKGROUND; import static com.google.common.truth.Truth.assertThat; @@ -38,6 +39,8 @@ import static org.mockito.Mockito.when; import android.os.UserHandle; import android.os.UserManager; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -226,9 +229,11 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { } @Test - public void onViewAttached_callbacksRegistered() { + @EnableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND) + public void onViewAttached_updateUserSwitcherFlagEnabled_callbacksRegistered() { mController.onViewAttached(); + runAllScheduled(); verify(mConfigurationController).addCallback(any()); verify(mAnimationScheduler).addCallback(any()); verify(mUserInfoController).addCallback(any()); @@ -238,7 +243,39 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { } @Test - public void onConfigurationChanged_updatesUserSwitcherVisibility() { + @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND) + public void onViewAttached_updateUserSwitcherFlagDisabled_callbacksRegistered() { + mController.onViewAttached(); + + verify(mConfigurationController).addCallback(any()); + verify(mAnimationScheduler).addCallback(any()); + verify(mUserInfoController).addCallback(any()); + verify(mCommandQueue).addCallback(any()); + verify(mStatusBarIconController).addIconGroup(any()); + verify(mUserManager).isUserSwitcherEnabled(anyBoolean()); + } + + @Test + @EnableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND) + public void + onConfigurationChanged_updateUserSwitcherFlagEnabled_updatesUserSwitcherVisibility() { + mController.onViewAttached(); + runAllScheduled(); + verify(mConfigurationController).addCallback(mConfigurationListenerCaptor.capture()); + clearInvocations(mUserManager); + clearInvocations(mKeyguardStatusBarView); + + mConfigurationListenerCaptor.getValue().onConfigChanged(null); + + runAllScheduled(); + verify(mUserManager).isUserSwitcherEnabled(anyBoolean()); + verify(mKeyguardStatusBarView).setUserSwitcherEnabled(anyBoolean()); + } + + @Test + @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND) + public void + onConfigurationChanged_updateUserSwitcherFlagDisabled_updatesUserSwitcherVisibility() { mController.onViewAttached(); verify(mConfigurationController).addCallback(mConfigurationListenerCaptor.capture()); clearInvocations(mUserManager); @@ -250,7 +287,26 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { } @Test - public void onKeyguardVisibilityChanged_updatesUserSwitcherVisibility() { + @EnableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND) + public void + onKeyguardVisibilityChanged_userSwitcherFlagEnabled_updatesUserSwitcherVisibility() { + mController.onViewAttached(); + runAllScheduled(); + verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardCallbackCaptor.capture()); + clearInvocations(mUserManager); + clearInvocations(mKeyguardStatusBarView); + + mKeyguardCallbackCaptor.getValue().onKeyguardVisibilityChanged(true); + + runAllScheduled(); + verify(mUserManager).isUserSwitcherEnabled(anyBoolean()); + verify(mKeyguardStatusBarView).setUserSwitcherEnabled(anyBoolean()); + } + + @Test + @DisableFlags(FLAG_UPDATE_USER_SWITCHER_BACKGROUND) + public void + onKeyguardVisibilityChanged_userSwitcherFlagDisabled_updatesUserSwitcherVisibility() { mController.onViewAttached(); verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardCallbackCaptor.capture()); clearInvocations(mUserManager); @@ -298,7 +354,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { verify(mStatusBarIconController).addIconGroup(any()); } - + @Test public void setBatteryListening_true_callbackAdded() { mController.setBatteryListening(true); @@ -762,6 +818,11 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase { return captor.getValue(); } + private void runAllScheduled() { + mBackgroundExecutor.runAllReady(); + mFakeExecutor.runAllReady(); + } + private static class TestShadeViewStateProvider implements ShadeViewStateProvider { diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt index e499a3c6c2eb..e4a1c2680658 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt @@ -30,16 +30,22 @@ object FoldableTestUtils { assumeTrue("Test should be launched on a foldable device", foldedDeviceStates.isNotEmpty()) - val folded = - DeviceState(foldedDeviceStates.maxOrNull()!! /* identifier */, - "" /* name */, - emptySet() /* properties */) - val unfolded = - DeviceState(folded.identifier + 1 /* identifier */, - "" /* name */, - emptySet() /* properties */) + val folded = getDeviceState( + identifier = foldedDeviceStates.maxOrNull()!! + ) + val unfolded = getDeviceState( + identifier = folded.identifier + 1 + ) return FoldableDeviceStates(folded = folded, unfolded = unfolded) } + + private fun getDeviceState(identifier: Int): DeviceState { + return DeviceState( + DeviceState.Configuration.Builder( + identifier, "" /* name */ + ).build() + ) + } } data class FoldableDeviceStates(val folded: DeviceState, val unfolded: DeviceState)
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java index d0261ae7d256..974e396fe280 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -20,6 +20,7 @@ import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; import static android.media.AudioManager.RINGER_MODE_VIBRATE; +import static com.android.systemui.Flags.FLAG_HAPTIC_VOLUME_SLIDER; import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN; import static com.android.systemui.volume.Events.SHOW_REASON_UNKNOWN; import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS; @@ -46,7 +47,10 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.media.AudioManager; +import android.media.AudioSystem; import android.os.SystemClock; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -265,6 +269,54 @@ public class VolumeDialogImplTest extends SysuiTestCase { } @Test + @DisableFlags(FLAG_HAPTIC_VOLUME_SLIDER) + public void testVolumeChange_noSliderHaptics_doesNotDeliverOnProgressChangedHaptics() { + // Initialize the dialog again with haptic sliders disabled + mDialog.init(0, null); + final State shellState = createShellState(); + VolumeDialogController.StreamState musicStreamState = + shellState.states.get(AudioSystem.STREAM_MUSIC); + + mDialog.show(SHOW_REASON_UNKNOWN); + mTestableLooper.processMessages(1); //Only the SHOW message + + // Change the volume two times + musicStreamState.level += 10; + mDialog.onStateChangedH(shellState); + mAnimatorTestRule.advanceTimeBy(10); + musicStreamState.level += 10; + mDialog.onStateChangedH(shellState); + + // expected: the type of the progress haptics for the stream should be DISABLED + short type = mDialog.progressHapticsForStream(AudioSystem.STREAM_MUSIC); + assertEquals(VolumeDialogImpl.PROGRESS_HAPTICS_DISABLED, type); + } + + @Test + @EnableFlags(FLAG_HAPTIC_VOLUME_SLIDER) + public void testVolumeChange_withSliderHaptics_deliversOnProgressChangedHapticsEagerly() { + // Initialize the dialog again to create haptic plugins on the rows with the flag enabled + mDialog.init(0, null); + final State shellState = createShellState(); + VolumeDialogController.StreamState musicStreamState = + shellState.states.get(AudioSystem.STREAM_MUSIC); + + mDialog.show(SHOW_REASON_UNKNOWN); + mTestableLooper.processMessages(1); //Only the SHOW message + + // Change the volume two times + musicStreamState.level += 10; + mDialog.onStateChangedH(shellState); + mAnimatorTestRule.advanceTimeBy(10); + musicStreamState.level += 10; + mDialog.onStateChangedH(shellState); + + // expected: the type of the progress haptics for the stream should be EAGER + short type = mDialog.progressHapticsForStream(AudioSystem.STREAM_MUSIC); + assertEquals(VolumeDialogImpl.PROGRESS_HAPTICS_EAGER, type); + } + + @Test public void testComputeTimeout() { Mockito.reset(mAccessibilityMgr); mDialog.rescheduleTimeoutH(); diff --git a/packages/SystemUI/tests/utils/src/android/os/LooperKosmos.kt b/packages/SystemUI/tests/utils/src/android/os/LooperKosmos.kt new file mode 100644 index 000000000000..a8ca9bfc7819 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/android/os/LooperKosmos.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os + +import android.testing.TestableLooper +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.testCase + +val Kosmos.looper by Fixture { + checkNotNull(TestableLooper.get(testCase).looper) { + "TestableLooper is returning null, make sure the test class is annotated with RunWithLooper" + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt new file mode 100644 index 000000000000..ed291d1b25a3 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.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 com.android.systemui.animation + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture + +val Kosmos.dialogTransitionAnimator by Fixture { fakeDialogTransitionAnimator() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt index 050c2c9793f3..4d74254cf9f8 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt @@ -30,7 +30,11 @@ import kotlinx.coroutines.flow.asStateFlow @SysUISingleton class FakeConfigurationRepository @Inject constructor() : ConfigurationRepository { - private val _onAnyConfigurationChange = MutableSharedFlow<Unit>() + private val _onAnyConfigurationChange = + MutableSharedFlow<Unit>( + replay = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST, + ) override val onAnyConfigurationChange: Flow<Unit> = _onAnyConfigurationChange.asSharedFlow() private val _onConfigurationChange = diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt index 6ac702eb2446..8866fd31faac 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt @@ -16,6 +16,8 @@ package com.android.systemui.communal.domain.interactor +import android.os.userManager +import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.communal.data.repository.communalMediaRepository import com.android.systemui.communal.data.repository.communalPrefsRepository import com.android.systemui.communal.data.repository.communalRepository @@ -29,6 +31,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.log.logcatLogBuffer +import com.android.systemui.plugins.activityStarter import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags import com.android.systemui.settings.userTracker @@ -39,6 +42,7 @@ import com.android.systemui.util.mockito.mock val Kosmos.communalInteractor by Fixture { CommunalInteractor( applicationScope = applicationCoroutineScope, + broadcastDispatcher = broadcastDispatcher, communalRepository = communalRepository, widgetRepository = communalWidgetRepository, mediaRepository = communalMediaRepository, @@ -48,6 +52,8 @@ val Kosmos.communalInteractor by Fixture { keyguardInteractor = keyguardInteractor, editWidgetsActivityStarter = editWidgetsActivityStarter, userTracker = userTracker, + activityStarter = activityStarter, + userManager = userManager, logBuffer = logcatLogBuffer("CommunalInteractor"), tableLogBuffer = mock(), communalSettingsInteractor = communalSettingsInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt index 5dd50731c58a..a45b269638c0 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/GlanceableHubTransitionsKosmos.kt @@ -19,12 +19,10 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.kosmos.Kosmos -import com.android.systemui.kosmos.testDispatcher val Kosmos.glanceableHubTransitions by Kosmos.Fixture { GlanceableHubTransitions( - bgDispatcher = testDispatcher, transitionRepository = keyguardTransitionRepository, transitionInteractor = keyguardTransitionInteractor, communalInteractor = communalInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModelKosmos.kt index 00741eb69c62..298c70de47ee 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModelKosmos.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.common.ui.domain.interactor.configurationInteractor +import com.android.systemui.keyguard.domain.interactor.fromDreamingTransitionInteractor import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow import com.android.systemui.kosmos.Kosmos @@ -25,5 +26,6 @@ val Kosmos.dreamingToGlanceableHubTransitionViewModel by DreamingToGlanceableHubTransitionViewModel( configurationInteractor = configurationInteractor, animationFlow = keyguardTransitionAnimationFlow, + fromDreamingTransitionInteractor = fromDreamingTransitionInteractor ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt index 5f70a2f06f2e..450dcc25c903 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelKosmos.kt @@ -16,7 +16,6 @@ package com.android.systemui.keyguard.ui.viewmodel -import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture @@ -26,7 +25,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi @ExperimentalCoroutinesApi val Kosmos.dreamingToLockscreenTransitionViewModel by Fixture { DreamingToLockscreenTransitionViewModel( - keyguardTransitionInteractor = keyguardTransitionInteractor, fromDreamingTransitionInteractor = mock(), animationFlow = keyguardTransitionAnimationFlow, ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt index 23d657d0abca..1ce26109ed04 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt @@ -16,16 +16,86 @@ package com.android.systemui.qs +import android.app.admin.devicePolicyManager +import android.content.applicationContext +import android.os.fakeExecutorHandler +import android.os.looper +import com.android.internal.logging.metricsLogger +import com.android.internal.logging.uiEventLogger import com.android.internal.logging.uiEventLoggerFake import com.android.systemui.InstanceIdSequenceFake +import com.android.systemui.animation.dialogTransitionAnimator +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.classifier.falsingManager import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.plugins.activityStarter import com.android.systemui.plugins.qs.QSFactory +import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractorImpl +import com.android.systemui.qs.footer.foregroundServicesRepository +import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.tiles.di.NewQSTileFactory +import com.android.systemui.security.data.repository.securityRepository +import com.android.systemui.settings.userTracker +import com.android.systemui.statusbar.policy.deviceProvisionedController +import com.android.systemui.statusbar.policy.securityController +import com.android.systemui.user.data.repository.userSwitcherRepository +import com.android.systemui.user.domain.interactor.userSwitcherInteractor +import com.android.systemui.util.mockito.mock -val Kosmos.instanceIdSequenceFake: InstanceIdSequenceFake by - Kosmos.Fixture { InstanceIdSequenceFake(0) } -val Kosmos.qsEventLogger: QsEventLoggerFake by - Kosmos.Fixture { QsEventLoggerFake(uiEventLoggerFake, instanceIdSequenceFake) } +val Kosmos.instanceIdSequenceFake: InstanceIdSequenceFake by Fixture { InstanceIdSequenceFake(0) } +val Kosmos.qsEventLogger: QsEventLoggerFake by Fixture { + QsEventLoggerFake(uiEventLoggerFake, instanceIdSequenceFake) +} -var Kosmos.newQSTileFactory by Kosmos.Fixture<NewQSTileFactory>() -var Kosmos.qsTileFactory by Kosmos.Fixture<QSFactory>() +var Kosmos.newQSTileFactory by Fixture<NewQSTileFactory>() +var Kosmos.qsTileFactory by Fixture<QSFactory>() + +val Kosmos.fgsManagerController by Fixture { FakeFgsManagerController() } + +val Kosmos.footerActionsController by Fixture { + FooterActionsController( + fgsManagerController = fgsManagerController, + ) +} + +val Kosmos.qsSecurityFooterUtils by Fixture { + QSSecurityFooterUtils( + applicationContext, + devicePolicyManager, + userTracker, + fakeExecutorHandler, + activityStarter, + securityController, + looper, + dialogTransitionAnimator, + ) +} + +val Kosmos.footerActionsInteractor by Fixture { + FooterActionsInteractorImpl( + activityStarter = activityStarter, + metricsLogger = metricsLogger, + uiEventLogger = uiEventLogger, + deviceProvisionedController = deviceProvisionedController, + qsSecurityFooterUtils = qsSecurityFooterUtils, + fgsManagerController = fgsManagerController, + userSwitcherInteractor = userSwitcherInteractor, + securityRepository = securityRepository, + foregroundServicesRepository = foregroundServicesRepository, + userSwitcherRepository = userSwitcherRepository, + broadcastDispatcher = broadcastDispatcher, + bgDispatcher = testDispatcher, + ) +} + +val Kosmos.footerActionsViewModelFactory by Fixture { + FooterActionsViewModel.Factory( + context = applicationContext, + falsingManager = falsingManager, + footerActionsInteractor = footerActionsInteractor, + globalActionsDialogLiteProvider = { mock() }, + showPowerButton = true, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/ForegroundServicesRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/ForegroundServicesRepositoryKosmos.kt new file mode 100644 index 000000000000..8f81b5efb01c --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/ForegroundServicesRepositoryKosmos.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.footer + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.qs.fgsManagerController +import com.android.systemui.qs.footer.data.repository.ForegroundServicesRepositoryImpl + +val Kosmos.foregroundServicesRepository by Fixture { + ForegroundServicesRepositoryImpl( + fgsManagerController = fgsManagerController, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/security/data/repository/SecurityRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/security/data/repository/SecurityRepositoryKosmos.kt new file mode 100644 index 000000000000..6ac5bcbd3af6 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/security/data/repository/SecurityRepositoryKosmos.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.security.data.repository + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.statusbar.policy.securityController + +val Kosmos.securityRepository by Fixture { + SecurityRepositoryImpl( + securityController = securityController, + bgDispatcher = testDispatcher, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt index 4aab822f6659..728c67af5e06 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt @@ -18,11 +18,13 @@ package com.android.systemui.shade.data.repository import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.shade.shared.model.ShadeMode import dagger.Binds import dagger.Module import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow /** Fake implementation of [ShadeRepository] */ @SysUISingleton @@ -59,6 +61,9 @@ class FakeShadeRepository @Inject constructor() : ShadeRepository { override val legacyLockscreenShadeTracking = MutableStateFlow(false) + private val _shadeMode = MutableStateFlow<ShadeMode>(ShadeMode.Single) + override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow() + @Deprecated("Use ShadeInteractor instead") override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) { _legacyIsQsExpanded.value = legacyIsQsExpanded @@ -131,6 +136,10 @@ class FakeShadeRepository @Inject constructor() : ShadeRepository { override fun setLegacyShadeExpansion(expandedFraction: Float) { _legacyShadeExpansion.value = expandedFraction } + + override fun setShadeMode(shadeMode: ShadeMode) { + _shadeMode.value = shadeMode + } } @Module diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt index 2bd76bec6852..07e2d6b0334c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt @@ -47,6 +47,7 @@ val Kosmos.shadeInteractorSceneContainerImpl by scope = applicationCoroutineScope, sceneInteractor = sceneInteractor, sharedNotificationContainerInteractor = sharedNotificationContainerInteractor, + shadeRepository = shadeRepository, ) } val Kosmos.shadeInteractorLegacyImpl by diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt new file mode 100644 index 000000000000..b99fdb9c5c63 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.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.shade.domain.startable + +import android.content.applicationContext +import com.android.systemui.common.ui.data.repository.configurationRepository +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.shade.data.repository.shadeRepository +import com.android.systemui.statusbar.policy.splitShadeStateController + +val Kosmos.shadeStartable by Fixture { + ShadeStartable( + applicationScope = applicationCoroutineScope, + applicationContext = applicationContext, + configurationRepository = configurationRepository, + shadeRepository = shadeRepository, + controller = splitShadeStateController, + ) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt index c01366489c69..de0cc6590593 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel -import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.dump.dumpManager import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor @@ -56,7 +55,6 @@ val Kosmos.sharedNotificationContainerViewModel by Fixture { keyguardInteractor = keyguardInteractor, keyguardTransitionInteractor = keyguardTransitionInteractor, shadeInteractor = shadeInteractor, - communalInteractor = communalInteractor, alternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel, aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel, aodToOccludedTransitionViewModel = aodToOccludedTransitionViewModel, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt new file mode 100644 index 000000000000..67a5cc98db98 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SecurityControllerKosmos.kt @@ -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.systemui.statusbar.policy + +import android.content.applicationContext +import android.os.fakeExecutorHandler +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.concurrency.fakeExecutor +import com.android.systemui.dump.dumpManager +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.settings.userTracker + +val Kosmos.securityController by Fixture { + SecurityControllerImpl( + applicationContext, + userTracker, + fakeExecutorHandler, + broadcastDispatcher, + fakeExecutor, + fakeExecutor, + dumpManager, + ) +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/FakeUserSwitcherRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserSwitcherRepository.kt index 758fe93a658c..90fb60bfb2a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/FakeUserSwitcherRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserSwitcherRepository.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 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. diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserSwitcherRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserSwitcherRepositoryKosmos.kt new file mode 100644 index 000000000000..1519f3062578 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserSwitcherRepositoryKosmos.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 com.android.systemui.user.data.repository + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture + +val Kosmos.userSwitcherRepository by Fixture { FakeUserSwitcherRepository() } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index ff48c9dd7c6e..3cbfd42c279d 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -715,16 +715,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } - private void onSomePackagesChangedLocked() { - final AccessibilityUserState userState = getCurrentUserStateLocked(); - // Reload the installed services since some services may have different attributes - // or resolve info (does not support equals), etc. Remove them then to force reload. - userState.mInstalledServices.clear(); - if (readConfigurationForUserStateLocked(userState)) { - onUserStateChangedLocked(userState); - } - } - private void onSomePackagesChangedLocked( @Nullable List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos, @Nullable List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos) { @@ -842,22 +832,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int userId = getChangingUserId(); List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = null; List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = null; - if (Flags.scanPackagesWithoutLock()) { - parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId); - parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId); - } + parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId); + parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId); synchronized (mLock) { // Only the profile parent can install accessibility services. // Therefore we ignore packages from linked profiles. if (userId != mCurrentUserId) { return; } - if (Flags.scanPackagesWithoutLock()) { - onSomePackagesChangedLocked(parsedAccessibilityServiceInfos, - parsedAccessibilityShortcutInfos); - } else { - onSomePackagesChangedLocked(); - } + onSomePackagesChangedLocked(parsedAccessibilityServiceInfos, + parsedAccessibilityShortcutInfos); } } @@ -875,10 +859,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub final int userId = getChangingUserId(); List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = null; List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = null; - if (Flags.scanPackagesWithoutLock()) { - parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId); - parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId); - } + parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId); + parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId); synchronized (mLock) { if (userId != mCurrentUserId) { return; @@ -893,12 +875,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // get a new one. userState.mInstalledServices.clear(); final boolean configurationChanged; - if (Flags.scanPackagesWithoutLock()) { - configurationChanged = readConfigurationForUserStateLocked(userState, - parsedAccessibilityServiceInfos, parsedAccessibilityShortcutInfos); - } else { - configurationChanged = readConfigurationForUserStateLocked(userState); - } + configurationChanged = readConfigurationForUserStateLocked(userState, + parsedAccessibilityServiceInfos, parsedAccessibilityShortcutInfos); if (reboundAService || configurationChanged) { onUserStateChangedLocked(userState); } @@ -993,34 +971,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // package changes mPackageMonitor.register(mContext, null, UserHandle.ALL, true); - if (!Flags.deprecatePackageListObserver()) { - final PackageManagerInternal pm = LocalServices.getService( - PackageManagerInternal.class); - if (pm != null) { - pm.getPackageList(new PackageManagerInternal.PackageListObserver() { - @Override - public void onPackageAdded(String packageName, int uid) { - final int userId = UserHandle.getUserId(uid); - synchronized (mLock) { - if (userId == mCurrentUserId) { - onSomePackagesChangedLocked(); - } - } - } - - @Override - public void onPackageRemoved(String packageName, int uid) { - final int userId = UserHandle.getUserId(uid); - synchronized (mLock) { - if (userId == mCurrentUserId) { - onPackageRemovedLocked(packageName); - } - } - } - }); - } - } - // user change and unlock IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); @@ -1994,10 +1944,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mMagnificationController.updateUserIdIfNeeded(userId); List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos = null; List<AccessibilityShortcutInfo> parsedAccessibilityShortcutInfos = null; - if (Flags.scanPackagesWithoutLock()) { - parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId); - parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId); - } + parsedAccessibilityServiceInfos = parseAccessibilityServiceInfos(userId); + parsedAccessibilityShortcutInfos = parseAccessibilityShortcutInfos(userId); synchronized (mLock) { if (mCurrentUserId == userId && mInitialized) { return; @@ -2022,12 +1970,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mCurrentUserId = userId; AccessibilityUserState userState = getCurrentUserStateLocked(); - if (Flags.scanPackagesWithoutLock()) { - readConfigurationForUserStateLocked(userState, - parsedAccessibilityServiceInfos, parsedAccessibilityShortcutInfos); - } else { - readConfigurationForUserStateLocked(userState); - } + readConfigurationForUserStateLocked(userState, + parsedAccessibilityServiceInfos, parsedAccessibilityShortcutInfos); mSecurityPolicy.onSwitchUserLocked(mCurrentUserId, userState.mEnabledServices); // Even if reading did not yield change, we have to update // the state since the context in which the current user @@ -3135,15 +3079,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub userState.setFilterKeyEventsEnabledLocked(false); } - // ErrorProne doesn't understand that this method is only called while locked, - // returning an error for accessing mCurrentUserId. - @SuppressWarnings("GuardedBy") - private boolean readConfigurationForUserStateLocked(AccessibilityUserState userState) { - return readConfigurationForUserStateLocked(userState, - parseAccessibilityServiceInfos(mCurrentUserId), - parseAccessibilityShortcutInfos(mCurrentUserId)); - } - private boolean readConfigurationForUserStateLocked( AccessibilityUserState userState, List<AccessibilityServiceInfo> parsedAccessibilityServiceInfos, diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 285e54c30167..e1291e5f75ec 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -33,10 +33,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManagerInternal; import android.content.ComponentName; -import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.graphics.Rect; import android.metrics.LogMaker; @@ -253,26 +251,6 @@ final class AutofillManagerServiceImpl @Override // from PerUserSystemService protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) throws NameNotFoundException { - final List<ResolveInfo> resolveInfos = - getContext().getPackageManager().queryIntentServicesAsUser( - new Intent(AutofillService.SERVICE_INTERFACE), - PackageManager.GET_META_DATA, - mUserId); - boolean currentPackageStillHasAutofillIntentFilter = false; - for (ResolveInfo resolveInfo : resolveInfos) { - final ServiceInfo serviceInfo = resolveInfo.serviceInfo; - if (serviceInfo.getComponentName().equals(serviceComponent)) { - currentPackageStillHasAutofillIntentFilter = true; - break; - } - } - if (!currentPackageStillHasAutofillIntentFilter) { - Slog.w(TAG, - "Autofill service from '" + serviceComponent.getPackageName() + "' does" - + "not have intent filter " + AutofillService.SERVICE_INTERFACE); - throw new SecurityException("Service does not declare intent filter " - + AutofillService.SERVICE_INTERFACE); - } mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId); return mInfo.getServiceInfo(); } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 13bc77296f0f..ca2a3ddc49bc 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -6458,12 +6458,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } else if (response != null) { if (viewId.isVirtualInt()) { ViewNode viewNode = getViewNodeFromContextsLocked(viewId); - if (viewNode != null && viewNode.getCredentialManagerCallback() != null) { + if (viewNode != null && viewNode.getPendingCredentialCallback() != null) { Bundle resultData = new Bundle(); resultData.putParcelable( CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE, response); - viewNode.getCredentialManagerCallback().send(SUCCESS_CREDMAN_SELECTOR, + viewNode.getPendingCredentialCallback().send(SUCCESS_CREDMAN_SELECTOR, resultData); } else { Slog.w(TAG, "View node not found after GetCredentialResponse"); diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index b1672ed9c732..8244d20e8e6a 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -29,6 +29,7 @@ import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; +import static android.companion.virtualdevice.flags.Flags.virtualCameraServiceDiscovery; import android.annotation.EnforcePermission; import android.annotation.NonNull; @@ -111,6 +112,8 @@ import com.android.server.companion.virtual.audio.VirtualAudioController; import com.android.server.companion.virtual.camera.VirtualCameraController; import com.android.server.inputmethod.InputMethodManagerInternal; +import dalvik.annotation.optimization.FastNative; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; @@ -265,7 +268,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub runningAppsChangedCallback, params, DisplayManagerGlobal.getInstance(), - Flags.virtualCamera() + isVirtualCameraEnabled() ? new VirtualCameraController(params.getDevicePolicy(POLICY_TYPE_CAMERA)) : null); } @@ -1535,4 +1538,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub return mToken; } } + + private static boolean isVirtualCameraEnabled() { + return Flags.virtualCamera() && virtualCameraServiceDiscovery() + && nativeVirtualCameraServiceBuildFlagEnabled(); + } + + // Returns true if virtual_camera service is enabled in this build. + @FastNative + private static native boolean nativeVirtualCameraServiceBuildFlagEnabled(); } diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index c5c2b0b5dd59..c7a83693e063 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -29,7 +29,6 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.IActivityManager; -import android.app.SearchManager; import android.app.UidObserver; import android.app.pinner.IPinnerService; import android.app.pinner.PinnedFileStat; @@ -53,7 +52,6 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.SystemProperties; -import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; @@ -139,7 +137,6 @@ public final class PinnerService extends SystemService { private final ActivityManagerInternal mAmInternal; private final IActivityManager mAm; private final UserManager mUserManager; - private SearchManager mSearchManager; /** The list of the statically pinned files. */ @GuardedBy("this") private final ArrayMap<String, PinnedFile> mPinnedFiles = new ArrayMap<>(); @@ -283,15 +280,6 @@ public final class PinnerService extends SystemService { sendPinAppsMessage(UserHandle.USER_SYSTEM); } - @Override - public void onBootPhase(int phase) { - // SearchManagerService is started after PinnerService, wait for PHASE_SYSTEM_SERVICES_READY - if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { - mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); - sendPinAppsMessage(UserHandle.USER_SYSTEM); - } - } - /** * Repin apps on user switch. * <p> @@ -308,8 +296,9 @@ public final class PinnerService extends SystemService { @Override public void onUserUnlocking(@NonNull TargetUser user) { - int userId = user.getUserIdentifier(); - if (!mUserManager.isManagedProfile(userId)) { + final int userId = user.getUserIdentifier(); + if (userId != UserHandle.USER_SYSTEM && !mUserManager.isManagedProfile(userId)) { + // App pinning for the system should have already been triggered from onStart(). sendPinAppsMessage(userId); } } @@ -532,11 +521,8 @@ public final class PinnerService extends SystemService { } private ApplicationInfo getAssistantInfo(int userHandle) { - if (mSearchManager != null) { - Intent intent = mSearchManager.getAssistIntent(false); - return getApplicationInfoForIntent(intent, userHandle, true); - } - return null; + Intent intent = new Intent(Intent.ACTION_ASSIST); + return getApplicationInfoForIntent(intent, userHandle, true); } private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle, diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 258f53d982d2..52988460606c 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -119,6 +119,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE_EXECUTING; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; @@ -1497,6 +1498,11 @@ public final class ActiveServices { FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName, serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START); mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName); + final ProcessRecord hostApp = r.app; + final boolean wasStopped = hostApp == null ? wasStopped(r) : false; + final boolean firstLaunch = + hostApp == null ? !mAm.wasPackageEverLaunched(r.packageName, r.userId) : false; + String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false /* whileRestarting */, false /* permissionsReviewRequired */, @@ -1509,10 +1515,14 @@ public final class ActiveServices { return new ComponentName("!!", error); } - final boolean wasStopped = (r.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; final int packageState = wasStopped ? SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED : SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; + if (DEBUG_PROCESSES) { + Slog.d(TAG, "Logging startService for " + packageName + ", stopped=" + + wasStopped + ", firstLaunch=" + firstLaunch + ", intent=" + service + + ", r.app=" + r.app); + } FrameworkStatsLog.write(SERVICE_REQUEST_EVENT_REPORTED, uid, callingUid, service.getAction(), SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__START, false, @@ -1527,7 +1537,9 @@ public final class ActiveServices { packageName, callingPackage, callingProcessState, - r.mProcessStateOnRequest); + r.mProcessStateOnRequest, + firstLaunch, + 0L /* TODO: stoppedDuration */); if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0; @@ -4038,7 +4050,6 @@ public final class ActiveServices { mAm.requireAllowedAssociationsLocked(s.appInfo.packageName); } - final boolean wasStopped = (s.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; final boolean wasStartRequested = s.startRequested; final boolean hadConnections = !s.getConnections().isEmpty(); mAm.startAssociationLocked(callerApp.uid, callerApp.processName, @@ -4113,6 +4124,10 @@ public final class ActiveServices { true); } + final boolean wasStopped = hostApp == null ? wasStopped(s) : false; + final boolean firstLaunch = + hostApp == null ? !mAm.wasPackageEverLaunched(s.packageName, s.userId) : false; + boolean needOomAdj = false; if (c.hasFlag(Context.BIND_AUTO_CREATE)) { s.lastActivity = SystemClock.uptimeMillis(); @@ -4155,6 +4170,10 @@ public final class ActiveServices { final int packageState = wasStopped ? SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED : SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; + if (DEBUG_PROCESSES) { + Slog.d(TAG, "Logging bindService for " + s.packageName + + ", stopped=" + wasStopped + ", firstLaunch=" + firstLaunch); + } FrameworkStatsLog.write(SERVICE_REQUEST_EVENT_REPORTED, s.appInfo.uid, callingUid, ActivityManagerService.getShortAction(service.getAction()), SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__BIND, false, @@ -4169,7 +4188,9 @@ public final class ActiveServices { s.packageName, callerApp.info.packageName, callerApp.mState.getCurProcState(), - s.mProcessStateOnRequest); + s.mProcessStateOnRequest, + firstLaunch, + 0L /* TODO */); if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b + ": received=" + b.intent.received @@ -9112,4 +9133,8 @@ public final class ActiveServices { return mCachedDeviceProvisioningPackage != null && mCachedDeviceProvisioningPackage.equals(packageName); } + + private boolean wasStopped(ServiceRecord serviceRecord) { + return (serviceRecord.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; + } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5e367097b78c..60bfc637225f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -725,12 +725,6 @@ public class ActivityManagerService extends IActivityManager.Stub // Whether we should use SCHED_FIFO for UI and RenderThreads. final boolean mUseFifoUiScheduling; - /** - * Flag indicating if we should use {@link BroadcastQueueModernImpl} instead - * of the default {@link BroadcastQueueImpl}. - */ - final boolean mEnableModernQueue; - @GuardedBy("this") private final SparseArray<IUnsafeIntentStrictModeCallback> mStrictModeCallbacks = new SparseArray<>(); @@ -2508,7 +2502,6 @@ public class ActivityManagerService extends IActivityManager.Stub mInternal = new LocalService(); mPendingStartActivityUids = new PendingStartActivityUids(); mUseFifoUiScheduling = false; - mEnableModernQueue = false; mBroadcastQueue = injector.getBroadcastQueue(this); mComponentAliasResolver = new ComponentAliasResolver(this); } @@ -2550,9 +2543,6 @@ public class ActivityManagerService extends IActivityManager.Stub ? new OomAdjusterModernImpl(this, mProcessList, activeUids) : new OomAdjuster(this, mProcessList, activeUids); - mEnableModernQueue = new BroadcastConstants( - Settings.Global.BROADCAST_FG_CONSTANTS).MODERN_QUEUE_ENABLED; - mBroadcastQueue = mInjector.getBroadcastQueue(this); mServices = new ActiveServices(this); @@ -5046,8 +5036,11 @@ public class ActivityManagerService extends IActivityManager.Stub * Send LOCKED_BOOT_COMPLETED and BOOT_COMPLETED to the package explicitly when unstopped */ private void maybeSendBootCompletedLocked(ProcessRecord app) { + if (!android.content.pm.Flags.stayStopped()) return; // Nothing to do if it wasn't previously stopped - if (!android.content.pm.Flags.stayStopped() || !app.wasForceStopped()) return; + if (!app.wasForceStopped() && !app.getWindowProcessController().wasForceStopped()) { + return; + } // Send LOCKED_BOOT_COMPLETED, if necessary if (app.getApplicationInfo().isEncryptionAware()) { @@ -5059,7 +5052,8 @@ public class ActivityManagerService extends IActivityManager.Stub sendBootBroadcastToAppLocked(app, new Intent(Intent.ACTION_BOOT_COMPLETED), REASON_BOOT_COMPLETED); } - app.setWasForceStopped(false); + // The stopped state is reset in ProcessRecord when the pid changes, to deal with + // any re-use of the ProcessRecord. } /** Send a boot_completed broadcast to app */ @@ -6844,6 +6838,17 @@ public class ActivityManagerService extends IActivityManager.Stub return mPermissionManagerInt; } + /** Returns whether the given package was ever launched since install */ + boolean wasPackageEverLaunched(String packageName, @UserIdInt int userId) { + boolean wasLaunched = false; + try { + wasLaunched = getPackageManagerInternal().wasPackageEverLaunched(packageName, userId); + } catch (Exception e) { + // If the package state record doesn't exist yet, assume it was never launched + } + return wasLaunched; + } + private TestUtilityService getTestUtilityServiceLocked() { if (mTestUtilityService == null) { mTestUtilityService = @@ -15010,9 +15015,6 @@ public class ActivityManagerService extends IActivityManager.Stub + " ordered=" + ordered + " userid=" + userId + " options=" + (brOptions == null ? "null" : brOptions.toBundle())); if ((resultTo != null) && !ordered) { - if (!mEnableModernQueue) { - Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); - } if (!UserHandle.isCore(callingUid)) { String msg = "Unauthorized unordered resultTo broadcast " + intent + " sent from uid " + callingUid; @@ -15613,29 +15615,6 @@ public class ActivityManagerService extends IActivityManager.Stub filterNonExportedComponents(intent, callingUid, callingPid, registeredReceivers, mPlatformCompat, callerPackage, resolvedType); int NR = registeredReceivers != null ? registeredReceivers.size() : 0; - if (!ordered && NR > 0 && !mEnableModernQueue) { - // If we are not serializing this broadcast, then send the - // registered receivers separately so they don't wait for the - // components to be launched. We don't do this split for the modern - // queue because delivery to registered receivers isn't blocked - // behind manifest receivers. - if (isCallerSystem) { - checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, - isProtectedBroadcast, registeredReceivers); - } - final BroadcastQueue queue = mBroadcastQueue; - BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, - callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, - requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions, - registeredReceivers, resultToApp, resultTo, resultCode, resultData, - resultExtras, ordered, sticky, false, userId, - backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver, - callerAppProcessState); - if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); - queue.enqueueBroadcastLocked(r); - registeredReceivers = null; - NR = 0; - } // Merge into one list. int ir = 0; @@ -18287,11 +18266,6 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public boolean isModernQueueEnabled() { - return mEnableModernQueue; - } - - @Override public void enforceBroadcastOptionsPermissions(Bundle options, int callingUid) { enforceBroadcastOptionPermissionsInternal(options, callingUid); } @@ -18720,7 +18694,6 @@ public class ActivityManagerService extends IActivityManager.Stub Binder.restoreCallingIdentity(origId); } } - } @Override @@ -18730,12 +18703,8 @@ public class ActivityManagerService extends IActivityManager.Stub int userId, int[] appIdAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver, @Nullable Bundle bOptions) { - // Sending broadcasts with a finish callback without the need for the broadcasts - // delivery to be serialized is only supported by modern queue. So, when modern - // queue is disabled, we continue to send broadcasts in a serialized fashion. - final boolean serialized = !isModernQueueEnabled(); - return broadcastIntent(intent, resultTo, requiredPermissions, serialized, userId, - appIdAllowList, filterExtrasForReceiver, bOptions); + return broadcastIntent(intent, resultTo, requiredPermissions, false /* serialized */, + userId, appIdAllowList, filterExtrasForReceiver, bOptions); } @Override @@ -19774,21 +19743,11 @@ public class ActivityManagerService extends IActivityManager.Stub Objects.requireNonNull(targetPackage); Preconditions.checkArgumentNonnegative(delayedDurationMs); enforceCallingPermission(permission.DUMP, "forceDelayBroadcastDelivery()"); - // Ignore request if modern queue is not enabled - if (!mEnableModernQueue) { - return; - } mBroadcastQueue.forceDelayBroadcastDelivery(targetPackage, delayedDurationMs); } @Override - public boolean isModernBroadcastQueueEnabled() { - enforceCallingPermission(permission.DUMP, "isModernBroadcastQueueEnabled()"); - return mEnableModernQueue; - } - - @Override public boolean isProcessFrozen(int pid) { enforceCallingPermission(permission.DUMP, "isProcessFrozen()"); return mOomAdjuster.mCachedAppOptimizer.isProcessFrozen(pid); diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java index 1dc384d61c91..3e633ccf798c 100644 --- a/services/core/java/com/android/server/am/AppStartInfoTracker.java +++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java @@ -54,6 +54,7 @@ import com.android.internal.app.ProcessMap; import com.android.server.IoThread; import com.android.server.ServiceThread; import com.android.server.SystemServiceManager; +import com.android.server.wm.WindowProcessController; import java.io.File; import java.io.FileInputStream; @@ -385,8 +386,10 @@ public final class AppStartInfoTracker { start.setPackageName(app.info.packageName); if (android.content.pm.Flags.stayStopped()) { // TODO: Verify this is created at the right time to have the correct force-stopped - // state in the ProcessRecord. Also use the WindowProcessRecord if activity. - start.setForceStopped(app.wasForceStopped()); + // state in the ProcessRecord. + final WindowProcessController wpc = app.getWindowProcessController(); + start.setForceStopped(app.wasForceStopped() + || (wpc != null ? wpc.wasForceStopped() : false)); } } diff --git a/services/core/java/com/android/server/am/BroadcastConstants.java b/services/core/java/com/android/server/am/BroadcastConstants.java index 887915d78bc9..57080f8b2d42 100644 --- a/services/core/java/com/android/server/am/BroadcastConstants.java +++ b/services/core/java/com/android/server/am/BroadcastConstants.java @@ -128,14 +128,6 @@ public class BroadcastConstants { public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT; /** - * Flag indicating if we should use {@link BroadcastQueueModernImpl} instead - * of the default {@link BroadcastQueueImpl}. - */ - public boolean MODERN_QUEUE_ENABLED = DEFAULT_MODERN_QUEUE_ENABLED; - private static final String KEY_MODERN_QUEUE_ENABLED = "modern_queue_enabled"; - private static final boolean DEFAULT_MODERN_QUEUE_ENABLED = true; - - /** * For {@link BroadcastQueueModernImpl}: Maximum dispatch parallelism * that we'll tolerate for ordinary broadcast dispatch. */ @@ -421,8 +413,6 @@ public class BroadcastConstants { */ private void updateDeviceConfigConstants() { synchronized (this) { - MODERN_QUEUE_ENABLED = getDeviceConfigBoolean(KEY_MODERN_QUEUE_ENABLED, - DEFAULT_MODERN_QUEUE_ENABLED); MAX_RUNNING_PROCESS_QUEUES = getDeviceConfigInt(KEY_MAX_RUNNING_PROCESS_QUEUES, DEFAULT_MAX_RUNNING_PROCESS_QUEUES); EXTRA_RUNNING_URGENT_PROCESS_QUEUES = getDeviceConfigInt( @@ -498,7 +488,6 @@ public class BroadcastConstants { pw.print(NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT); pw.println("):"); pw.increaseIndent(); - pw.print(KEY_MODERN_QUEUE_ENABLED, MODERN_QUEUE_ENABLED).println(); pw.print(KEY_MAX_RUNNING_PROCESS_QUEUES, MAX_RUNNING_PROCESS_QUEUES).println(); pw.print(KEY_MAX_RUNNING_ACTIVE_BROADCASTS, MAX_RUNNING_ACTIVE_BROADCASTS).println(); pw.print(KEY_CORE_MAX_RUNNING_BLOCKING_BROADCASTS, diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 298eb794c220..e98e1ba6a44e 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -182,6 +182,12 @@ class BroadcastProcessQueue { private boolean mActiveWasStopped; /** + * Flag indicating that the currently active broadcast is being dispatched + * to a package that was never launched before. + */ + private boolean mActiveFirstLaunch; + + /** * Number of consecutive urgent broadcasts that have been dispatched * since the last non-urgent dispatch. */ @@ -626,6 +632,10 @@ class BroadcastProcessQueue { mActiveWasStopped = activeWasStopped; } + public void setActiveFirstLaunch(boolean activeFirstLaunch) { + mActiveFirstLaunch = activeFirstLaunch; + } + public boolean getActiveViaColdStart() { return mActiveViaColdStart; } @@ -634,6 +644,10 @@ class BroadcastProcessQueue { return mActiveWasStopped; } + public boolean getActiveFirstLaunch() { + return mActiveFirstLaunch; + } + /** * Get package name of the first application loaded into this process. */ diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 569f9ecf5d0b..5521381e8908 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -32,6 +32,7 @@ import static com.android.internal.util.FrameworkStatsLog.BROADCAST_DELIVERY_EVE import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO; import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList; import static com.android.server.am.BroadcastProcessQueue.reasonToString; @@ -984,6 +985,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { queue.setActiveWasStopped(true); } final int intentFlags = r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND; + final boolean firstLaunch = !mService.wasPackageEverLaunched(info.packageName, r.userId); + queue.setActiveFirstLaunch(firstLaunch); + final HostingRecord hostingRecord = new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST, component, r.intent.getAction(), r.getHostingRecordTriggerType()); final boolean isActivityCapable = (r.options != null @@ -2138,6 +2142,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final long dispatchDelay = r.scheduledTime[index] - r.enqueueTime; final long receiveDelay = 0; final long finishDelay = r.terminalTime[index] - r.scheduledTime[index]; + if (DEBUG_PROCESSES) { + Slog.d(TAG, "Logging broadcast for " + + (app != null ? app.info.packageName : "<null>") + + ", stopped=" + queue.getActiveWasStopped() + + ", firstLaunch=" + queue.getActiveFirstLaunch()); + } if (queue != null) { final int packageState = queue.getActiveWasStopped() ? SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED @@ -2147,7 +2157,11 @@ class BroadcastQueueModernImpl extends BroadcastQueue { app != null ? app.info.packageName : null, r.callerPackage, r.calculateTypeForLogging(), r.getDeliveryGroupPolicy(), r.intent.getFlags(), BroadcastRecord.getReceiverPriority(receiver), r.callerProcState, - receiverProcessState); + receiverProcessState, queue.getActiveFirstLaunch(), + 0L /* TODO: stoppedDuration */); + // Reset the states after logging + queue.setActiveFirstLaunch(false); + queue.setActiveWasStopped(false); } } diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java index cb7898d8b862..f76bf37e4d58 100644 --- a/services/core/java/com/android/server/am/ContentProviderHelper.java +++ b/services/core/java/com/android/server/am/ContentProviderHelper.java @@ -34,6 +34,7 @@ import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_E import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD; import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; import static com.android.server.am.ActivityManagerService.TAG_MU; import static com.android.server.am.Flags.serviceBindingOomAdjPolicy; @@ -290,7 +291,8 @@ public class ContentProviderHelper { PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM, PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, cpi.packageName, callingPackage, - callingProcessState, callingProcessState); + callingProcessState, callingProcessState, + false, 0L); return holder; } @@ -368,7 +370,7 @@ public class ContentProviderHelper { PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM, PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, cpi.packageName, callingPackage, - callingProcessState, providerProcessState); + callingProcessState, providerProcessState, false, 0L); } } finally { Binder.restoreCallingIdentity(origId); @@ -546,12 +548,16 @@ public class ContentProviderHelper { PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM, PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL, cpi.packageName, callingPackage, - callingProcessState, proc.mState.getCurProcState()); + callingProcessState, proc.mState.getCurProcState(), + false, 0L); } else { - final int packageState = - ((cpr.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) + final boolean stopped = + (cpr.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; + final int packageState = stopped ? PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED : PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; + final boolean firstLaunch = !mService.wasPackageEverLaunched( + cpi.packageName, userId); checkTime(startTime, "getContentProviderImpl: before start process"); proc = mService.startProcessLocked( cpi.processName, cpr.appInfo, false, 0, @@ -567,12 +573,18 @@ public class ContentProviderHelper { + ": process is bad"); return null; } + if (DEBUG_PROCESSES) { + Slog.d(TAG, "Logging provider access for " + cpi.packageName + + ", stopped=" + stopped + ", firstLaunch=" + firstLaunch); + } FrameworkStatsLog.write( PROVIDER_ACQUISITION_EVENT_REPORTED, proc.uid, callingUid, PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD, packageState, cpi.packageName, callingPackage, - callingProcessState, ActivityManager.PROCESS_STATE_NONEXISTENT); + callingProcessState, ActivityManager.PROCESS_STATE_NONEXISTENT, + firstLaunch, + 0L /* TODO: stoppedDuration */); } cpr.launchingApp = proc; mLaunchingProviders.add(cpr); diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java index 30811a175bac..1a78a13cbf8c 100644 --- a/services/core/java/com/android/server/am/HostingRecord.java +++ b/services/core/java/com/android/server/am/HostingRecord.java @@ -325,4 +325,15 @@ public final class HostingRecord { return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN; } } + + private static boolean isTypeActivity(String hostingType) { + return HOSTING_TYPE_ACTIVITY.equals(hostingType) + || HOSTING_TYPE_NEXT_ACTIVITY.equals(hostingType) + || HOSTING_TYPE_NEXT_TOP_ACTIVITY.equals(hostingType) + || HOSTING_TYPE_TOP_ACTIVITY.equals(hostingType); + } + + public boolean isTypeActivity() { + return isTypeActivity(mHostingType); + } } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index cd6964ea2631..7f6d62c29648 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1051,7 +1051,7 @@ public class OomAdjuster { assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP()); - postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime); + postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime, true); if (startProfiling) { mService.mOomAdjProfiler.oomAdjEnded(); @@ -1073,12 +1073,12 @@ public class OomAdjuster { @GuardedBy({"mService", "mProcLock"}) protected void postUpdateOomAdjInnerLSP(@OomAdjReason int oomAdjReason, ActiveUids activeUids, - long now, long nowElapsed, long oldTime) { + long now, long nowElapsed, long oldTime, boolean doingAll) { mNumNonCachedProcs = 0; mNumCachedHiddenProcs = 0; final boolean allChanged = updateAndTrimProcessLSP(now, nowElapsed, oldTime, activeUids, - oomAdjReason); + oomAdjReason, doingAll); mNumServiceProcs = mNewNumServiceProcs; if (mService.mAlwaysFinishActivities) { @@ -1288,7 +1288,8 @@ public class OomAdjuster { @GuardedBy({"mService", "mProcLock"}) private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed, - final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason) { + final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason, + boolean doingAll) { ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP(); final int numLru = lruList.size(); @@ -1321,7 +1322,7 @@ public class OomAdjuster { if (!app.isKilledByAm() && app.getThread() != null) { // We don't need to apply the update for the process which didn't get computed if (state.getCompletedAdjSeq() == mAdjSeq) { - applyOomAdjLSP(app, true, now, nowElapsed, oomAdjReason); + applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason); } if (app.isPendingFinishAttach()) { diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java index dd75bc0442d0..46bdfe892040 100644 --- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java +++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java @@ -820,7 +820,7 @@ public class OomAdjusterModernImpl extends OomAdjuster { computeConnectionsLSP(); assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP()); - postUpdateOomAdjInnerLSP(oomAdjReason, mActiveUids, now, nowElapsed, oldTime); + postUpdateOomAdjInnerLSP(oomAdjReason, mActiveUids, now, nowElapsed, oldTime, true); } /** @@ -908,7 +908,7 @@ public class OomAdjusterModernImpl extends OomAdjuster { } } - postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime); + postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime, false); } /** diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index a1fdd5070527..27d6c608cf6c 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -59,6 +59,8 @@ import static com.android.server.am.ActivityManagerService.TAG_LRU; import static com.android.server.am.ActivityManagerService.TAG_NETWORK; import static com.android.server.am.ActivityManagerService.TAG_PROCESSES; import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS; +import static com.android.server.wm.WindowProcessController.STOPPED_STATE_FIRST_LAUNCH; +import static com.android.server.wm.WindowProcessController.STOPPED_STATE_FORCE_STOPPED; import android.Manifest; import android.annotation.NonNull; @@ -3327,19 +3329,24 @@ public final class ProcessList { hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName()); final ProcessStateRecord state = r.mState; + final boolean wasStopped = (info.flags & ApplicationInfo.FLAG_STOPPED) != 0; // Check if we should mark the processrecord for first launch after force-stopping - if ((r.getApplicationInfo().flags & ApplicationInfo.FLAG_STOPPED) != 0) { - try { - final boolean wasPackageEverLaunched = mService.getPackageManagerInternal() + if (wasStopped) { + // Check if the hosting record is for an activity or not. Since the stopped + // state tracking is handled differently to avoid WM calling back into AM, + // store the state in the correct record + if (hostingRecord.isTypeActivity()) { + final boolean wasPackageEverLaunched = mService .wasPackageEverLaunched(r.getApplicationInfo().packageName, r.userId); - // If the package was launched in the past but is currently stopped, only then it - // should be considered as stopped after use. Do not mark it if it's the - // first launch. - if (wasPackageEverLaunched) { - r.setWasForceStopped(true); - } - } catch (IllegalArgumentException e) { - // App doesn't have state yet, so wasn't forcestopped + // If the package was launched in the past but is currently stopped, only then + // should it be considered as force-stopped. + @WindowProcessController.StoppedState int stoppedState = wasPackageEverLaunched + ? STOPPED_STATE_FORCE_STOPPED + : STOPPED_STATE_FIRST_LAUNCH; + r.getWindowProcessController().setStoppedState(stoppedState); + } else { + r.setWasForceStopped(true); + // first launch is computed just before logging, for non-activity types } } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 7356588b408a..9fa3a8bf6f3b 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -439,6 +439,7 @@ class ProcessRecord implements WindowProcessListener { final ProcessRecordNode[] mLinkedNodes = new ProcessRecordNode[NUM_NODE_TYPE]; /** Whether the app was launched from a stopped state and is being unstopped. */ + @GuardedBy("mService") volatile boolean mWasForceStopped; void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo, @@ -684,6 +685,11 @@ class ProcessRecord implements WindowProcessListener { @GuardedBy({"mService", "mProcLock"}) void setPid(int pid) { + // If the pid is changing and not the first time pid is being assigned, clear stopped state + // So if the process record is re-used for a different pid, it wouldn't keep the state. + if (pid != mPid && mPid != 0) { + setWasForceStopped(false); + } mPid = pid; mWindowProcessController.setPid(pid); mShortStringName = null; diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING index feab2c05cad6..bac513221c78 100644 --- a/services/core/java/com/android/server/am/TEST_MAPPING +++ b/services/core/java/com/android/server/am/TEST_MAPPING @@ -8,6 +8,7 @@ { "include-filter": "android.app.cts.ActivityManagerProcessStateTest" }, { "include-filter": "android.app.cts.ServiceTest" }, { "include-filter": "android.app.cts.ActivityManagerFgsBgStartTest" }, + { "include-filter": "android.app.cts.ForceStopTest" }, { "include-annotation": "android.platform.test.annotations.Presubmit" }, diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 13a1807b3563..70d447fce18a 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -646,7 +646,7 @@ class UserController implements Handler.Callback { new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, AppOpsManager.OP_NONE, getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED) - .toBundle(), true, + .toBundle(), false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), userId); } @@ -740,7 +740,7 @@ class UserController implements Handler.Callback { unlockedIntent.addFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); mInjector.broadcastIntent(unlockedIntent, null, null, 0, null, - null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + null, null, AppOpsManager.OP_NONE, null, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), userId); } @@ -765,7 +765,7 @@ class UserController implements Handler.Callback { | Intent.FLAG_RECEIVER_FOREGROUND); mInjector.broadcastIntent(profileUnlockedIntent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + null, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), parent.id); } } @@ -824,7 +824,7 @@ class UserController implements Handler.Callback { initializeUser.run(); } }, 0, null, null, null, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + null, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), userId); } } @@ -876,7 +876,7 @@ class UserController implements Handler.Callback { new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, AppOpsManager.OP_NONE, getTemporaryAppAllowlistBroadcastOptions(REASON_BOOT_COMPLETED).toBundle(), - true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId); + false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId); }); } @@ -1124,7 +1124,7 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(stoppingIntent, null, stoppingReceiver, 0, null, null, new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + null, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); }); } @@ -1187,7 +1187,7 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(shutdownIntent, null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + null, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), userId); } @@ -1464,7 +1464,7 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), + null, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.USER_ALL); // Send PROFILE_INACCESSIBLE broadcast if a profile was stopped @@ -2404,7 +2404,7 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(intent, /* resolvedType= */ null, /* resultTo= */ null, /* resultCode= */ 0, /* resultData= */ null, /* resultExtras= */ null, /* requiredPermissions= */ null, AppOpsManager.OP_NONE, /* bOptions= */ null, - /* ordered= */ false, /* sticky= */ false, MY_PID, SYSTEM_UID, + /* sticky= */ false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId); } @@ -2432,7 +2432,7 @@ class UserController implements Handler.Callback { } }, /* resultCode= */ 0, /* resultData= */ null, /* resultExtras= */ null, new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, /* bOptions= */ null, - /* ordered= */ true, /* sticky= */ false, MY_PID, SYSTEM_UID, + /* sticky= */ false, MY_PID, SYSTEM_UID, callingUid, callingPid, UserHandle.USER_ALL); } @@ -2457,7 +2457,7 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER, UserHandle.of(profileUserId)); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + null, false, MY_PID, SYSTEM_UID, callingUid, callingPid, profileUserId); } } @@ -2476,7 +2476,7 @@ class UserController implements Handler.Callback { intent.putExtra(Intent.EXTRA_USER, UserHandle.of(profileUserId)); mInjector.broadcastIntent(intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + null, false, MY_PID, SYSTEM_UID, callingUid, callingPid, profileUserId); } intent = new Intent(Intent.ACTION_USER_SWITCHED); @@ -2489,7 +2489,7 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(intent, null, null, 0, null, null, new String[] {android.Manifest.permission.MANAGE_USERS}, - AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid, + AppOpsManager.OP_NONE, null, false, MY_PID, SYSTEM_UID, callingUid, callingPid, UserHandle.USER_ALL); } } finally { @@ -2513,7 +2513,7 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(intent, /* resolvedType= */ null, /* resultTo= */ null, /* resultCode= */ 0, /* resultData= */ null, /* resultExtras= */ null, /* requiredPermissions= */ null, AppOpsManager.OP_NONE, /* bOptions= */ - null, /* ordered= */ false, /* sticky= */ false, MY_PID, SYSTEM_UID, + null, /* sticky= */ false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), parentId); } @@ -3576,7 +3576,7 @@ class UserController implements Handler.Callback { protected int broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, - boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, + boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, @UserIdInt int userId) { int logUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); @@ -3585,21 +3585,13 @@ class UserController implements Handler.Callback { } EventLog.writeEvent(EventLogTags.UC_SEND_USER_BROADCAST, logUserId, intent.getAction()); - // When the modern broadcast stack is enabled, deliver all our - // broadcasts as unordered, since the modern stack has better - // support for sequencing cold-starts, and it supports delivering - // resultTo for non-ordered broadcasts - if (mService.mEnableModernQueue) { - ordered = false; - } - TimingsTraceAndSlog t = new TimingsTraceAndSlog(); // TODO b/64165549 Verify that mLock is not held before calling AMS methods synchronized (mService) { t.traceBegin("broadcastIntent-" + userId + "-" + intent.getAction()); final int result = mService.broadcastIntentLocked(null, null, null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, - requiredPermissions, null, null, appOp, bOptions, ordered, sticky, + requiredPermissions, null, null, appOp, bOptions, false, sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId); t.traceEnd(); return result; diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 38051c13049c..177c345686b9 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -19,8 +19,9 @@ package com.android.server.devicestate; import static android.Manifest.permission.CONTROL_DEVICE_STATE; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.hardware.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; @@ -75,6 +76,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -109,6 +111,12 @@ public final class DeviceStateManagerService extends SystemService { private static final String TAG = "DeviceStateManagerService"; private static final boolean DEBUG = false; + /** {@link DeviceState} to model an invalid device state */ + // TODO(b/328314031): Investigate how we can remove this constant + private static final DeviceState INVALID_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(INVALID_DEVICE_STATE_IDENTIFIER, + "INVALID").build()); + private final Object mLock = new Object(); // Handler on the {@link DisplayThread} used to dispatch calls to the policy and to registered // callbacks though its handler (mHandler). Provides a guarantee of callback order when @@ -354,16 +362,22 @@ public final class DeviceStateManagerService extends SystemService { } /** Returns the list of currently supported device states. */ - DeviceState[] getSupportedStates() { + List<DeviceState> getSupportedStates() { synchronized (mLock) { - DeviceState[] supportedStates = new DeviceState[mDeviceStates.size()]; - for (int i = 0; i < supportedStates.length; i++) { - supportedStates[i] = mDeviceStates.valueAt(i); - } - return supportedStates; + return getSupportedStatesLocked(); } } + /** Returns the list of currently supported device states */ + @GuardedBy("mLock") + private List<DeviceState> getSupportedStatesLocked() { + List<DeviceState> supportedStates = new ArrayList<>(mDeviceStates.size()); + for (int i = 0; i < mDeviceStates.size(); i++) { + supportedStates.add(i, mDeviceStates.valueAt(i)); + } + return supportedStates; + } + /** Returns the list of currently supported device state identifiers. */ private int[] getSupportedStateIdentifiersLocked() { int[] supportedStates = new int[mDeviceStates.size()]; @@ -375,20 +389,46 @@ public final class DeviceStateManagerService extends SystemService { /** * Returns the current {@link DeviceStateInfo} of the device. If there has been no base state - * or committed state provided, {@link DeviceStateManager#INVALID_DEVICE_STATE} will be returned + * or committed state provided, {@link #INVALID_DEVICE_STATE} will be returned * respectively. The supported states will always be included. * */ @GuardedBy("mLock") @NonNull private DeviceStateInfo getDeviceStateInfoLocked() { - final int[] supportedStates = getSupportedStateIdentifiersLocked(); - final int baseState = - mBaseState.isPresent() ? mBaseState.get().getIdentifier() : INVALID_DEVICE_STATE; - final int currentState = mCommittedState.isPresent() ? mCommittedState.get().getIdentifier() - : INVALID_DEVICE_STATE; + final List<DeviceState> supportedStates = getSupportedStatesLocked(); + final DeviceState baseState = mBaseState.orElse(null); + final DeviceState currentState = mCommittedState.orElse(null); + + return new DeviceStateInfo(supportedStates, + baseState != null ? baseState : INVALID_DEVICE_STATE, + createMergedDeviceState(currentState, baseState)); + } + + /** + * Returns a {@link DeviceState} with the combined properties of the current system state, as + * well as the physical property that corresponds to the base state (physical hardware state) of + * the device. + */ + private DeviceState createMergedDeviceState(@Nullable DeviceState committedState, + @Nullable DeviceState baseState) { + if (committedState == null) { + return INVALID_DEVICE_STATE; + } - return new DeviceStateInfo(supportedStates, baseState, currentState); + Set<@DeviceState.DeviceStateProperties Integer> systemProperties = + committedState.getConfiguration().getSystemProperties(); + + Set<@DeviceState.DeviceStateProperties Integer> physicalProperties = + baseState != null ? baseState.getConfiguration().getPhysicalProperties() + : Collections.emptySet(); + + DeviceState.Configuration deviceStateConfiguration = new DeviceState.Configuration.Builder( + committedState.getIdentifier(), committedState.getName()) + .setSystemProperties(systemProperties) + .setPhysicalProperties(physicalProperties) + .build(); + return new DeviceState(deviceStateConfiguration); } @VisibleForTesting @@ -408,7 +448,7 @@ public final class DeviceStateManagerService extends SystemService { mDeviceStates.clear(); for (int i = 0; i < supportedDeviceStates.length; i++) { DeviceState state = supportedDeviceStates[i]; - if (state.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) { + if (state.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)) { hasTerminalDeviceState = true; } mDeviceStates.put(state.getIdentifier(), state); @@ -436,7 +476,7 @@ public final class DeviceStateManagerService extends SystemService { private void setRearDisplayStateLocked() { int rearDisplayIdentifier = getContext().getResources().getInteger( R.integer.config_deviceStateRearDisplay); - if (rearDisplayIdentifier != INVALID_DEVICE_STATE) { + if (rearDisplayIdentifier != INVALID_DEVICE_STATE_IDENTIFIER) { mRearDisplayState = mDeviceStates.get(rearDisplayIdentifier); } } @@ -453,7 +493,7 @@ public final class DeviceStateManagerService extends SystemService { * Returns the {@link DeviceState} with the supplied {@code identifier}, or {@code null} if * there is no device state with the identifier. */ - @Nullable + @NonNull private Optional<DeviceState> getStateLocked(int identifier) { return Optional.ofNullable(mDeviceStates.get(identifier)); } @@ -468,7 +508,7 @@ public final class DeviceStateManagerService extends SystemService { private void setBaseState(int identifier) { synchronized (mLock) { final Optional<DeviceState> baseStateOptional = getStateLocked(identifier); - if (!baseStateOptional.isPresent()) { + if (baseStateOptional.isEmpty()) { throw new IllegalArgumentException("Base state is not supported"); } @@ -484,7 +524,7 @@ public final class DeviceStateManagerService extends SystemService { } mBaseState = Optional.of(baseState); - if (baseState.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) { + if (baseState.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)) { mOverrideRequestController.cancelOverrideRequest(); } mOverrideRequestController.handleBaseStateChanged(identifier); @@ -1023,7 +1063,7 @@ public final class DeviceStateManagerService extends SystemService { } private Set<Integer> readFoldedStates() { - Set<Integer> foldedStates = new HashSet(); + Set<Integer> foldedStates = new HashSet<>(); int[] mFoldedStatesArray = getContext().getResources().getIntArray( com.android.internal.R.array.config_foldedDeviceStates); for (int i = 0; i < mFoldedStatesArray.length; i++) { @@ -1338,7 +1378,7 @@ public final class DeviceStateManagerService extends SystemService { } int identifier = mActiveOverride.get().getRequestedStateIdentifier(); DeviceState deviceState = mDeviceStates.get(identifier); - return deviceState.hasFlag(DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); + return deviceState.hasProperty(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); } private class OverrideRequestScreenObserver implements diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java index 02c9bb3b9deb..97913de32076 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java @@ -25,7 +25,7 @@ import android.os.Binder; import android.os.ShellCommand; import java.io.PrintWriter; -import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -177,17 +177,18 @@ public class DeviceStateManagerShellCommand extends ShellCommand { } private int runPrintStates(PrintWriter pw) { - DeviceState[] states = mService.getSupportedStates(); + List<DeviceState> states = mService.getSupportedStates(); pw.print("Supported states: [\n"); - for (int i = 0; i < states.length; i++) { - pw.print(" " + states[i] + ",\n"); + for (int i = 0; i < states.size(); i++) { + pw.print(" " + states.get(i) + ",\n"); } pw.println("]"); return 0; } private int runPrintStatesSimple(PrintWriter pw) { - pw.print(Arrays.stream(mService.getSupportedStates()) + pw.print(mService.getSupportedStates() + .stream() .map(DeviceState::getIdentifier) .map(Object::toString) .collect(Collectors.joining(","))); diff --git a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java index f9aefd0535d0..46478c139aca 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java @@ -323,7 +323,7 @@ class DeviceStateNotificationController extends BroadcastReceiver { for (int i = 0; i < stateIdentifiers.length; i++) { int identifier = stateIdentifiers[i]; - if (identifier == DeviceStateManager.INVALID_DEVICE_STATE) { + if (identifier == DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER) { continue; } diff --git a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java index b865c1d90a49..8d07609cef30 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java @@ -28,8 +28,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Responsible for providing the set of supported {@link DeviceState device states} as well as the - * current device state. + * Responsible for providing the set of supported {@link DeviceState.Configuration device states} as + * well as the current device state. * * @see DeviceStatePolicy */ diff --git a/services/core/java/com/android/server/devicestate/OverrideRequest.java b/services/core/java/com/android/server/devicestate/OverrideRequest.java index d92629f77a95..df7301eee93e 100644 --- a/services/core/java/com/android/server/devicestate/OverrideRequest.java +++ b/services/core/java/com/android/server/devicestate/OverrideRequest.java @@ -72,8 +72,9 @@ final class OverrideRequest { @Retention(RetentionPolicy.SOURCE) public @interface OverrideRequestType {} - OverrideRequest(IBinder token, int pid, int uid, @NonNull DeviceState requestedState, - @DeviceStateRequest.RequestFlags int flags, @OverrideRequestType int requestType) { + OverrideRequest(IBinder token, int pid, int uid, + @NonNull DeviceState requestedState, @DeviceStateRequest.RequestFlags int flags, + @OverrideRequestType int requestType) { mToken = token; mPid = pid; mUid = uid; diff --git a/services/core/java/com/android/server/devicestate/OverrideRequestController.java b/services/core/java/com/android/server/devicestate/OverrideRequestController.java index 6c3fd83d17a0..041ab3ad9d2d 100644 --- a/services/core/java/com/android/server/devicestate/OverrideRequestController.java +++ b/services/core/java/com/android/server/devicestate/OverrideRequestController.java @@ -205,8 +205,8 @@ final class OverrideRequestController { } if (mRequest != null && mRequest.getPid() == pid) { - if (mRequest.getRequestedDeviceState().hasFlag( - DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP)) { + if (mRequest.getRequestedDeviceState().hasProperty( + DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP)) { cancelCurrentRequestLocked(); return; } diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java index e54f30fa29f1..146810f5e1e6 100644 --- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java +++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java @@ -51,7 +51,7 @@ import javax.xml.datatype.DatatypeConfigurationException; class DeviceStateToLayoutMap { private static final String TAG = "DeviceStateToLayoutMap"; - public static final int STATE_DEFAULT = DeviceStateManager.INVALID_DEVICE_STATE; + public static final int STATE_DEFAULT = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; // Direction of the display relative to the default display, whilst in this state private static final int POSITION_UNKNOWN = Layout.Display.POSITION_UNKNOWN; diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index ad89444edcfd..ce7c22438d54 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -284,6 +284,8 @@ public final class DisplayManagerService extends SystemService { // Display mode chosen by user. private Display.Mode mUserPreferredMode; + @HdrConversionMode.ConversionMode + private final int mDefaultHdrConversionMode; // HDR conversion mode chosen by user @GuardedBy("mSyncRoot") private HdrConversionMode mHdrConversionMode = null; @@ -582,6 +584,10 @@ public final class DisplayManagerService extends SystemService { mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1); + mDefaultHdrConversionMode = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_enableDefaultHdrConversionPassthrough) + ? HdrConversionMode.HDR_CONVERSION_PASSTHROUGH + : HdrConversionMode.HDR_CONVERSION_SYSTEM; float[] lux = getFloatArray(resources.obtainTypedArray( com.android.internal.R.array.config_minimumBrightnessCurveLux)); float[] nits = getFloatArray(resources.obtainTypedArray( @@ -2236,7 +2242,7 @@ public final class DisplayManagerService extends SystemService { @GuardedBy("mSyncRoot") void updateHdrConversionModeSettingsLocked() { final int conversionMode = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.HDR_CONVERSION_MODE, HdrConversionMode.HDR_CONVERSION_SYSTEM); + Settings.Global.HDR_CONVERSION_MODE, mDefaultHdrConversionMode); final int preferredHdrOutputType = conversionMode == HdrConversionMode.HDR_CONVERSION_FORCE ? Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.HDR_FORCE_CONVERSION_TYPE, @@ -2461,7 +2467,7 @@ public final class DisplayManagerService extends SystemService { return mHdrConversionMode; } } - return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM); + return new HdrConversionMode(mDefaultHdrConversionMode); } HdrConversionMode getHdrConversionModeInternal() { @@ -2473,6 +2479,14 @@ public final class DisplayManagerService extends SystemService { mode = mOverrideHdrConversionMode != null ? mOverrideHdrConversionMode : mHdrConversionMode; + // Handle default: PASSTHROUGH. Don't include the system-preferred type. + if (mode == null + && mDefaultHdrConversionMode == HdrConversionMode.HDR_CONVERSION_PASSTHROUGH) { + return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH); + } + // Handle default or current mode: SYSTEM. Include the system preferred type. + // mOverrideHdrConversionMode and mHdrConversionMode do not include the system + // preferred type, it is kept separately in mSystemPreferredHdrOutputType. if (mode == null || mode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM) { return new HdrConversionMode( @@ -5021,7 +5035,7 @@ public final class DisplayManagerService extends SystemService { */ class DeviceStateListener implements DeviceStateManager.DeviceStateCallback { // Base state corresponds to the physical state of the device - private int mBaseState = DeviceStateManager.INVALID_DEVICE_STATE; + private int mBaseState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; @Override public void onStateChanged(int deviceState) { diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 2e8de31f2af1..3452e0f188c3 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -192,9 +192,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private final DisplayIdProducer mIdProducer = (isDefault) -> isDefault ? DEFAULT_DISPLAY : sNextNonDefaultDisplayId++; private Layout mCurrentLayout = null; - private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE; - private int mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE; - private int mDeviceStateToBeAppliedAfterBoot = DeviceStateManager.INVALID_DEVICE_STATE; + private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; + private int mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; + private int mDeviceStateToBeAppliedAfterBoot = + DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; private boolean mBootCompleted = false; private boolean mInteractive; private final DisplayManagerFlags mFlags; @@ -460,7 +461,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { // temporarily turned off. resetLayoutLocked(mDeviceState, state, /* transitionValue= */ true); mPendingDeviceState = state; - mDeviceStateToBeAppliedAfterBoot = DeviceStateManager.INVALID_DEVICE_STATE; + mDeviceStateToBeAppliedAfterBoot = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState, mInteractive, mBootCompleted); final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState, @@ -510,7 +511,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { void onBootCompleted() { synchronized (mSyncRoot) { mBootCompleted = true; - if (mDeviceStateToBeAppliedAfterBoot != DeviceStateManager.INVALID_DEVICE_STATE) { + if (mDeviceStateToBeAppliedAfterBoot + != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER) { setDeviceStateLocked(mDeviceStateToBeAppliedAfterBoot, /* isOverrideActive= */ false); } @@ -568,7 +570,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { @VisibleForTesting boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isOverrideActive, boolean isInteractive, boolean isBootCompleted) { - return currentState != DeviceStateManager.INVALID_DEVICE_STATE + return currentState != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER && mDeviceStatesOnWhichToSleep.get(pendingState) && !mDeviceStatesOnWhichToSleep.get(currentState) && !isOverrideActive @@ -598,13 +600,13 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { private void transitionToPendingStateLocked() { resetLayoutLocked(mDeviceState, mPendingDeviceState, /* transitionValue= */ false); mDeviceState = mPendingDeviceState; - mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE; + mPendingDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; applyLayoutLocked(); updateLogicalDisplaysLocked(); } private void finishStateTransitionLocked(boolean force) { - if (mPendingDeviceState == DeviceStateManager.INVALID_DEVICE_STATE) { + if (mPendingDeviceState == DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER) { return; } diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index c6d66db3f8cd..d9970204cf66 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -982,6 +982,18 @@ public final class DreamManagerService extends SystemService { } @Override // Binder call + public boolean canStartDreaming(boolean isScreenOn) { + checkPermission(android.Manifest.permission.READ_DREAM_STATE); + + final long ident = Binder.clearCallingIdentity(); + try { + return canStartDreamingInternal(isScreenOn); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call public void testDream(int userId, ComponentName dream) { if (dream == null) { throw new IllegalArgumentException("dream must not be null"); diff --git a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java index 252ea4b08464..0ef23e903b6a 100644 --- a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java +++ b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java @@ -126,7 +126,7 @@ public class GrammaticalInflectionService extends SystemService { @Override public void setSystemWideGrammaticalGender(int grammaticalGender, int userId) { - checkCallerIsSystem(); + isCallerAllowed(); GrammaticalInflectionService.this.setSystemWideGrammaticalGender(grammaticalGender, userId); } @@ -154,7 +154,7 @@ public class GrammaticalInflectionService extends SystemService { @Override @Nullable public byte[] getBackupPayload(int userId) { - checkCallerIsSystem(); + isCallerAllowed(); return mBackupHelper.getBackupPayload(userId); } @@ -333,11 +333,13 @@ public class GrammaticalInflectionService extends SystemService { return GRAMMATICAL_GENDER_NOT_SPECIFIED; } - private void checkCallerIsSystem() { + private void isCallerAllowed() { int callingUid = Binder.getCallingUid(); if (callingUid != Process.SYSTEM_UID && callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) { - throw new SecurityException("Caller is not system, shell and root."); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_CONFIGURATION, + "Caller must be system, shell, root or has CHANGE_CONFIGURATION permission."); } } diff --git a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java index f60f55c11935..7acc3efe8564 100644 --- a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java +++ b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java @@ -374,6 +374,7 @@ public final class MediaMetricsManagerService extends SystemService { event.getInputMediaItemInfos().isEmpty() ? EMPTY_MEDIA_ITEM_INFO : event.getInputMediaItemInfos().get(0); + @MediaItemInfo.DataType long inputDataTypes = inputMediaItemInfo.getDataTypes(); String inputAudioSampleMimeType = getFilteredFirstMimeType( inputMediaItemInfo.getSampleMimeTypes(), AUDIO_MIME_TYPE_PREFIX); @@ -396,6 +397,7 @@ public final class MediaMetricsManagerService extends SystemService { event.getOutputMediaItemInfo() == null ? EMPTY_MEDIA_ITEM_INFO : event.getOutputMediaItemInfo(); + @MediaItemInfo.DataType long outputDataTypes = outputMediaItemInfo.getDataTypes(); String outputAudioSampleMimeType = getFilteredFirstMimeType( outputMediaItemInfo.getSampleMimeTypes(), AUDIO_MIME_TYPE_PREFIX); @@ -415,6 +417,7 @@ public final class MediaMetricsManagerService extends SystemService { !outputCodecNames.isEmpty() ? outputCodecNames.get(0) : ""; String outputSecondCodecName = outputCodecNames.size() > 1 ? outputCodecNames.get(1) : ""; + @EditingEndedEvent.OperationType long operationTypes = event.getOperationTypes(); StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(798) @@ -423,11 +426,63 @@ public final class MediaMetricsManagerService extends SystemService { .writeFloat(event.getFinalProgressPercent()) .writeInt(event.getErrorCode()) .writeLong(event.getTimeSinceCreatedMillis()) + .writeBoolean( + (operationTypes + & EditingEndedEvent + .OPERATION_TYPE_VIDEO_TRANSCODE) + != 0) + .writeBoolean( + (operationTypes + & EditingEndedEvent + .OPERATION_TYPE_AUDIO_TRANSCODE) + != 0) + .writeBoolean( + (operationTypes & EditingEndedEvent.OPERATION_TYPE_VIDEO_EDIT) + != 0) + .writeBoolean( + (operationTypes & EditingEndedEvent.OPERATION_TYPE_AUDIO_EDIT) + != 0) + .writeBoolean( + (operationTypes + & EditingEndedEvent + .OPERATION_TYPE_VIDEO_TRANSMUX) + != 0) + .writeBoolean( + (operationTypes + & EditingEndedEvent + .OPERATION_TYPE_AUDIO_TRANSMUX) + != 0) + .writeBoolean( + (operationTypes & EditingEndedEvent.OPERATION_TYPE_PAUSED) != 0) + .writeBoolean( + (operationTypes & EditingEndedEvent.OPERATION_TYPE_RESUMED) + != 0) .writeString(getFilteredLibraryName(event.getExporterName())) .writeString(getFilteredLibraryName(event.getMuxerName())) .writeInt(getThroughputFps(event)) .writeInt(event.getInputMediaItemInfos().size()) .writeInt(inputMediaItemInfo.getSourceType()) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_IMAGE) != 0) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_VIDEO) != 0) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_AUDIO) != 0) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_METADATA) != 0) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_DEPTH) != 0) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_GAIN_MAP) != 0) + .writeBoolean( + (inputDataTypes & MediaItemInfo.DATA_TYPE_HIGH_FRAME_RATE) != 0) + .writeBoolean( + (inputDataTypes + & MediaItemInfo + .DATA_TYPE_SPEED_SETTING_CUE_POINTS) + != 0) + .writeBoolean((inputDataTypes & MediaItemInfo.DATA_TYPE_GAPLESS) != 0) + .writeBoolean( + (inputDataTypes & MediaItemInfo.DATA_TYPE_SPATIAL_AUDIO) != 0) + .writeBoolean( + (inputDataTypes + & MediaItemInfo + .DATA_TYPE_HIGH_DYNAMIC_RANGE_VIDEO) + != 0) .writeLong( getBucketedDurationMillis( inputMediaItemInfo.getDurationMillis())) @@ -443,6 +498,7 @@ public final class MediaMetricsManagerService extends SystemService { getFilteredAudioSampleRateHz( inputMediaItemInfo.getAudioSampleRateHz())) .writeInt(inputMediaItemInfo.getAudioChannelCount()) + .writeLong(inputMediaItemInfo.getAudioSampleCount()) .writeInt(inputVideoSize.getWidth()) .writeInt(inputVideoSize.getHeight()) .writeInt(inputVideoResolution) @@ -456,6 +512,28 @@ public final class MediaMetricsManagerService extends SystemService { .writeInt(getVideoFrameRateEnum(inputMediaItemInfo.getVideoFrameRate())) .writeString(inputFirstCodecName) .writeString(inputSecondCodecName) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_IMAGE) != 0) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_VIDEO) != 0) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_AUDIO) != 0) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_METADATA) != 0) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_DEPTH) != 0) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_GAIN_MAP) != 0) + .writeBoolean( + (outputDataTypes & MediaItemInfo.DATA_TYPE_HIGH_FRAME_RATE) + != 0) + .writeBoolean( + (outputDataTypes + & MediaItemInfo + .DATA_TYPE_SPEED_SETTING_CUE_POINTS) + != 0) + .writeBoolean((outputDataTypes & MediaItemInfo.DATA_TYPE_GAPLESS) != 0) + .writeBoolean( + (outputDataTypes & MediaItemInfo.DATA_TYPE_SPATIAL_AUDIO) != 0) + .writeBoolean( + (outputDataTypes + & MediaItemInfo + .DATA_TYPE_HIGH_DYNAMIC_RANGE_VIDEO) + != 0) .writeLong( getBucketedDurationMillis( outputMediaItemInfo.getDurationMillis())) @@ -471,6 +549,7 @@ public final class MediaMetricsManagerService extends SystemService { getFilteredAudioSampleRateHz( outputMediaItemInfo.getAudioSampleRateHz())) .writeInt(outputMediaItemInfo.getAudioChannelCount()) + .writeLong(outputMediaItemInfo.getAudioSampleCount()) .writeInt(outputVideoSize.getWidth()) .writeInt(outputVideoSize.getHeight()) .writeInt(outputVideoResolution) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b98424cfade4..e7455dbad949 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -8210,7 +8210,7 @@ public class NotificationManagerService extends SystemService { try { return mTelecomManager.isInManagedCall() || mTelecomManager.isInSelfManagedCall(pkg, - /* hasCrossUserAccess */ true); + UserHandle.ALL); } catch (IllegalStateException ise) { // Telecom is not ready (this is likely early boot), so there are no calls. return false; diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java index 9af2b3f6e2ae..278deb84996d 100644 --- a/services/core/java/com/android/server/pm/BroadcastHelper.java +++ b/services/core/java/com/android/server/pm/BroadcastHelper.java @@ -207,18 +207,8 @@ public final class BroadcastHelper { + intent.toShortString(false, true, false, false) + " " + intent.getExtras(), here); } - final boolean ordered; - if (mAmInternal.isModernQueueEnabled()) { - // When the modern broadcast stack is enabled, deliver all our - // broadcasts as unordered, since the modern stack has better - // support for sequencing cold-starts, and it supports - // delivering resultTo for non-ordered broadcasts - ordered = false; - } else { - ordered = (finishedReceiver != null); - } - mAmInternal.broadcastIntent( - intent, finishedReceiver, requiredPermissions, ordered, userId, + mAmInternal.broadcastIntentWithCallback( + intent, finishedReceiver, requiredPermissions, userId, broadcastAllowList == null ? null : broadcastAllowList.get(userId), filterExtrasForReceiver, bOptions); } diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java index 29de26e41df4..ec98fff25af7 100644 --- a/services/core/java/com/android/server/pm/PackageArchiver.java +++ b/services/core/java/com/android/server/pm/PackageArchiver.java @@ -557,6 +557,28 @@ public class PackageArchiver { } /** + * An extension of {@link BitmapDrawable} which returns the bitmap pixel size as intrinsic size. + * This allows the badging to be done based on the actual bitmap size rather than + * the scaled bitmap size. + */ + private static class FixedSizeBitmapDrawable extends BitmapDrawable { + + FixedSizeBitmapDrawable(@Nullable final Bitmap bitmap) { + super(null, bitmap); + } + + @Override + public int getIntrinsicHeight() { + return getBitmap().getWidth(); + } + + @Override + public int getIntrinsicWidth() { + return getBitmap().getWidth(); + } + } + + /** * Create an <a * href="https://developer.android.com/develop/ui/views/launch/icon_design_adaptive"> * adaptive icon</a> from an icon. @@ -569,6 +591,11 @@ public class PackageArchiver { } // see BaseIconFactory#createShapedIconBitmap + if (iconDrawable instanceof BitmapDrawable) { + var icon = ((BitmapDrawable) iconDrawable).getBitmap(); + iconDrawable = new FixedSizeBitmapDrawable(icon); + } + float inset = getExtraInsetFraction(); inset = inset / (1 + 2 * inset); Drawable d = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java index 1b220a0b1485..453c6ef41437 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -16,7 +16,7 @@ package com.android.server.policy; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import android.annotation.NonNull; @@ -45,9 +45,9 @@ import com.android.server.devicestate.DeviceStateProvider; import com.android.server.input.InputManagerInternal; import com.android.server.policy.devicestate.config.Conditions; import com.android.server.policy.devicestate.config.DeviceStateConfig; -import com.android.server.policy.devicestate.config.Flags; import com.android.server.policy.devicestate.config.LidSwitchCondition; import com.android.server.policy.devicestate.config.NumericRange; +import com.android.server.policy.devicestate.config.Properties; import com.android.server.policy.devicestate.config.SensorCondition; import com.android.server.policy.devicestate.config.XmlParser; @@ -63,8 +63,10 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.BooleanSupplier; import javax.xml.datatype.DatatypeConfigurationException; @@ -94,21 +96,49 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, private static final BooleanSupplier FALSE_BOOLEAN_SUPPLIER = () -> false; @VisibleForTesting - static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE_IDENTIFIER, - "DEFAULT", 0 /* flags */); + static final DeviceState DEFAULT_DEVICE_STATE = + new DeviceState(new DeviceState.Configuration.Builder(MINIMUM_DEVICE_STATE_IDENTIFIER, + "DEFAULT").build()); private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/"; private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/"; private static final String CONFIG_FILE_NAME = "device_state_configuration.xml"; - private static final String FLAG_CANCEL_OVERRIDE_REQUESTS = "FLAG_CANCEL_OVERRIDE_REQUESTS"; - private static final String FLAG_APP_INACCESSIBLE = "FLAG_APP_INACCESSIBLE"; - private static final String FLAG_EMULATED_ONLY = "FLAG_EMULATED_ONLY"; - private static final String FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = - "FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP"; - private static final String FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = - "FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL"; - private static final String FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE = - "FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE"; + private static final String PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED = + "com.android.server.policy.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED"; + private static final String PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN = + "com.android.server.policy.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN"; + private static final String PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN = + "com.android.server.policy.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN"; + private static final String PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS = + "com.android.server.policy.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS"; + private static final String PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = + "com.android.server.policy.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP"; + private static final String PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = + "com.android.server.policy.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL"; + private static final String PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE = + "com.android.server.policy.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE"; + private static final String PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = + "com.android.server.policy.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST"; + private static final String PROPERTY_APP_INACCESSIBLE = + "com.android.server.policy.PROPERTY_APP_INACCESSIBLE"; + private static final String PROPERTY_EMULATED_ONLY = + "com.android.server.policy.PROPERTY_EMULATED_ONLY"; + private static final String PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY = + "com.android.server.policy.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY"; + private static final String PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY = + "com.android.server.policy.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY"; + private static final String PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP = + "com.android.server.policy.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP"; + private static final String PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE = + "com.android.server.policy.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE"; + private static final String PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY = + "com.android.server.policy.PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY"; + private static final String PROPERTY_FEATURE_REAR_DISPLAY = + "com.android.server.policy.PROPERTY_FEATURE_REAR_DISPLAY"; + private static final String PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT = + "com.android.server.policy.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT"; + + /** Interface that allows reading the device state configuration. */ interface ReadableConfig { @@ -149,40 +179,25 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, final int state = stateConfig.getIdentifier().intValue(); final String name = stateConfig.getName() == null ? "" : stateConfig.getName(); - int flags = 0; - final Flags configFlags = stateConfig.getFlags(); + Set<@DeviceState.DeviceStateProperties Integer> systemProperties = + new HashSet<>(); + Set<@DeviceState.DeviceStateProperties Integer> physicalProperties = + new HashSet<>(); + final Properties configFlags = stateConfig.getProperties(); if (configFlags != null) { - List<String> configFlagStrings = configFlags.getFlag(); - for (int i = 0; i < configFlagStrings.size(); i++) { - final String configFlagString = configFlagStrings.get(i); - switch (configFlagString) { - case FLAG_CANCEL_OVERRIDE_REQUESTS: - flags |= DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS; - break; - case FLAG_APP_INACCESSIBLE: - flags |= DeviceState.FLAG_APP_INACCESSIBLE; - break; - case FLAG_EMULATED_ONLY: - flags |= DeviceState.FLAG_EMULATED_ONLY; - break; - case FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP: - flags |= DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; - break; - case FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL: - flags |= DeviceState - .FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL; - break; - case FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE: - flags |= DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE; - default: - Slog.w(TAG, "Parsed unknown flag with name: " - + configFlagString); - break; - } + List<String> configPropertyStrings = configFlags.getProperty(); + for (int i = 0; i < configPropertyStrings.size(); i++) { + final String configPropertyString = configPropertyStrings.get(i); + addPropertyByString(configPropertyString, systemProperties, + physicalProperties); } } - - deviceStateList.add(new DeviceState(state, name, flags)); + DeviceState.Configuration deviceStateConfiguration = + new DeviceState.Configuration.Builder(state, name) + .setSystemProperties(systemProperties) + .setPhysicalProperties(physicalProperties) + .build(); + deviceStateList.add(new DeviceState(deviceStateConfiguration)); final Conditions condition = stateConfig.getConditions(); conditionsList.add(condition); @@ -190,13 +205,88 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } } - if (deviceStateList.size() == 0) { + if (deviceStateList.isEmpty()) { deviceStateList.add(DEFAULT_DEVICE_STATE); conditionsList.add(null); } return new DeviceStateProviderImpl(context, deviceStateList, conditionsList); } + private static void addPropertyByString(String propertyString, + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties, + Set<@DeviceState.PhysicalDeviceStateProperties Integer> physicalProperties) { + switch (propertyString) { + // Look for the physical hardware properties first + case PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED: + physicalProperties.add( + DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED); + break; + case PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN: + physicalProperties.add( + DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN); + break; + case PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN: + physicalProperties.add( + DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN); + break; + case PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS: + systemProperties.add( + DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS); + break; + case PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP: + systemProperties.add( + DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); + break; + case PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL: + systemProperties.add( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL); + break; + case PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE: + systemProperties.add( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE); + break; + case PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST: + systemProperties.add( + DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST); + break; + case PROPERTY_APP_INACCESSIBLE: + systemProperties.add(DeviceState.PROPERTY_APP_INACCESSIBLE); + break; + case PROPERTY_EMULATED_ONLY: + systemProperties.add(DeviceState.PROPERTY_EMULATED_ONLY); + break; + case PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY: + systemProperties.add( + DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY); + break; + case PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY: + systemProperties.add( + DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY); + break; + case PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP: + systemProperties.add( + DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP); + break; + case PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE: + systemProperties.add( + DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE); + break; + case PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY: + systemProperties.add( + DeviceState.PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY); + break; + case PROPERTY_FEATURE_REAR_DISPLAY: + systemProperties.add(DeviceState.PROPERTY_FEATURE_REAR_DISPLAY); + break; + case PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT: + systemProperties.add(DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT); + break; + default: + Slog.w(TAG, "Parsed unknown flag with name: " + propertyString); + break; + } + } + // Lock for internal state. private final Object mLock = new Object(); private final Context mContext; @@ -210,7 +300,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, @GuardedBy("mLock") private Listener mListener = null; @GuardedBy("mLock") - private int mLastReportedState = INVALID_DEVICE_STATE; + private int mLastReportedState = INVALID_DEVICE_STATE_IDENTIFIER; @GuardedBy("mLock") private Boolean mIsLidOpen; @@ -285,7 +375,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, if (conditions == null) { // If this state has the FLAG_EMULATED_ONLY flag on it, it should never be triggered // by a physical hardware change, and should always return false for it's conditions - if (deviceStates.get(i).hasFlag(DeviceState.FLAG_EMULATED_ONLY)) { + if (deviceStates.get(i).hasProperty(DeviceState.PROPERTY_EMULATED_ONLY)) { mStateConditions.put(state, FALSE_BOOLEAN_SUPPLIER); } else { mStateConditions.put(state, TRUE_BOOLEAN_SUPPLIER); @@ -410,13 +500,13 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } listener = mListener; for (DeviceState deviceState : mOrderedStates) { - if (isThermalStatusCriticalOrAbove(mThermalStatus) - && deviceState.hasFlag( - DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { + if (isThermalStatusCriticalOrAbove(mThermalStatus) && deviceState.hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL + )) { continue; } - if (mPowerSaveModeEnabled && deviceState.hasFlag( - DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { + if (mPowerSaveModeEnabled && deviceState.hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { continue; } supportedStates.add(deviceState); @@ -424,18 +514,19 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } listener.onSupportedDeviceStatesChanged( - supportedStates.toArray(new DeviceState[supportedStates.size()]), reason); + supportedStates.toArray(new DeviceState[supportedStates.size()]), + reason); } /** Computes the current device state and notifies the listener of a change, if needed. */ void notifyDeviceStateChangedIfNeeded() { - int stateToReport = INVALID_DEVICE_STATE; + int stateToReport = INVALID_DEVICE_STATE_IDENTIFIER; synchronized (mLock) { if (mListener == null) { return; } - int newState = INVALID_DEVICE_STATE; + int newState = INVALID_DEVICE_STATE_IDENTIFIER; for (int i = 0; i < mOrderedStates.length; i++) { int state = mOrderedStates[i].getIdentifier(); if (DEBUG) { @@ -464,18 +555,18 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, break; } } - if (newState == INVALID_DEVICE_STATE) { + if (newState == INVALID_DEVICE_STATE_IDENTIFIER) { Slog.e(TAG, "No declared device states match any of the required conditions."); dumpSensorValues(); } - if (newState != INVALID_DEVICE_STATE && newState != mLastReportedState) { + if (newState != INVALID_DEVICE_STATE_IDENTIFIER && newState != mLastReportedState) { mLastReportedState = newState; stateToReport = newState; } } - if (stateToReport != INVALID_DEVICE_STATE) { + if (stateToReport != INVALID_DEVICE_STATE_IDENTIFIER) { mListener.onStateChanged(stateToReport); } } @@ -774,8 +865,9 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } private static boolean hasThermalSensitiveState(List<DeviceState> deviceStates) { - for (DeviceState state : deviceStates) { - if (state.hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { + for (int i = 0; i < deviceStates.size(); i++) { + if (deviceStates.get(i).hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { return true; } } @@ -784,7 +876,8 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, private static boolean hasPowerSaveSensitiveState(List<DeviceState> deviceStates) { for (int i = 0; i < deviceStates.size(); i++) { - if (deviceStates.get(i).hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { + if (deviceStates.get(i).hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { return true; } } diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index 652cf18ed257..fde49d210f80 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -902,9 +902,9 @@ public class Notifier { } if (mActivityManagerInternal.isSystemReady()) { - final boolean ordered = !mActivityManagerInternal.isModernQueueEnabled(); - mActivityManagerInternal.broadcastIntent(mScreenOnIntent, mWakeUpBroadcastDone, - null, ordered, UserHandle.USER_ALL, null, null, mScreenOnOffOptions); + mActivityManagerInternal.broadcastIntentWithCallback(mScreenOnIntent, + mWakeUpBroadcastDone, null, UserHandle.USER_ALL, + null, null, mScreenOnOffOptions); } else { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1); sendNextBroadcast(); @@ -927,9 +927,9 @@ public class Notifier { } if (mActivityManagerInternal.isSystemReady()) { - final boolean ordered = !mActivityManagerInternal.isModernQueueEnabled(); - mActivityManagerInternal.broadcastIntent(mScreenOffIntent, mGoToSleepBroadcastDone, - null, ordered, UserHandle.USER_ALL, null, null, mScreenOnOffOptions); + mActivityManagerInternal.broadcastIntentWithCallback(mScreenOffIntent, + mGoToSleepBroadcastDone, null, UserHandle.USER_ALL, + null, null, mScreenOnOffOptions); } else { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1); sendNextBroadcast(); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index a172de0bb0ff..b50e2bf317b5 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -7149,7 +7149,7 @@ public final class PowerManagerService extends SystemService * Any changes to the device state are treated as user interactions. */ class DeviceStateListener implements DeviceStateManager.DeviceStateCallback { - private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE; + private int mDeviceState = DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; @Override public void onStateChanged(int deviceState) { diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index 78f501ad9fed..59a56de16ce6 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -1133,10 +1133,12 @@ class ActivityMetricsLogger { isIncremental = true; isLoading = isIncrementalLoading(info.packageName, info.userId); } - final boolean stopped = (info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; + final boolean stopped = wasStoppedNeedsLogging(info); final int packageState = stopped ? APP_START_OCCURRED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED : APP_START_OCCURRED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; + + final boolean firstLaunch = wasFirstLaunch(info); FrameworkStatsLog.write( FrameworkStatsLog.APP_START_OCCURRED, info.applicationInfo.uid, @@ -1163,18 +1165,26 @@ class ActivityMetricsLogger { TimeUnit.NANOSECONDS.toMillis(info.timestampNs), processState, processOomAdj, - packageState); + packageState, + false, // is_xr_activity + firstLaunch, + 0L /* TODO: stoppedDuration */); + // Reset the stopped state to avoid reporting stopped again + if (info.processRecord != null) { + info.processRecord.setWasStoppedLogged(true); + } if (DEBUG_METRICS) { - Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)", + Slog.i(TAG, String.format( + "APP_START_OCCURRED(%s, %s, %s, %s, %s, wasStopped=%b, firstLaunch=%b)", info.applicationInfo.uid, info.packageName, getAppStartTransitionType(info.type, info.relaunched), info.launchedActivityName, - info.launchedActivityLaunchedFromPackage)); + info.launchedActivityLaunchedFromPackage, + stopped, firstLaunch)); } - logAppStartMemoryStateCapture(info); } @@ -1794,4 +1804,28 @@ class ActivityMetricsLogger { return -1; } } + + private boolean wasStoppedNeedsLogging(TransitionInfoSnapshot info) { + if (info.processRecord != null) { + return (info.processRecord.wasForceStopped() + || info.processRecord.wasFirstLaunch()) + && !info.processRecord.getWasStoppedLogged(); + } else { + return (info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0; + } + } + + private boolean wasFirstLaunch(TransitionInfoSnapshot info) { + if (info.processRecord != null) { + return info.processRecord.wasFirstLaunch() + && !info.processRecord.getWasStoppedLogged(); + } + try { + return !mSupervisor.mService.getPackageManagerInternalLocked() + .wasPackageEverLaunched(info.packageName, info.userId); + } catch (Exception e) { + // Couldn't find the state record, so must be a newly installed app + return true; + } + } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 7ba953dae55c..0069cdd1e4e8 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -50,6 +50,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.activityTypeToString; +import static android.app.WindowConfiguration.isFloating; import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION; import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE; import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON; @@ -75,6 +76,7 @@ import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY; import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED; import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON; +import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED; import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; @@ -332,6 +334,7 @@ import android.service.contentcapture.ActivityEvent; import android.service.dreams.DreamActivity; import android.service.voice.IVoiceInteractionSession; import android.util.ArraySet; +import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; import android.util.MergedConfiguration; @@ -3717,8 +3720,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean endTask = task.getTopNonFinishingActivity() == null && !task.isClearingToReuseTask(); + final WindowContainer<?> trigger = endTask ? task : this; final Transition newTransition = - mTransitionController.requestCloseTransitionIfNeeded(endTask ? task : this); + mTransitionController.requestCloseTransitionIfNeeded(trigger); + if (newTransition != null) { + newTransition.collectClose(trigger); + } else if (mTransitionController.isCollecting()) { + mTransitionController.getCollectingTransition().collectClose(trigger); + } if (isState(RESUMED)) { if (endTask) { mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted( @@ -4377,7 +4386,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // closing the task. final WindowContainer trigger = remove && task != null && task.getChildCount() == 1 ? task : this; - mTransitionController.requestCloseTransitionIfNeeded(trigger); + final Transition newTransit = mTransitionController.requestCloseTransitionIfNeeded(trigger); + if (newTransit != null) { + newTransit.collectClose(trigger); + } else if (mTransitionController.isCollecting()) { + mTransitionController.getCollectingTransition().collectClose(trigger); + } cleanUp(true /* cleanServices */, true /* setState */); if (remove) { if (mStartingData != null && mVisible && task != null) { @@ -8470,6 +8484,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // and back which can cause visible issues (see b/184078928). final int parentWindowingMode = newParentConfiguration.windowConfiguration.getWindowingMode(); + + applySizeOverrideIfNeeded(newParentConfiguration, parentWindowingMode, resolvedConfig); + final boolean isFixedOrientationLetterboxAllowed = parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW || parentWindowingMode == WINDOWING_MODE_FULLSCREEN @@ -8569,6 +8586,87 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** + * If necessary, override configuration fields related to app bounds. + * This will happen when the app is targeting SDK earlier than 35. + * The insets and configuration has decoupled since SDK level 35, to make the system + * compatible to existing apps, override the configuration with legacy metrics. In legacy + * metrics, fields such as appBounds will exclude some of the system bar areas. + * The override contains all potentially affected fields in Configuration, including + * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation. + * All overrides to those fields should be in this method. + */ + private void applySizeOverrideIfNeeded(Configuration newParentConfiguration, + int parentWindowingMode, Configuration inOutConfig) { + if (mDisplayContent == null) { + return; + } + final Rect fullBounds = newParentConfiguration.windowConfiguration.getAppBounds(); + int rotation = newParentConfiguration.windowConfiguration.getRotation(); + if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming()) { + rotation = mDisplayContent.getRotation(); + } + if (!mWmService.mFlags.mInsetsDecoupledConfiguration + || info.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED) + || getCompatDisplayInsets() != null + || isFloating(parentWindowingMode) || fullBounds == null + || fullBounds.isEmpty() || rotation == ROTATION_UNDEFINED) { + // If the insets configuration decoupled logic is not enabled for the app, or the app + // already has a compat override, or the context doesn't contain enough info to + // calculate the override, skip the override. + return; + } + + // Override starts here. + final Rect stableInsets = mDisplayContent.getDisplayPolicy().getDecorInsetsInfo( + rotation, fullBounds.width(), fullBounds.height()).mLegacyConfigInsets; + // This should be the only place override the configuration for ActivityRecord. Override + // the value if not calculated yet. + Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); + if (outAppBounds == null || outAppBounds.isEmpty()) { + inOutConfig.windowConfiguration.setAppBounds(fullBounds); + outAppBounds = inOutConfig.windowConfiguration.getAppBounds(); + outAppBounds.inset(stableInsets); + } + float density = inOutConfig.densityDpi; + if (density == Configuration.DENSITY_DPI_UNDEFINED) { + density = newParentConfiguration.densityDpi; + } + density *= DisplayMetrics.DENSITY_DEFAULT_SCALE; + if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) { + final int overrideScreenWidthDp = (int) (outAppBounds.width() / density + 0.5f); + inOutConfig.screenWidthDp = + Math.min(overrideScreenWidthDp, newParentConfiguration.screenWidthDp); + } + if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) { + final int overrideScreenHeightDp = + (int) (outAppBounds.height() / density + 0.5f); + inOutConfig.screenHeightDp = + Math.min(overrideScreenHeightDp, newParentConfiguration.screenHeightDp); + } + if (inOutConfig.smallestScreenWidthDp + == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED + && parentWindowingMode == WINDOWING_MODE_FULLSCREEN) { + // For the case of PIP transition and multi-window environment, the + // smallestScreenWidthDp is handled already. Override only if the app is in + // fullscreen. + final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); + DisplayInfo info = new DisplayInfo(); + mDisplayContent.getDisplay().getDisplayInfo(info); + mDisplayContent.computeSizeRanges(info, rotated, info.logicalWidth, + info.logicalHeight, mDisplayContent.getDisplayMetrics().density, + inOutConfig, true /* legacyConfig */); + } + + // It's possible that screen size will be considered in different orientation with or + // without considering the system bar insets. Override orientation as well. + if (inOutConfig.orientation == ORIENTATION_UNDEFINED) { + inOutConfig.orientation = + (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp) + ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; + } + } + + /** * @return The orientation to use to understand if reachability is enabled. */ @Configuration.Orientation @@ -8821,6 +8919,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mDisplayContent == null) { return true; } + if (mWmService.mFlags.mInsetsDecoupledConfiguration + && info.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED)) { + // No insets should be considered any more. + return true; + } // Only need to make changes if activity sets an orientation final int requestedOrientation = getRequestedConfigurationOrientation(); if (requestedOrientation == ORIENTATION_UNDEFINED) { @@ -8835,7 +8938,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A : mDisplayContent.getDisplayInfo(); final Task task = getTask(); task.calculateInsetFrames(mTmpBounds /* outNonDecorBounds */, - outStableBounds /* outStableBounds */, parentBounds /* bounds */, di); + outStableBounds /* outStableBounds */, parentBounds /* bounds */, di, + true /* useLegacyInsetsForStableBounds */); final int orientationWithInsets = outStableBounds.height() >= outStableBounds.width() ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; // If orientation does not match the orientation with insets applied, then a diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index e283f3e8ef0e..060f1c8cfac0 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3665,7 +3665,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } /** - * Prepare to enter PiP mode after {@link TransitionController#requestStartTransition}. + * Prepare to enter PiP mode after {@link TransitionController#requestStartDisplayTransition}. * * @param r activity auto entering pip * @return true if the activity is about to auto-enter pip or is already in pip mode. diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 826e332b5f3c..2fc6b5f5ca9a 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -57,6 +57,7 @@ import static com.android.server.wm.ActivityRecord.State.PAUSED; import static com.android.server.wm.ActivityRecord.State.PAUSING; import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS; import static com.android.server.wm.ActivityRecord.State.RESUMED; +import static com.android.server.wm.ActivityRecord.State.STOPPING; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE; @@ -104,6 +105,7 @@ import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.LaunchActivityItem; import android.app.servertransaction.PauseActivityItem; import android.app.servertransaction.ResumeActivityItem; +import android.app.servertransaction.StopActivityItem; import android.companion.virtual.VirtualDeviceManager; import android.content.ComponentName; import android.content.Context; @@ -944,8 +946,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { if (andResume) { lifecycleItem = ResumeActivityItem.obtain(r.token, isTransitionForward, r.shouldSendCompatFakeFocus()); - } else { + } else if (r.isVisibleRequested()) { lifecycleItem = PauseActivityItem.obtain(r.token); + } else { + lifecycleItem = StopActivityItem.obtain(r.token); } // Schedule transaction. @@ -1013,7 +1017,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // a resume. r.setState(RESUMED, "realStartActivityLocked"); r.completeResumeLocked(); - } else { + } else if (r.isVisibleRequested()) { // This activity is not starting in the resumed state... which should look like we asked // it to pause+stop (but remain visible), and it has done so and reported back the // current icicle and other state. @@ -1021,6 +1025,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { + "(starting in paused state)", r); r.setState(PAUSED, "realStartActivityLocked"); mRootWindowContainer.executeAppTransitionForAllDisplay(); + } else { + // This activity is starting while invisible, so it should be stopped. + r.setState(STOPPING, "realStartActivityLocked"); } // Perform OOM scoring after the activity state is set, so the process can be updated with // the latest state. @@ -1598,9 +1605,14 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } private void removePinnedRootTaskInSurfaceTransaction(Task rootTask) { - rootTask.mTransitionController.requestTransitionIfNeeded(TRANSIT_TO_BACK, 0 /* flags */, - rootTask, rootTask.mDisplayContent, null /* remoteTransition */, - null /* displayChange */); + final Transition transition = rootTask.mTransitionController.requestTransitionIfNeeded( + TRANSIT_TO_BACK, 0 /* flags */, rootTask, rootTask.mDisplayContent); + if (transition == null) { + rootTask.mTransitionController.collect(rootTask); + } else { + transition.collect(rootTask); + } + /** * Workaround: Force-stop all the activities in the root pinned task before we reparent them * to the fullscreen root task. This is to guarantee that when we are removing a root task, @@ -1683,7 +1695,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Prevent recursion. return; } - task.mTransitionController.requestCloseTransitionIfNeeded(task); + final Transition transit = task.mTransitionController.requestCloseTransitionIfNeeded(task); + if (transit != null) { + transit.collectClose(task); + } else if (task.mTransitionController.isCollecting()) { + task.mTransitionController.getCollectingTransition().collectClose(task); + } // Consume the stopping activities immediately so activity manager won't skip killing // the process because it is still foreground state, i.e. RESUMED -> PAUSING set from // removeActivities -> finishIfPossible. diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java index c79a8b6b13a1..25885ed7e09a 100644 --- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java +++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java @@ -116,6 +116,7 @@ class BLASTSyncEngine { */ class SyncGroup { final int mSyncId; + final String mSyncName; int mSyncMethod = METHOD_BLAST; final TransactionReadyListener mListener; final Runnable mOnTimeout; @@ -138,6 +139,7 @@ class BLASTSyncEngine { private SyncGroup(TransactionReadyListener listener, int id, String name) { mSyncId = id; + mSyncName = name; mListener = listener; mOnTimeout = () -> { Slog.w(TAG, "Sync group " + mSyncId + " timeout"); @@ -221,15 +223,20 @@ class BLASTSyncEngine { for (WindowContainer wc : mRootMembers) { wc.waitForSyncTransactionCommit(wcAwaitingCommit); } + + final int syncId = mSyncId; + final long mergedTxId = merged.getId(); + final String syncName = mSyncName; class CommitCallback implements Runnable { // Can run a second time if the action completes after the timeout. boolean ran = false; public void onCommitted(SurfaceControl.Transaction t) { + // Don't wait to hold the global lock to remove the timeout runnable + mHandler.removeCallbacks(this); synchronized (mWm.mGlobalLock) { if (ran) { return; } - mHandler.removeCallbacks(this); ran = true; for (WindowContainer wc : wcAwaitingCommit) { wc.onSyncTransactionCommitted(t); @@ -246,8 +253,9 @@ class BLASTSyncEngine { // a trace. Since these kind of ANRs can trigger such an issue, // try and ensure we will have some visibility in both cases. Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionCommitTimeout"); - Slog.e(TAG, "WM sent Transaction to organized, but never received" + - " commit callback. Application ANR likely to follow."); + Slog.e(TAG, "WM sent Transaction (#" + syncId + ", " + syncName + ", tx=" + + mergedTxId + ") to organizer, but never received commit callback." + + " Application ANR likely to follow."); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); synchronized (mWm.mGlobalLock) { mListener.onTransactionCommitTimeout(); diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index e15512678104..e3ac35ca8f3b 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -60,7 +60,6 @@ import android.window.TaskSnapshot; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.TransitionAnimation; import com.android.internal.protolog.common.ProtoLog; -import com.android.server.wm.utils.InsetUtils; import com.android.window.flags.Flags; import java.io.PrintWriter; @@ -1436,15 +1435,11 @@ class BackNavigationController { return null; } final WindowState mainWindow = r.findMainWindow(); - Rect insets; - if (mainWindow != null) { - insets = mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets( - mBounds, WindowInsets.Type.tappableElement(), - false /* ignoreVisibility */).toRect(); - InsetUtils.addInsets(insets, mainWindow.mActivityRecord.getLetterboxInsets()); - } else { - insets = new Rect(); - } + final Rect insets = mainWindow != null + ? mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets( + mBounds, WindowInsets.Type.tappableElement(), + false /* ignoreVisibility */).toRect() + : new Rect(); final int mode = mIsOpen ? MODE_OPENING : MODE_CLOSING; mAnimationTarget = new RemoteAnimationTarget(t.mTaskId, mode, mCapturedLeash, !r.fillsParent(), new Rect(), @@ -1686,7 +1681,7 @@ class BackNavigationController { || (wallpaperController.getWallpaperTarget() != null && wallpaperController.wallpaperTransitionReady()); if (wallpaperReady && mPendingAnimation != null) { - startAnimation(); + mWindowManagerService.mAnimator.addAfterPrepareSurfacesRunnable(this::startAnimation); } } diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java index 7052982d3203..877378cac06a 100644 --- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java +++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java @@ -113,8 +113,10 @@ public class DeferredDisplayUpdater implements DisplayUpdater { // Apply whole display info immediately as is if either: // * it is the first display update + // * the display doesn't have visible content // * shell transitions are disabled or temporary unavailable if (displayInfoDiff == DIFF_EVERYTHING + || !mDisplayContent.getLastHasContent() || !mDisplayContent.mTransitionController.isShellTransitionsEnabled()) { ProtoLog.d(WM_DEBUG_WINDOW_TRANSITIONS, "DeferredDisplayUpdater: applying DisplayInfo immediately"); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index d3acd716aed3..282ecc77bd50 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1319,7 +1319,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp for (int i = 0; i < mChildren.size(); i++) { SurfaceControl sc = mChildren.get(i).getSurfaceControl(); if (sc != null) { - t.reparent(sc, mSurfaceControl); + t.reparent(sc, getParentingSurfaceControl()); } } @@ -1625,22 +1625,23 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (configChanged) { mWaitingForConfig = true; - if (mTransitionController.isShellTransitionsEnabled()) { + if (mLastHasContent && mTransitionController.isShellTransitionsEnabled()) { final Rect startBounds = currentDisplayConfig.windowConfiguration.getBounds(); final Rect endBounds = mTmpConfiguration.windowConfiguration.getBounds(); - final Transition transition = mTransitionController.getCollectingTransition(); - final TransitionRequestInfo.DisplayChange change = transition != null - ? null : new TransitionRequestInfo.DisplayChange(mDisplayId); - if (change != null) { + if (!mTransitionController.isCollecting()) { + final TransitionRequestInfo.DisplayChange change = + new TransitionRequestInfo.DisplayChange(mDisplayId); change.setStartAbsBounds(startBounds); change.setEndAbsBounds(endBounds); + requestChangeTransition(changes, change); } else { + final Transition transition = mTransitionController.getCollectingTransition(); transition.setKnownConfigChanges(this, changes); // A collecting transition is existed. The sync method must be set before // collecting this display, so WindowState#prepareSync can use the sync method. mTransitionController.setDisplaySyncMethod(startBounds, endBounds, this); + collectDisplayChange(transition); } - requestChangeTransitionIfNeeded(changes, change); } else if (mLastHasContent) { mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this); } @@ -2301,7 +2302,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mDisplayInfo.flags &= ~Display.FLAG_SCALING_DISABLED; } - computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig); + computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig, + false /* legacyConfig */); setDisplayInfoOverride(); @@ -2437,7 +2439,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp displayInfo.appHeight = appBounds.height(); final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation); displayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout; - computeSizeRanges(displayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig); + computeSizeRanges(displayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig, + false /* legacyConfig */); return displayInfo; } @@ -2601,8 +2604,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return curSize; } - private void computeSizeRanges(DisplayInfo displayInfo, boolean rotated, - int dw, int dh, float density, Configuration outConfig) { + /** + * Compute size range related fields of DisplayInfo and Configuration based on provided info. + * The fields usually contain word such as smallest or largest. + * + * @param displayInfo In-out display info to compute the result. + * @param rotated Whether the display is rotated. + * @param dw Display Width in current rotation. + * @param dh Display Height in current rotation. + * @param density Display density. + * @param outConfig The output configuration to + * @param legacyConfig Whether we need to report the legacy result, which is excluding system + * decorations. + */ + void computeSizeRanges(DisplayInfo displayInfo, boolean rotated, + int dw, int dh, float density, Configuration outConfig, boolean legacyConfig) { // We need to determine the smallest width that will occur under normal // operation. To this, start with the base screen size and compute the @@ -2620,10 +2636,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp displayInfo.smallestNominalAppHeight = 1<<30; displayInfo.largestNominalAppWidth = 0; displayInfo.largestNominalAppHeight = 0; - adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh); - adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw); - adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh); - adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw); + adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh, legacyConfig); + adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw, legacyConfig); + adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh, legacyConfig); + adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw, legacyConfig); if (outConfig == null) { return; @@ -2632,11 +2648,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp (int) (displayInfo.smallestNominalAppWidth / density + 0.5f); } - private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) { + private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh, + boolean legacyConfig) { final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo( rotation, dw, dh); - final int w = info.mConfigFrame.width(); - final int h = info.mConfigFrame.height(); + final int w; + final int h; + if (!legacyConfig) { + w = info.mConfigFrame.width(); + h = info.mConfigFrame.height(); + } else { + w = info.mLegacyConfigFrame.width(); + h = info.mLegacyConfigFrame.height(); + } if (w < displayInfo.smallestNominalAppWidth) { displayInfo.smallestNominalAppWidth = w; } @@ -3551,58 +3575,60 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } /** - * Requests to start a transition for the display configuration change. The given changes must - * be non-zero. This method is no-op if the display has been collected. + * Collects this display into an already-collecting transition. */ - void requestChangeTransitionIfNeeded(@ActivityInfo.Config int changes, - @Nullable TransitionRequestInfo.DisplayChange displayChange) { + void collectDisplayChange(@NonNull Transition transition) { if (!mLastHasContent) return; - final TransitionController controller = mTransitionController; - if (controller.isCollecting()) { - if (displayChange != null) { - throw new IllegalArgumentException("Provided displayChange for non-new transition"); - } - if (!controller.isCollecting(this)) { - controller.collect(this); - startAsyncRotationIfNeeded(); - if (mFixedRotationLaunchingApp != null) { - setSeamlessTransitionForFixedRotation(controller.getCollectingTransition()); - } - } else if (mAsyncRotationController != null && !isRotationChanging()) { - Slog.i(TAG, "Finish AsyncRotation for previous intermediate change"); - finishAsyncRotationIfPossible(); - } - return; + if (!transition.isCollecting()) { + throw new IllegalArgumentException("Can only collect display change if transition" + + " is collecting"); } - final Transition t = controller.requestTransitionIfNeeded(TRANSIT_CHANGE, 0 /* flags */, - this, this, null /* remoteTransition */, displayChange); - if (t != null) { - mAtmService.startPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); - if (mAsyncRotationController != null) { - // Give a chance to update the transform if the current rotation is changed when - // some windows haven't finished previous rotation. - mAsyncRotationController.updateRotation(); - } + if (!transition.mParticipants.contains(this)) { + transition.collect(this); + startAsyncRotationIfNeeded(); if (mFixedRotationLaunchingApp != null) { - // A fixed-rotation transition is done, then continue to start a seamless display - // transition. - setSeamlessTransitionForFixedRotation(t); - } else if (isRotationChanging()) { - if (displayChange != null) { - final boolean seamless = mDisplayRotation.shouldRotateSeamlessly( - displayChange.getStartRotation(), displayChange.getEndRotation(), - false /* forceUpdate */); - if (seamless) { - t.onSeamlessRotating(this); - } + setSeamlessTransitionForFixedRotation(transition); + } + } else if (mAsyncRotationController != null && !isRotationChanging()) { + Slog.i(TAG, "Finish AsyncRotation for previous intermediate change"); + finishAsyncRotationIfPossible(); + } + } + + /** + * Requests to start a transition for a display change. {@code changes} must be non-zero. + */ + void requestChangeTransition(@ActivityInfo.Config int changes, + @Nullable TransitionRequestInfo.DisplayChange displayChange) { + final TransitionController controller = mTransitionController; + final Transition t = controller.requestStartDisplayTransition(TRANSIT_CHANGE, 0 /* flags */, + this, null /* remoteTransition */, displayChange); + t.collect(this); + mAtmService.startPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); + if (mAsyncRotationController != null) { + // Give a chance to update the transform if the current rotation is changed when + // some windows haven't finished previous rotation. + mAsyncRotationController.updateRotation(); + } + if (mFixedRotationLaunchingApp != null) { + // A fixed-rotation transition is done, then continue to start a seamless display + // transition. + setSeamlessTransitionForFixedRotation(t); + } else if (isRotationChanging()) { + if (displayChange != null) { + final boolean seamless = mDisplayRotation.shouldRotateSeamlessly( + displayChange.getStartRotation(), displayChange.getEndRotation(), + false /* forceUpdate */); + if (seamless) { + t.onSeamlessRotating(this); } - mWmService.mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN); - controller.mTransitionMetricsReporter.associate(t.getToken(), - startTime -> mWmService.mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN)); - startAsyncRotation(false /* shouldDebounce */); } - t.setKnownConfigChanges(this, changes); + mWmService.mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN); + controller.mTransitionMetricsReporter.associate(t.getToken(), + startTime -> mWmService.mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN)); + startAsyncRotation(false /* shouldDebounce */); } + t.setKnownConfigChanges(this, changes); } private void setSeamlessTransitionForFixedRotation(Transition t) { @@ -5722,14 +5748,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit, @WindowManager.TransitionFlags int flags) { - requestTransitionAndLegacyPrepare(transit, flags, null /* trigger */); - } - - /** @see #requestTransitionAndLegacyPrepare(int, int) */ - void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit, - @WindowManager.TransitionFlags int flags, @Nullable WindowContainer trigger) { prepareAppTransition(transit, flags); - mTransitionController.requestTransitionIfNeeded(transit, flags, trigger, this); + mTransitionController.requestTransitionIfNeeded(transit, flags, null /* trigger */, this); } void executeAppTransition() { @@ -5808,6 +5828,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp || supportsSystemDecorations(); } + /** + * Returns the {@link SurfaceControl} where all the children should be parented on. + * + * <p> {@link DisplayContent} inserts a RootWrapper leash in the hierarchy above its original + * {@link #mSurfaceControl} and then overrides the {@link #mSurfaceControl} to point to the + * RootWrapper. + * <p> To prevent inconsistent state later where the DAs might get re-parented to the + * RootWrapper, this method should be used which returns the correct surface where the + * re-parenting should happen. + */ + @Override + SurfaceControl getParentingSurfaceControl() { + return mWindowingLayer; + } + SurfaceControl getWindowingLayer() { return mWindowingLayer; } @@ -6372,8 +6407,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (changes != 0) { Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig + " for displayId=" + mDisplayId); - if (isReady() && mTransitionController.isShellTransitionsEnabled()) { - requestChangeTransitionIfNeeded(changes, null /* displayChange */); + if (isReady() && mTransitionController.isShellTransitionsEnabled() && mLastHasContent) { + final Transition transition = mTransitionController.getCollectingTransition(); + if (transition != null) { + collectDisplayChange(transition); + } else { + requestChangeTransition(changes, null /* displayChange */); + } } onRequestedOverrideConfigurationChanged(mTempConfig); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 57b9c63aaa05..e789fecb8625 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1917,6 +1917,11 @@ public class DisplayPolicy { */ final Rect mConfigInsets = new Rect(); + /** + * Legacy value of mConfigInsets for app compatibility purpose. + */ + final Rect mLegacyConfigInsets = new Rect(); + /** The display frame available after excluding {@link #mNonDecorInsets}. */ final Rect mNonDecorFrame = new Rect(); @@ -1927,6 +1932,11 @@ public class DisplayPolicy { */ final Rect mConfigFrame = new Rect(); + /** + * Legacy value of mConfigFrame for app compatibility purpose. + */ + final Rect mLegacyConfigFrame = new Rect(); + private boolean mNeedUpdate = true; InsetsState update(DisplayContent dc, int rotation, int w, int h) { @@ -1937,15 +1947,26 @@ public class DisplayPolicy { final Rect displayFrame = insetsState.getDisplayFrame(); final Insets decor = insetsState.calculateInsets(displayFrame, dc.mWmService.mDecorTypes, true /* ignoreVisibility */); - final Insets configInsets = insetsState.calculateInsets(displayFrame, - dc.mWmService.mConfigTypes, true /* ignoreVisibility */); + final Insets configInsets = dc.mWmService.mConfigTypes == dc.mWmService.mDecorTypes + ? decor + : insetsState.calculateInsets(displayFrame, dc.mWmService.mConfigTypes, + true /* ignoreVisibility */); + final Insets legacyConfigInsets = dc.mWmService.mConfigTypes + == dc.mWmService.mLegacyConfigTypes + ? configInsets + : insetsState.calculateInsets(displayFrame, + dc.mWmService.mLegacyConfigTypes, true /* ignoreVisibility */); mNonDecorInsets.set(decor.left, decor.top, decor.right, decor.bottom); mConfigInsets.set(configInsets.left, configInsets.top, configInsets.right, configInsets.bottom); + mLegacyConfigInsets.set(legacyConfigInsets.left, legacyConfigInsets.top, + legacyConfigInsets.right, legacyConfigInsets.bottom); mNonDecorFrame.set(displayFrame); mNonDecorFrame.inset(mNonDecorInsets); mConfigFrame.set(displayFrame); mConfigFrame.inset(mConfigInsets); + mLegacyConfigFrame.set(displayFrame); + mLegacyConfigFrame.inset(mLegacyConfigInsets); mNeedUpdate = false; return insetsState; } @@ -1953,8 +1974,10 @@ public class DisplayPolicy { void set(Info other) { mNonDecorInsets.set(other.mNonDecorInsets); mConfigInsets.set(other.mConfigInsets); + mLegacyConfigInsets.set(other.mLegacyConfigInsets); mNonDecorFrame.set(other.mNonDecorFrame); mConfigFrame.set(other.mConfigFrame); + mLegacyConfigFrame.set(other.mLegacyConfigFrame); mNeedUpdate = false; } @@ -2066,7 +2089,8 @@ public class DisplayPolicy { final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo; final InsetsState newInsetsState = newInfo.update(mDisplayContent, rotation, dw, dh); final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh); - if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) { + if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame) + && newInfo.mLegacyConfigFrame.equals(currentInfo.mLegacyConfigFrame)) { // Even if the config frame is not changed in current rotation, it may change the // insets in other rotations if the frame of insets source is changed. final InsetsState currentInsetsState = mDisplayContent.mDisplayFrames.mInsetsState; diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index d37661312cfb..384b91a07d4e 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -629,13 +629,17 @@ public class DisplayRotation { if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) { final boolean wasCollecting = mDisplayContent.mTransitionController.isCollecting(); - final TransitionRequestInfo.DisplayChange change = wasCollecting ? null - : new TransitionRequestInfo.DisplayChange(mDisplayContent.getDisplayId(), - oldRotation, mRotation); - - mDisplayContent.requestChangeTransitionIfNeeded( - ActivityInfo.CONFIG_WINDOW_CONFIGURATION, change); - if (wasCollecting) { + if (!wasCollecting) { + if (mDisplayContent.getLastHasContent()) { + final TransitionRequestInfo.DisplayChange change = + new TransitionRequestInfo.DisplayChange(mDisplayContent.getDisplayId(), + oldRotation, mRotation); + mDisplayContent.requestChangeTransition( + ActivityInfo.CONFIG_WINDOW_CONFIGURATION, change); + } + } else { + mDisplayContent.collectDisplayChange( + mDisplayContent.mTransitionController.getCollectingTransition()); // Use remote-rotation infra since the transition has already been requested // TODO(shell-transitions): Remove this once lifecycle management can cover all // rotation cases. diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index 9fee3433f6be..21326be0734c 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -31,6 +31,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import android.os.Trace; +import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.InsetsSource; import android.view.InsetsSourceConsumer; @@ -50,6 +51,8 @@ import java.io.PrintWriter; */ final class ImeInsetsSourceProvider extends InsetsSourceProvider { + private static final String TAG = ImeInsetsSourceProvider.class.getSimpleName(); + /** The token tracking the current IME request or {@code null} otherwise. */ @Nullable private ImeTracker.Token mImeRequesterStatsToken; @@ -220,12 +223,16 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { */ void scheduleShowImePostLayout(InsetsControlTarget imeTarget, @NonNull ImeTracker.Token statsToken) { + if (mImeRequesterStatsToken != null) { + // Cancel the pre-existing stats token, if any. + // Log state on pre-existing request cancel. + logShowImePostLayoutState(); + ImeTracker.forLogging().onCancelled( + mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER); + } + mImeRequesterStatsToken = statsToken; boolean targetChanged = isTargetChangedWithinActivity(imeTarget); mImeRequester = imeTarget; - // Cancel the pre-existing stats token, if any. - ImeTracker.forLogging().onCancelled( - mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER); - mImeRequesterStatsToken = statsToken; if (targetChanged) { // target changed, check if new target can show IME. ProtoLog.d(WM_DEBUG_IME, "IME target changed within ActivityRecord"); @@ -297,12 +304,16 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { */ void abortShowImePostLayout() { ProtoLog.d(WM_DEBUG_IME, "abortShowImePostLayout"); + if (mImeRequesterStatsToken != null) { + // Log state on abort. + logShowImePostLayoutState(); + ImeTracker.forLogging().onFailed( + mImeRequesterStatsToken, ImeTracker.PHASE_WM_ABORT_SHOW_IME_POST_LAYOUT); + mImeRequesterStatsToken = null; + } mImeRequester = null; mIsImeLayoutDrawn = false; mShowImeRunner = null; - ImeTracker.forLogging().onFailed( - mImeRequesterStatsToken, ImeTracker.PHASE_WM_ABORT_SHOW_IME_POST_LAYOUT); - mImeRequesterStatsToken = null; } @VisibleForTesting @@ -337,6 +348,41 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { || sameAsImeControlTarget(); } + /** + * Logs the current state required for scheduleShowImePostLayout's runnable to be triggered. + */ + private void logShowImePostLayoutState() { + final var windowState = mWindowContainer != null ? mWindowContainer.asWindowState() : null; + final var dcTarget = mDisplayContent.getImeTarget(IME_TARGET_LAYERING); + final var controlTarget = mDisplayContent.getImeTarget(IME_TARGET_CONTROL); + final var sb = new StringBuilder(); + sb.append("mWindowContainer: ").append(mWindowContainer); + sb.append(" windowState: ").append(windowState); + if (windowState != null) { + sb.append(" windowState.isDrawn(): ").append(windowState.isDrawn()); + sb.append(" windowState.mGivenInsetsPending: ").append(windowState.mGivenInsetsPending); + } + sb.append(" mIsImeLayoutDrawn: ").append(mIsImeLayoutDrawn); + sb.append(" mShowImeRunner: ").append(mShowImeRunner); + sb.append(" mImeRequester: ").append(mImeRequester); + sb.append(" dcTarget: ").append(dcTarget); + sb.append(" controlTarget: ").append(controlTarget); + sb.append(" isReadyToShowIme(): ").append(isReadyToShowIme()); + if (mImeRequester != null && dcTarget != null && controlTarget != null) { + sb.append(" isImeLayeringTarget: "); + sb.append(isImeLayeringTarget(mImeRequester, dcTarget)); + sb.append(" isAboveImeLayeringTarget: "); + sb.append(isAboveImeLayeringTarget(mImeRequester, dcTarget)); + sb.append(" isImeFallbackTarget: "); + sb.append(isImeFallbackTarget(mImeRequester)); + sb.append(" isImeInputTarget: "); + sb.append(isImeInputTarget(mImeRequester)); + sb.append(" sameAsImeControlTarget: "); + sb.append(sameAsImeControlTarget()); + } + Slog.d(TAG, sb.toString()); + } + // --------------------------------------------------------------------------------------- // Methods for checking IME insets target changing state. // @@ -399,6 +445,10 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { pw.print("showImePostLayout pending for mImeRequester="); pw.print(mImeRequester); pw.println(); + } else { + pw.print(prefix); + pw.print("showImePostLayout not scheduled, mImeRequester=null"); + pw.println(); } pw.println(); } diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 6d1180497fed..b8bb258aa2ce 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -432,15 +432,22 @@ class KeyguardController { mService.deferWindowLayout(); try { if (isKeyguardLocked(displayId)) { - if (occluded) { - mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare( - TRANSIT_KEYGUARD_OCCLUDE, - TRANSIT_FLAG_KEYGUARD_OCCLUDING, - topActivity != null ? topActivity.getRootTask() : null); + final int type = occluded ? TRANSIT_KEYGUARD_OCCLUDE : TRANSIT_KEYGUARD_UNOCCLUDE; + final int flag = occluded ? TRANSIT_FLAG_KEYGUARD_OCCLUDING + : TRANSIT_FLAG_KEYGUARD_UNOCCLUDING; + if (tc.isShellTransitionsEnabled()) { + final Task trigger = (occluded && topActivity != null) + ? topActivity.getRootTask() : null; + Transition transition = tc.requestTransitionIfNeeded(type, flag, trigger, + mRootWindowContainer.getDefaultDisplay()); + if (trigger != null) { + if (transition == null) { + transition = tc.getCollectingTransition(); + } + transition.collect(trigger); + } } else { - mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare( - TRANSIT_KEYGUARD_UNOCCLUDE, - TRANSIT_FLAG_KEYGUARD_UNOCCLUDING); + mRootWindowContainer.getDefaultDisplay().prepareAppTransition(type, flag); } } else { if (tc.inTransition()) { diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java index 2b841fdad9c0..4c797f8d17ea 100644 --- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java +++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java @@ -115,8 +115,8 @@ public class PhysicalDisplaySwitchTransitionLauncher { if (mTransitionController.isCollecting()) { // Add display container to the currently collecting transition - mTransitionController.collect(mDisplayContent); mTransition = mTransitionController.getCollectingTransition(); + mTransition.collect(mDisplayContent); // Make sure that transition is not ready until we finish the remote display change mTransition.setReady(mDisplayContent, false); @@ -134,10 +134,9 @@ public class PhysicalDisplaySwitchTransitionLauncher { displayChange.setEndAbsBounds(endAbsBounds); displayChange.setPhysicalDisplayChanged(true); - mTransition = mTransitionController.requestTransitionIfNeeded(TRANSIT_CHANGE, - 0 /* flags */, - mDisplayContent, mDisplayContent, null /* remoteTransition */, - displayChange); + mTransition = mTransitionController.requestStartDisplayTransition(TRANSIT_CHANGE, + 0 /* flags */, mDisplayContent, null /* remoteTransition */, displayChange); + mTransition.collect(mDisplayContent); } if (mTransition != null) { diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 597e901f62ef..c91925081d8e 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2307,7 +2307,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { // area, i.e. the screen area without the system bars. // The non decor inset are areas that could never be removed in Honeycomb. See // {@link WindowManagerPolicy#getNonDecorInsetsLw}. - calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di); + calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di, + false /* useLegacyInsetsForStableBounds */); } else { // Apply the given non-decor and stable insets to calculate the corresponding bounds // for screen size of configuration. @@ -2405,9 +2406,11 @@ class TaskFragment extends WindowContainer<WindowContainer> { * @param outNonDecorBounds where to place bounds with non-decor insets applied. * @param outStableBounds where to place bounds with stable insets applied. * @param bounds the bounds to inset. + * @param useLegacyInsetsForStableBounds {@code true} if we need to use the legacy insets frame + * for apps targeting U or before when calculating stable bounds. */ void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds, - DisplayInfo displayInfo) { + DisplayInfo displayInfo, boolean useLegacyInsetsForStableBounds) { outNonDecorBounds.set(bounds); outStableBounds.set(bounds); if (mDisplayContent == null) { @@ -2419,7 +2422,11 @@ class TaskFragment extends WindowContainer<WindowContainer> { final DisplayPolicy.DecorInsets.Info info = policy.getDecorInsetsInfo( displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight); intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, info.mNonDecorInsets); - intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets); + if (!useLegacyInsetsForStableBounds) { + intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets); + } else { + intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mLegacyConfigInsets); + } } /** diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 7edc3a2b9786..6d8b03020561 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -503,6 +503,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } mConfigAtEndActivities.add(ar); ar.pauseConfigurationDispatch(); + snapshotStartState(ar); + mChanges.get(ar).mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END; }); snapshotStartState(wc); mChanges.get(wc).mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END; @@ -623,7 +625,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { throw new IllegalStateException("Attempting to re-use a transition"); } mState = STATE_COLLECTING; - mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG, + mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, + TAG + "-" + transitTypeToString(mType), mParallelCollectType != PARALLEL_TYPE_NONE); mSyncEngine.setSyncMethod(mSyncId, TransitionController.SYNC_METHOD); @@ -856,6 +859,19 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } /** + * Collects a window container which will be removed or invisible. + */ + void collectClose(@NonNull WindowContainer<?> wc) { + if (wc.isVisibleRequested()) { + collectExistenceChange(wc); + } else { + // Removing a non-visible window doesn't require a transition, but if there is one + // collecting, this should be a member just in case. + collect(wc); + } + } + + /** * @return {@code true} if `wc` is a participant or is a descendant of one. */ boolean isInTransition(WindowContainer wc) { @@ -2381,9 +2397,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } else { parentChange.mFlags |= ChangeInfo.FLAG_CHANGE_YES_ANIMATION; } - final ActivityRecord ar = targetChange.mContainer.asActivityRecord(); - if ((ar != null && ar.isConfigurationDispatchPaused()) - || ((targetChange.mFlags & ChangeInfo.FLAG_CHANGE_CONFIG_AT_END) != 0)) { + if ((targetChange.mFlags & ChangeInfo.FLAG_CHANGE_CONFIG_AT_END) != 0) { parentChange.mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END; } } @@ -2470,6 +2484,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { } else { intermediates.add(parentChange); } + // for config-at-end, we want to promote the flag based on the end-state even + // if the activity was reparented because it operates after the animation. So, + // check that here since the promote code skips reparents. + if ((targetChange.mFlags & ChangeInfo.FLAG_CHANGE_CONFIG_AT_END) != 0 + && targetChange.mContainer.asActivityRecord() != null + && targetChange.mContainer.getParent() == p) { + parentChange.mFlags |= ChangeInfo.FLAG_CHANGE_CONFIG_AT_END; + } foundParentInTargets = true; break; } else if (reportIfNotTop(p) && !skipIntermediateReports) { diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 503f925bf557..ac03a1bbf590 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -21,7 +21,6 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS; import static android.view.WindowManager.TRANSIT_NONE; -import static android.view.WindowManager.TRANSIT_OPEN; import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY; @@ -616,30 +615,6 @@ class TransitionController { return changeInfo != null && changeInfo.mRotation != targetRotation; } - /** - * @see #requestTransitionIfNeeded(int, int, WindowContainer, WindowContainer, RemoteTransition) - */ - @Nullable - Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, - @NonNull WindowContainer trigger) { - return requestTransitionIfNeeded(type, 0 /* flags */, trigger, trigger /* readyGroupRef */); - } - - /** - * @see #requestTransitionIfNeeded(int, int, WindowContainer, WindowContainer, RemoteTransition) - */ - @Nullable - Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, - @WindowManager.TransitionFlags int flags, @Nullable WindowContainer trigger, - @NonNull WindowContainer readyGroupRef) { - return requestTransitionIfNeeded(type, flags, trigger, readyGroupRef, - null /* remoteTransition */, null /* displayChange */); - } - - private static boolean isExistenceType(@WindowManager.TransitionType int type) { - return type == TRANSIT_OPEN || type == TRANSIT_CLOSE; - } - /** Sets the sync method for the display change. */ private void setDisplaySyncMethod(@NonNull TransitionRequestInfo.DisplayChange displayChange, @NonNull DisplayContent displayContent) { @@ -672,21 +647,17 @@ class TransitionController { * start it. Collection can start immediately. * @param trigger if non-null, this is the first container that will be collected * @param readyGroupRef Used to identify which ready-group this request is for. - * @return the created transition if created or null otherwise. + * @return the created transition if created or null otherwise (already global collecting) */ @Nullable Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, @WindowManager.TransitionFlags int flags, @Nullable WindowContainer trigger, - @NonNull WindowContainer readyGroupRef, @Nullable RemoteTransition remoteTransition, - @Nullable TransitionRequestInfo.DisplayChange displayChange) { + @NonNull WindowContainer readyGroupRef) { if (mTransitionPlayer == null) { return null; } Transition newTransition = null; if (isCollecting()) { - if (displayChange != null) { - Slog.e(TAG, "Provided displayChange for a non-new request", new Throwable()); - } // Make the collecting transition wait until this request is ready. mCollectingTransition.setReady(readyGroupRef, false); if ((flags & KEYGUARD_VISIBILITY_TRANSIT_FLAGS) != 0) { @@ -695,18 +666,26 @@ class TransitionController { } } else { newTransition = requestStartTransition(createTransition(type, flags), - trigger != null ? trigger.asTask() : null, remoteTransition, displayChange); - if (newTransition != null && displayChange != null && trigger != null - && trigger.asDisplayContent() != null) { - setDisplaySyncMethod(displayChange, trigger.asDisplayContent()); - } + trigger != null ? trigger.asTask() : null, null /* remote */, null /* disp */); } - if (trigger != null) { - if (isExistenceType(type)) { - collectExistenceChange(trigger); - } else { - collect(trigger); - } + return newTransition; + } + + /** + * Creates a transition and asks the TransitionPlayer (Shell) to + * start it. Collection can start immediately. + * @param trigger if non-null, this is the first container that will be collected + * @return the created transition if created or null otherwise. + */ + @NonNull + Transition requestStartDisplayTransition(@WindowManager.TransitionType int type, + @WindowManager.TransitionFlags int flags, @NonNull DisplayContent trigger, + @Nullable RemoteTransition remoteTransition, + @Nullable TransitionRequestInfo.DisplayChange displayChange) { + final Transition newTransition = createTransition(type, flags); + requestStartTransition(newTransition, null /* trigger */, remoteTransition, displayChange); + if (displayChange != null) { + setDisplaySyncMethod(displayChange, trigger); } return newTransition; } @@ -770,20 +749,10 @@ class TransitionController { * @return the new transition if it was created for this request, `null` otherwise. */ Transition requestCloseTransitionIfNeeded(@NonNull WindowContainer<?> wc) { - if (mTransitionPlayer == null) return null; - Transition out = null; - if (wc.isVisibleRequested()) { - if (!isCollecting()) { - out = requestStartTransition(createTransition(TRANSIT_CLOSE, 0 /* flags */), - wc.asTask(), null /* remoteTransition */, null /* displayChange */); - } - collectExistenceChange(wc); - } else { - // Removing a non-visible window doesn't require a transition, but if there is one - // collecting, this should be a member just in case. - collect(wc); - } - return out; + if (mTransitionPlayer == null || isCollecting()) return null; + if (!wc.isVisibleRequested()) return null; + return requestStartTransition(createTransition(TRANSIT_CLOSE, 0 /* flags */), wc.asTask(), + null /* remoteTransition */, null /* displayChange */); } /** @see Transition#collect */ diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index fd0289edc84b..f2af852dfeed 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -716,7 +716,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // If parent is null, the layer should be placed offscreen so reparent to null. Otherwise, // set to the available parent. - t.reparent(mSurfaceControl, mParent == null ? null : mParent.getSurfaceControl()); + t.reparent(mSurfaceControl, mParent == null ? null : mParent.getParentingSurfaceControl()); if (mLastRelativeToLayer != null) { t.setRelativeLayer(mSurfaceControl, mLastRelativeToLayer, mLastLayer); @@ -2907,6 +2907,17 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } /** + * Returns the {@link SurfaceControl} where all the children should be parented on. + * + * A {@link WindowContainer} might insert intermediate leashes in the hierarchy and hence + * {@link #getSurfaceControl} won't return the correct surface where the children should be + * re-parented on. + */ + SurfaceControl getParentingSurfaceControl() { + return getSurfaceControl(); + } + + /** * Use this method instead of {@link #getPendingTransaction()} if the Transaction should be * synchronized with the client. * diff --git a/services/core/java/com/android/server/wm/WindowManagerFlags.java b/services/core/java/com/android/server/wm/WindowManagerFlags.java index 7b0d931abf8a..294733e85fbd 100644 --- a/services/core/java/com/android/server/wm/WindowManagerFlags.java +++ b/services/core/java/com/android/server/wm/WindowManagerFlags.java @@ -48,5 +48,7 @@ class WindowManagerFlags { final boolean mAllowsScreenSizeDecoupledFromStatusBarAndCutout = Flags.allowsScreenSizeDecoupledFromStatusBarAndCutout(); + final boolean mInsetsDecoupledConfiguration = Flags.insetsDecoupledConfiguration(); + /* End Available Flags */ } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index a055db274ae8..71ffabf20bb4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -561,6 +561,8 @@ public class WindowManagerService extends IWindowManager.Stub /** Device default insets types shall be excluded from config app sizes. */ final int mConfigTypes; + final int mLegacyConfigTypes; + final boolean mLimitedAlphaCompositing; final int mMaxUiWidth; @@ -1190,13 +1192,23 @@ public class WindowManagerService extends IWindowManager.Stub final boolean isScreenSizeDecoupledFromStatusBarAndCutout = context.getResources() .getBoolean(R.bool.config_decoupleStatusBarAndDisplayCutoutFromScreenSize) && mFlags.mAllowsScreenSizeDecoupledFromStatusBarAndCutout; - if (!isScreenSizeDecoupledFromStatusBarAndCutout) { + if (mFlags.mInsetsDecoupledConfiguration) { + mDecorTypes = 0; + mConfigTypes = 0; + } else if (isScreenSizeDecoupledFromStatusBarAndCutout) { + mDecorTypes = WindowInsets.Type.navigationBars(); + mConfigTypes = WindowInsets.Type.navigationBars(); + } else { mDecorTypes = WindowInsets.Type.displayCutout() | WindowInsets.Type.navigationBars(); mConfigTypes = WindowInsets.Type.displayCutout() | WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars(); + } + if (isScreenSizeDecoupledFromStatusBarAndCutout) { + // Do not fallback to legacy value for enabled devices. + mLegacyConfigTypes = WindowInsets.Type.navigationBars(); } else { - mDecorTypes = WindowInsets.Type.navigationBars(); - mConfigTypes = WindowInsets.Type.navigationBars(); + mLegacyConfigTypes = WindowInsets.Type.displayCutout() | WindowInsets.Type.statusBars() + | WindowInsets.Type.navigationBars(); } mLetterboxConfiguration = new LetterboxConfiguration( @@ -3646,7 +3658,11 @@ public class WindowManagerService extends IWindowManager.Stub public void setCurrentUser(@UserIdInt int newUserId) { synchronized (mGlobalLock) { - mAtmService.getTransitionController().requestTransitionIfNeeded(TRANSIT_OPEN, null); + final TransitionController controller = mAtmService.getTransitionController(); + if (!controller.isCollecting() && controller.isShellTransitionsEnabled()) { + controller.requestStartTransition(controller.createTransition(TRANSIT_OPEN), + null /* trigger */, null /* remote */, null /* disp */); + } mCurrentUserId = newUserId; mPolicy.setCurrentUserLw(newUserId); mKeyguardDisableHandler.setCurrentUser(newUserId); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index a7eb444ecb59..a63e106beb55 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -2018,6 +2018,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub try { callback.onTransactionReady(syncId, t); } catch (RemoteException e) { + Slog.e(TAG, "Failed to notify transaction (" + syncId + ") ready", e); // If there's an exception when trying to send the mergedTransaction to the client, we // should immediately apply it here so the transactions aren't lost. t.apply(); diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index ee16a37d6baf..6ac2774941e1 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -114,6 +114,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private static final long RAPID_ACTIVITY_LAUNCH_MS = 300; private static final long RESET_RAPID_ACTIVITY_LAUNCH_MS = 5 * RAPID_ACTIVITY_LAUNCH_MS; + public static final int STOPPED_STATE_NOT_STOPPED = 0; + public static final int STOPPED_STATE_FIRST_LAUNCH = 1; + public static final int STOPPED_STATE_FORCE_STOPPED = 2; + private int mRapidActivityLaunchCount; // all about the first app in the process @@ -281,6 +285,22 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio @AnimatingReason private int mAnimatingReasons; + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + STOPPED_STATE_NOT_STOPPED, + STOPPED_STATE_FIRST_LAUNCH, + STOPPED_STATE_FORCE_STOPPED + }) + public @interface StoppedState {} + + private volatile @StoppedState int mStoppedState; + + /** + * Whether the stopped state was logged for an activity start, as we don't want to log + * multiple times. + */ + private volatile boolean mWasStoppedLogged; + // The bits used for mActivityStateFlags. private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16; private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17; @@ -1928,6 +1948,29 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio && (mInfo.flags & ApplicationInfo.FLAG_FACTORY_TEST) != 0; } + /** Sets the current stopped state of the app, which is reset as soon as metrics are logged */ + public void setStoppedState(@StoppedState int stoppedState) { + mStoppedState = stoppedState; + } + + boolean getWasStoppedLogged() { + return mWasStoppedLogged; + } + + void setWasStoppedLogged(boolean logged) { + mWasStoppedLogged = logged; + } + + /** Returns whether the app had been force-stopped before this launch */ + public boolean wasForceStopped() { + return mStoppedState == STOPPED_STATE_FORCE_STOPPED; + } + + /** Returns whether this app is being launched for the first time since install */ + boolean wasFirstLaunch() { + return mStoppedState == STOPPED_STATE_FIRST_LAUNCH; + } + void setRunningRecentsAnimation(boolean running) { if (running) { addAnimatingReason(ANIMATING_REASON_LEGACY_RECENT_ANIMATION); diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 13e1ba785b87..4dca23bc03c7 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -563,9 +563,15 @@ class WindowToken extends WindowContainer<WindowState> { if (mTransitionController.isShellTransitionsEnabled() && asActivityRecord() != null && isVisible()) { // Trigger an activity level rotation transition. - mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_CHANGE, this); - mTransitionController.collectVisibleChange(this); - mTransitionController.setReady(this); + Transition transition = mTransitionController.getCollectingTransition(); + if (transition == null) { + transition = mTransitionController.requestStartTransition( + mTransitionController.createTransition(WindowManager.TRANSIT_CHANGE), + null /* trigger */, null /* remote */, null /* disp */); + } + transition.collect(this); + transition.collectVisibleChange(this); + transition.setReady(mDisplayContent, true); } final int originalRotation = getWindowConfiguration().getRotation(); onConfigurationChanged(parent.getConfiguration()); diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 3607dddc66d5..7a710dc51004 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -40,6 +40,7 @@ cc_library_static { "com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp", "com_android_server_ConsumerIrService.cpp", "com_android_server_companion_virtual_InputController.cpp", + "com_android_server_companion_virtual_VirtualDeviceImpl.cpp", "com_android_server_devicepolicy_CryptoTestHelper.cpp", "com_android_server_display_DisplayControl.cpp", "com_android_server_display_SmallAreaDetectionController.cpp", @@ -214,6 +215,7 @@ cc_defaults { static_libs: [ "android.hardware.broadcastradio@common-utils-1x-lib", "libaidlcommonsupport", + "libvirtualdevicebuildflags", ], product_variables: { diff --git a/services/core/jni/com_android_server_companion_virtual_VirtualDeviceImpl.cpp b/services/core/jni/com_android_server_companion_virtual_VirtualDeviceImpl.cpp new file mode 100644 index 000000000000..1e6a9dbcb58e --- /dev/null +++ b/services/core/jni/com_android_server_companion_virtual_VirtualDeviceImpl.cpp @@ -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. + */ + +#include <android_companion_virtualdevice_build_flags.h> +#include <nativehelper/JNIHelp.h> + +#include <array> + +#include "jni.h" + +namespace android { +namespace { + +jboolean nativeVirtualCameraServiceBuildFlagEnabled(JNIEnv* env, jobject clazz) { + return ::android::companion::virtualdevice::flags::virtual_camera_service_build_flag(); +} + +const std::array<JNINativeMethod, 1> kMethods = { + {{"nativeVirtualCameraServiceBuildFlagEnabled", "()Z", + (void*)nativeVirtualCameraServiceBuildFlagEnabled}}, +}; + +} // namespace + +int register_android_server_companion_virtual_VirtualDeviceImpl(JNIEnv* env) { + return jniRegisterNativeMethods(env, "com/android/server/companion/virtual/VirtualDeviceImpl", + kMethods.data(), kMethods.size()); +} + +} // namespace android diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 0936888b24a0..6464081d615a 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -65,6 +65,7 @@ int register_android_server_GpuService(JNIEnv* env); int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env); int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env); int register_android_server_companion_virtual_InputController(JNIEnv* env); +int register_android_server_companion_virtual_VirtualDeviceImpl(JNIEnv* env); int register_android_server_app_GameManagerService(JNIEnv* env); int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env); int register_com_android_server_display_DisplayControl(JNIEnv* env); @@ -128,6 +129,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_stats_pull_StatsPullAtomService(env); register_android_server_sensor_SensorService(vm, env); register_android_server_companion_virtual_InputController(env); + register_android_server_companion_virtual_VirtualDeviceImpl(env); register_android_server_app_GameManagerService(env); register_com_android_server_wm_TaskFpsCallbackController(env); register_com_android_server_display_DisplayControl(env); diff --git a/services/core/xsd/device-state-config/device-state-config.xsd b/services/core/xsd/device-state-config/device-state-config.xsd index 86f41769008d..4a947327070a 100644 --- a/services/core/xsd/device-state-config/device-state-config.xsd +++ b/services/core/xsd/device-state-config/device-state-config.xsd @@ -40,14 +40,14 @@ <xs:element name="name" type="xs:string" minOccurs="0"> <xs:annotation name="nullable" /> </xs:element> - <xs:element name="flags" type="flags" /> + <xs:element name="properties" type="properties" /> <xs:element name="conditions" type="conditions" /> </xs:sequence> </xs:complexType> - <xs:complexType name="flags"> + <xs:complexType name="properties"> <xs:sequence> - <xs:element name="flag" type="xs:string" minOccurs="0" maxOccurs="unbounded"> + <xs:element name="property" type="xs:string" minOccurs="0" maxOccurs="unbounded"> <xs:annotation name="nullable" /> </xs:element> </xs:sequence> diff --git a/services/core/xsd/device-state-config/schema/current.txt b/services/core/xsd/device-state-config/schema/current.txt index a98d4e569cd6..5bb216e69e4d 100644 --- a/services/core/xsd/device-state-config/schema/current.txt +++ b/services/core/xsd/device-state-config/schema/current.txt @@ -11,13 +11,13 @@ package com.android.server.policy.devicestate.config { public class DeviceState { ctor public DeviceState(); method public com.android.server.policy.devicestate.config.Conditions getConditions(); - method public com.android.server.policy.devicestate.config.Flags getFlags(); method public java.math.BigInteger getIdentifier(); method @Nullable public String getName(); + method public com.android.server.policy.devicestate.config.Properties getProperties(); method public void setConditions(com.android.server.policy.devicestate.config.Conditions); - method public void setFlags(com.android.server.policy.devicestate.config.Flags); method public void setIdentifier(java.math.BigInteger); method public void setName(@Nullable String); + method public void setProperties(com.android.server.policy.devicestate.config.Properties); } public class DeviceStateConfig { @@ -25,11 +25,6 @@ package com.android.server.policy.devicestate.config { method public java.util.List<com.android.server.policy.devicestate.config.DeviceState> getDeviceState(); } - public class Flags { - ctor public Flags(); - method @Nullable public java.util.List<java.lang.String> getFlag(); - } - public class LidSwitchCondition { ctor public LidSwitchCondition(); method public boolean getOpen(); @@ -48,6 +43,11 @@ package com.android.server.policy.devicestate.config { method public void setMin_optional(@Nullable java.math.BigDecimal); } + public class Properties { + ctor public Properties(); + method @Nullable public java.util.List<java.lang.String> getProperty(); + } + public class SensorCondition { ctor public SensorCondition(); method public String getName(); diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/BookStyleDeviceStatePolicy.java b/services/foldables/devicestateprovider/src/com/android/server/policy/BookStyleDeviceStatePolicy.java index bc264a46f051..95c4407e3963 100644 --- a/services/foldables/devicestateprovider/src/com/android/server/policy/BookStyleDeviceStatePolicy.java +++ b/services/foldables/devicestateprovider/src/com/android/server/policy/BookStyleDeviceStatePolicy.java @@ -16,29 +16,43 @@ package com.android.server.policy; -import static android.hardware.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS; -import static android.hardware.devicestate.DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; -import static android.hardware.devicestate.DeviceState.FLAG_EMULATED_ONLY; -import static android.hardware.devicestate.DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE; -import static android.hardware.devicestate.DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL; +import static android.hardware.devicestate.DeviceState.PROPERTY_EMULATED_ONLY; +import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT; +import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY; +import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY; +import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY; +import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED; +import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN; +import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL; +import static android.hardware.devicestate.DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP; +import static android.hardware.devicestate.DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE; import static com.android.server.policy.BookStyleStateTransitions.DEFAULT_STATE_TRANSITIONS; -import static com.android.server.policy.FoldableDeviceStateProvider.DeviceStateConfiguration.createConfig; -import static com.android.server.policy.FoldableDeviceStateProvider.DeviceStateConfiguration.createTentModeClosedState; +import static com.android.server.policy.FoldableDeviceStateProvider.DeviceStatePredicateWrapper.createConfig; +import static com.android.server.policy.FoldableDeviceStateProvider.DeviceStatePredicateWrapper.createTentModeClosedState; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorManager; +import android.hardware.devicestate.DeviceState; import android.hardware.display.DisplayManager; import com.android.server.devicestate.DeviceStatePolicy; import com.android.server.devicestate.DeviceStateProvider; -import com.android.server.policy.FoldableDeviceStateProvider.DeviceStateConfiguration; +import com.android.server.policy.FoldableDeviceStateProvider.DeviceStatePredicateWrapper; import com.android.server.policy.feature.flags.FeatureFlags; import java.io.PrintWriter; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.function.Predicate; /** @@ -55,9 +69,8 @@ public class BookStyleDeviceStatePolicy extends DeviceStatePolicy implements private static final int DEVICE_STATE_CLOSED = 0; private static final int DEVICE_STATE_HALF_OPENED = 1; private static final int DEVICE_STATE_OPENED = 2; - private static final int DEVICE_STATE_REAR_DISPLAY_STATE = 3; + private static final int DEVICE_STATE_REAR_DISPLAY = 3; private static final int DEVICE_STATE_CONCURRENT_INNER_DEFAULT = 4; - private static final int TENT_MODE_SWITCH_ANGLE_DEGREES = 90; private static final int TABLE_TOP_MODE_SWITCH_ANGLE_DEGREES = 125; private static final int MIN_CLOSED_ANGLE_DEGREES = 0; @@ -92,81 +105,60 @@ public class BookStyleDeviceStatePolicy extends DeviceStatePolicy implements mEnablePostureBasedClosedState = featureFlags.enableFoldablesPostureBasedClosedState(); mIsDualDisplayBlockingEnabled = featureFlags.enableDualDisplayBlocking(); - final DeviceStateConfiguration[] configuration = createConfiguration( + final DeviceStatePredicateWrapper[] configuration = createConfiguration( leftAccelerometerSensor, rightAccelerometerSensor, closeAngleDegrees); - mProvider = new FoldableDeviceStateProvider(mContext, sensorManager, - hingeAngleSensor, hallSensor, displayManager, configuration); + mProvider = new FoldableDeviceStateProvider(mContext, sensorManager, hingeAngleSensor, + hallSensor, displayManager, configuration); } - private DeviceStateConfiguration[] createConfiguration(@Nullable Sensor leftAccelerometerSensor, - @Nullable Sensor rightAccelerometerSensor, Integer closeAngleDegrees) { - return new DeviceStateConfiguration[]{ + private DeviceStatePredicateWrapper[] createConfiguration( + @Nullable Sensor leftAccelerometerSensor, @Nullable Sensor rightAccelerometerSensor, + Integer closeAngleDegrees) { + return new DeviceStatePredicateWrapper[]{ createClosedConfiguration(leftAccelerometerSensor, rightAccelerometerSensor, closeAngleDegrees), - createConfig(DEVICE_STATE_HALF_OPENED, - /* name= */ "HALF_OPENED", - /* activeStatePredicate= */ (provider) -> { + createConfig(getHalfOpenedDeviceState(), /* activeStatePredicate= */ + (provider) -> { final float hingeAngle = provider.getHingeAngle(); return hingeAngle >= MAX_CLOSED_ANGLE_DEGREES && hingeAngle <= TABLE_TOP_MODE_SWITCH_ANGLE_DEGREES; }), - createConfig(DEVICE_STATE_OPENED, - /* name= */ "OPENED", - /* activeStatePredicate= */ ALLOWED), - createConfig(DEVICE_STATE_REAR_DISPLAY_STATE, - /* name= */ "REAR_DISPLAY_STATE", - /* flags= */ FLAG_EMULATED_ONLY, - /* activeStatePredicate= */ NOT_ALLOWED), - createConfig(DEVICE_STATE_CONCURRENT_INNER_DEFAULT, - /* name= */ "CONCURRENT_INNER_DEFAULT", - /* flags= */ FLAG_EMULATED_ONLY | FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP - | FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE, - /* activeStatePredicate= */ NOT_ALLOWED, - /* availabilityPredicate= */ + createConfig(getOpenedDeviceState(), /* activeStatePredicate= */ + ALLOWED), + createConfig(getRearDisplayDeviceState(), /* activeStatePredicate= */ + NOT_ALLOWED), + createConfig(getDualDisplayDeviceState(), /* activeStatePredicate= */ + NOT_ALLOWED, /* availabilityPredicate= */ provider -> !mIsDualDisplayBlockingEnabled - || provider.hasNoConnectedExternalDisplay()) - }; + || provider.hasNoConnectedExternalDisplay())}; } - private DeviceStateConfiguration createClosedConfiguration( + private DeviceStatePredicateWrapper createClosedConfiguration( @Nullable Sensor leftAccelerometerSensor, @Nullable Sensor rightAccelerometerSensor, @Nullable Integer closeAngleDegrees) { + if (closeAngleDegrees != null) { // Switch displays at closeAngleDegrees in both ways (folding and unfolding) - return createConfig( - DEVICE_STATE_CLOSED, - /* name= */ "CLOSED", - /* flags= */ FLAG_CANCEL_OVERRIDE_REQUESTS, - /* activeStatePredicate= */ (provider) -> { + return createConfig(getClosedDeviceState(), /* activeStatePredicate= */ + (provider) -> { final float hingeAngle = provider.getHingeAngle(); return hingeAngle <= closeAngleDegrees; - } - ); + }); } if (mEnablePostureBasedClosedState) { // Use smart closed state predicate that will use different switch angles // based on the device posture (e.g. wedge mode, tent mode, reverse wedge mode) - return createConfig( - DEVICE_STATE_CLOSED, - /* name= */ "CLOSED", - /* flags= */ FLAG_CANCEL_OVERRIDE_REQUESTS, - /* activeStatePredicate= */ new BookStyleClosedStatePredicate(mContext, - this, leftAccelerometerSensor, rightAccelerometerSensor, - DEFAULT_STATE_TRANSITIONS) - ); + return createConfig(getClosedDeviceState(), /* activeStatePredicate= */ + new BookStyleClosedStatePredicate(mContext, this, leftAccelerometerSensor, + rightAccelerometerSensor, DEFAULT_STATE_TRANSITIONS)); } // Switch to the outer display only at 0 degrees but use TENT_MODE_SWITCH_ANGLE_DEGREES // angle when switching to the inner display - return createTentModeClosedState(DEVICE_STATE_CLOSED, - /* name= */ "CLOSED", - /* flags= */ FLAG_CANCEL_OVERRIDE_REQUESTS, - MIN_CLOSED_ANGLE_DEGREES, - MAX_CLOSED_ANGLE_DEGREES, - TENT_MODE_SWITCH_ANGLE_DEGREES); + return createTentModeClosedState(getClosedDeviceState(), + MIN_CLOSED_ANGLE_DEGREES, MAX_CLOSED_ANGLE_DEGREES, TENT_MODE_SWITCH_ANGLE_DEGREES); } @Override @@ -188,4 +180,84 @@ public class BookStyleDeviceStatePolicy extends DeviceStatePolicy implements public void dump(@NonNull PrintWriter writer, @Nullable String[] args) { mProvider.dump(writer, args); } + + /** Returns the {@link DeviceState.Configuration} that represents the closed state. */ + @NonNull + private DeviceState getClosedDeviceState() { + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties = new HashSet<>( + List.of(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY, + PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP)); + + Set<@DeviceState.PhysicalDeviceStateProperties Integer> physicalProperties = new HashSet<>( + List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED)); + + return new DeviceState(new DeviceState.Configuration.Builder(DEVICE_STATE_CLOSED, "CLOSED") + .setSystemProperties(systemProperties) + .setPhysicalProperties(physicalProperties) + .build()); + } + + /** Returns the {@link DeviceState.Configuration} that represents the half_opened state. */ + @NonNull + private DeviceState getHalfOpenedDeviceState() { + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties = new HashSet<>( + List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, + PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE)); + + Set<@DeviceState.PhysicalDeviceStateProperties Integer> physicalProperties = new HashSet<>( + List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN)); + + return new DeviceState(new DeviceState.Configuration.Builder(DEVICE_STATE_HALF_OPENED, + "HALF_OPENED") + .setSystemProperties(systemProperties) + .setPhysicalProperties(physicalProperties) + .build()); + } + + /** Returns the {@link DeviceState.Configuration} that represents the opened state */ + @NonNull + private DeviceState getOpenedDeviceState() { + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties = new HashSet<>( + List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, + PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE)); + Set<@DeviceState.PhysicalDeviceStateProperties Integer> physicalProperties = new HashSet<>( + List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)); + + return new DeviceState(new DeviceState.Configuration.Builder(DEVICE_STATE_OPENED, "OPENED") + .setSystemProperties(systemProperties) + .setPhysicalProperties(physicalProperties) + .build()); + } + + /** Returns the {@link DeviceState.Configuration} that represents the rear display state. */ + @NonNull + private DeviceState getRearDisplayDeviceState() { + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties = new HashSet<>( + List.of(PROPERTY_EMULATED_ONLY, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST, PROPERTY_FEATURE_REAR_DISPLAY)); + + return new DeviceState(new DeviceState.Configuration.Builder(DEVICE_STATE_REAR_DISPLAY, + "REAR_DISPLAY_STATE") + .setSystemProperties(systemProperties) + .build()); + } + + /** Returns the {@link DeviceState.Configuration} that represents the dual display state. */ + @NonNull + private DeviceState getDualDisplayDeviceState() { + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties = new HashSet<>( + List.of(PROPERTY_EMULATED_ONLY, PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST, + PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, + PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, + PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT)); + + return new DeviceState(new DeviceState.Configuration.Builder( + DEVICE_STATE_CONCURRENT_INNER_DEFAULT, "CONCURRENT_INNER_DEFAULT") + .setSystemProperties(systemProperties) + .build()); + } } diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java index 42e41d59cfeb..bc8643f3d173 100644 --- a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java +++ b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java @@ -17,13 +17,12 @@ package com.android.server.policy; import static android.hardware.SensorManager.SENSOR_DELAY_FASTEST; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; -import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; -import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.TYPE_EXTERNAL; -import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; @@ -89,7 +88,7 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, // the conditions needed for availability. private final SparseArray<BooleanSupplier> mStateAvailabilityConditions = new SparseArray<>(); - private final DeviceStateConfiguration[] mConfigurations; + private final DeviceStatePredicateWrapper[] mConfigurations; @GuardedBy("mLock") private final SparseBooleanArray mExternalDisplaysConnected = new SparseBooleanArray(); @@ -103,7 +102,7 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, @GuardedBy("mLock") private Listener mListener = null; @GuardedBy("mLock") - private int mLastReportedState = INVALID_DEVICE_STATE; + private int mLastReportedState = INVALID_DEVICE_STATE_IDENTIFIER; @GuardedBy("mLock") private SensorEvent mLastHingeAngleSensorEvent = null; @GuardedBy("mLock") @@ -125,9 +124,9 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, @NonNull Sensor hingeAngleSensor, @NonNull Sensor hallSensor, @NonNull DisplayManager displayManager, - @NonNull DeviceStateConfiguration[] deviceStateConfigurations) { + @NonNull DeviceStatePredicateWrapper[] deviceStatePredicateWrappers) { this(new FeatureFlagsImpl(), context, sensorManager, hingeAngleSensor, hallSensor, - displayManager, deviceStateConfigurations); + displayManager, deviceStatePredicateWrappers); } @VisibleForTesting @@ -138,23 +137,23 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, @NonNull Sensor hingeAngleSensor, @NonNull Sensor hallSensor, @NonNull DisplayManager displayManager, - @NonNull DeviceStateConfiguration[] deviceStateConfigurations) { + @NonNull DeviceStatePredicateWrapper[] deviceStatePredicateWrappers) { - Preconditions.checkArgument(deviceStateConfigurations.length > 0, + Preconditions.checkArgument(deviceStatePredicateWrappers.length > 0, "Device state configurations array must not be empty"); mHingeAngleSensor = hingeAngleSensor; mHallSensor = hallSensor; mDisplayManager = displayManager; - mConfigurations = deviceStateConfigurations; + mConfigurations = deviceStatePredicateWrappers; mIsDualDisplayBlockingEnabled = featureFlags.enableDualDisplayBlocking(); sensorManager.registerListener(this, mHingeAngleSensor, SENSOR_DELAY_FASTEST); sensorManager.registerListener(this, mHallSensor, SENSOR_DELAY_FASTEST); - mOrderedStates = new DeviceState[deviceStateConfigurations.length]; - for (int i = 0; i < deviceStateConfigurations.length; i++) { - final DeviceStateConfiguration configuration = deviceStateConfigurations[i]; + mOrderedStates = new DeviceState[deviceStatePredicateWrappers.length]; + for (int i = 0; i < deviceStatePredicateWrappers.length; i++) { + final DeviceStatePredicateWrapper configuration = deviceStatePredicateWrappers[i]; mOrderedStates[i] = configuration.mDeviceState; assertUniqueDeviceStateIdentifier(configuration); @@ -174,14 +173,14 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, // If any of the device states are thermal sensitive, i.e. it should be disabled when // the device is overheating, then we will update the list of supported states when // thermal status changes. - if (hasThermalSensitiveState(deviceStateConfigurations)) { + if (hasThermalSensitiveState(deviceStatePredicateWrappers)) { powerManager.addThermalStatusListener(this); } // If any of the device states are power sensitive, i.e. it should be disabled when // power save mode is enabled, then we will update the list of supported states when // power save mode is toggled. - if (hasPowerSaveSensitiveState(deviceStateConfigurations)) { + if (hasPowerSaveSensitiveState(deviceStatePredicateWrappers)) { IntentFilter filter = new IntentFilter( PowerManager.ACTION_POWER_SAVE_MODE_CHANGED_INTERNAL); BroadcastReceiver receiver = new BroadcastReceiver() { @@ -198,7 +197,7 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } } - private void assertUniqueDeviceStateIdentifier(DeviceStateConfiguration configuration) { + private void assertUniqueDeviceStateIdentifier(DeviceStatePredicateWrapper configuration) { if (mStateConditions.get(configuration.mDeviceState.getIdentifier()) != null) { throw new IllegalArgumentException("Device state configurations must have unique" + " device state identifiers, found duplicated identifier: " @@ -206,12 +205,12 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } } - private void initialiseStateConditions(DeviceStateConfiguration configuration) { + private void initialiseStateConditions(DeviceStatePredicateWrapper configuration) { mStateConditions.put(configuration.mDeviceState.getIdentifier(), () -> configuration.mActiveStatePredicate.test(this)); } - private void initialiseStateAvailabilityConditions(DeviceStateConfiguration configuration) { + private void initialiseStateAvailabilityConditions(DeviceStatePredicateWrapper configuration) { mStateAvailabilityConditions.put(configuration.mDeviceState.getIdentifier(), () -> configuration.mAvailabilityPredicate.test(this)); } @@ -250,13 +249,12 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, @GuardedBy("mLock") private boolean isStateSupported(DeviceState deviceState) { - if (isThermalStatusCriticalOrAbove(mThermalStatus) - && deviceState.hasFlag( - DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { + if (isThermalStatusCriticalOrAbove(mThermalStatus) && deviceState.hasProperty( + PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { return false; } - if (mPowerSaveModeEnabled && deviceState.hasFlag( - DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { + if (mPowerSaveModeEnabled && deviceState.hasProperty( + PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { return false; } if (mIsDualDisplayBlockingEnabled @@ -270,7 +268,7 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, /** Computes the current device state and notifies the listener of a change, if needed. */ void notifyDeviceStateChangedIfNeeded() { - int stateToReport = INVALID_DEVICE_STATE; + int stateToReport = INVALID_DEVICE_STATE_IDENTIFIER; Listener listener; synchronized (mLock) { if (mListener == null) { @@ -279,7 +277,7 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, listener = mListener; - int newState = INVALID_DEVICE_STATE; + int newState = INVALID_DEVICE_STATE_IDENTIFIER; for (int i = 0; i < mOrderedStates.length; i++) { int state = mOrderedStates[i].getIdentifier(); if (DEBUG) { @@ -307,18 +305,18 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, break; } } - if (newState == INVALID_DEVICE_STATE) { + if (newState == INVALID_DEVICE_STATE_IDENTIFIER) { Slog.e(TAG, "No declared device states match any of the required conditions."); dumpSensorValues(); } - if (newState != INVALID_DEVICE_STATE && newState != mLastReportedState) { + if (newState != INVALID_DEVICE_STATE_IDENTIFIER && newState != mLastReportedState) { mLastReportedState = newState; stateToReport = newState; } } - if (stateToReport != INVALID_DEVICE_STATE) { + if (stateToReport != INVALID_DEVICE_STATE_IDENTIFIER) { listener.onStateChanged(stateToReport); } } @@ -441,7 +439,7 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, writer.println(" Predicates:"); for (int i = 0; i < mConfigurations.length; i++) { - final DeviceStateConfiguration configuration = mConfigurations[i]; + final DeviceStatePredicateWrapper configuration = mConfigurations[i]; final Predicate<FoldableDeviceStateProvider> predicate = configuration.mActiveStatePredicate; @@ -452,22 +450,23 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } /** - * Configuration for a single device state, contains information about the state like + * Configuration wrapper for a single device state, contains information about the state like * identifier, name, flags and a predicate that should return true if the state should * be selected. */ - public static class DeviceStateConfiguration { + public static class DeviceStatePredicateWrapper { private final DeviceState mDeviceState; private final Predicate<FoldableDeviceStateProvider> mActiveStatePredicate; private final Predicate<FoldableDeviceStateProvider> mAvailabilityPredicate; - private DeviceStateConfiguration( + private DeviceStatePredicateWrapper( @NonNull DeviceState deviceState, @NonNull Predicate<FoldableDeviceStateProvider> predicate) { this(deviceState, predicate, ALLOWED); } - private DeviceStateConfiguration( + /** Create a configuration with availability and availability predicate **/ + private DeviceStatePredicateWrapper( @NonNull DeviceState deviceState, @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate, @NonNull Predicate<FoldableDeviceStateProvider> availabilityPredicate) { @@ -477,38 +476,22 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, mAvailabilityPredicate = availabilityPredicate; } - public static DeviceStateConfiguration createConfig( - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = - MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, - @NonNull String name, - @DeviceState.DeviceStateFlags int flags, - @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate - ) { - return new DeviceStateConfiguration(new DeviceState(identifier, name, flags), - activeStatePredicate); - } - - public static DeviceStateConfiguration createConfig( - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = - MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, - @NonNull String name, + /** Create a configuration with an active state predicate **/ + public static DeviceStatePredicateWrapper createConfig( + @NonNull DeviceState deviceState, @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate ) { - return new DeviceStateConfiguration(new DeviceState(identifier, name, /* flags= */ 0), - activeStatePredicate); + return new DeviceStatePredicateWrapper(deviceState, activeStatePredicate); } - /** Create a configuration with availability predicate **/ - public static DeviceStateConfiguration createConfig( - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = - MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, - @NonNull String name, - @DeviceState.DeviceStateFlags int flags, + /** Create a configuration with availability and active state predicate **/ + public static DeviceStatePredicateWrapper createConfig( + @NonNull DeviceState deviceState, @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate, @NonNull Predicate<FoldableDeviceStateProvider> availabilityPredicate ) { - return new DeviceStateConfiguration(new DeviceState(identifier, name, flags), - activeStatePredicate, availabilityPredicate); + return new DeviceStatePredicateWrapper(deviceState, activeStatePredicate, + availabilityPredicate); } /** @@ -536,25 +519,20 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, * so the switch from the inner display to the outer will become only when the device * is fully closed. * - * @param identifier state identifier - * @param name state name - * @param flags state flags + * @param deviceState {@link DeviceState} that corresponds to this state. * @param minClosedAngleDegrees minimum (inclusive) hinge angle value for the closed state * @param maxClosedAngleDegrees maximum (non-inclusive) hinge angle value for the closed * state * @param tentModeSwitchAngleDegrees the angle when this state should switch when unfolding * @return device state configuration */ - public static DeviceStateConfiguration createTentModeClosedState( - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = - MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, - @NonNull String name, - @DeviceState.DeviceStateFlags int flags, + public static DeviceStatePredicateWrapper createTentModeClosedState( + @NonNull DeviceState deviceState, int minClosedAngleDegrees, int maxClosedAngleDegrees, int tentModeSwitchAngleDegrees ) { - return new DeviceStateConfiguration(new DeviceState(identifier, name, flags), + return new DeviceStatePredicateWrapper(deviceState, (stateContext) -> { final boolean hallSensorClosed = stateContext.isHallSensorClosed(); final float hingeAngle = stateContext.getHingeAngle(); @@ -564,9 +542,9 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, final int switchingDegrees = isScreenOn ? tentModeSwitchAngleDegrees : maxClosedAngleDegrees; - final int closedDeviceState = identifier; + final int closedDeviceState = deviceState.getIdentifier(); final boolean isLastStateClosed = lastState == closedDeviceState - || lastState == INVALID_DEVICE_STATE; + || lastState == INVALID_DEVICE_STATE_IDENTIFIER; final boolean shouldBeClosedBecauseTentMode = isLastStateClosed && hingeAngle >= minClosedAngleDegrees @@ -671,21 +649,21 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } } - private static boolean hasThermalSensitiveState(DeviceStateConfiguration[] deviceStates) { + private static boolean hasThermalSensitiveState(DeviceStatePredicateWrapper[] deviceStates) { for (int i = 0; i < deviceStates.length; i++) { - DeviceStateConfiguration state = deviceStates[i]; - if (state.mDeviceState - .hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { + DeviceStatePredicateWrapper state = deviceStates[i]; + if (state.mDeviceState.hasProperty( + PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { return true; } } return false; } - private static boolean hasPowerSaveSensitiveState(DeviceStateConfiguration[] deviceStates) { + private static boolean hasPowerSaveSensitiveState(DeviceStatePredicateWrapper[] deviceStates) { for (int i = 0; i < deviceStates.length; i++) { - if (deviceStates[i].mDeviceState - .hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { + if (deviceStates[i].mDeviceState.hasProperty( + PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { return true; } } diff --git a/services/foldables/devicestateprovider/tests/src/com/android/server/policy/FoldableDeviceStateProviderTest.java b/services/foldables/devicestateprovider/tests/src/com/android/server/policy/FoldableDeviceStateProviderTest.java index 930f4a61a453..c9bbfee753fd 100644 --- a/services/foldables/devicestateprovider/tests/src/com/android/server/policy/FoldableDeviceStateProviderTest.java +++ b/services/foldables/devicestateprovider/tests/src/com/android/server/policy/FoldableDeviceStateProviderTest.java @@ -30,7 +30,7 @@ import static com.android.server.devicestate.DeviceStateProvider.SUPPORTED_DEVIC import static com.android.server.devicestate.DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED; import static com.android.server.devicestate.DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL; import static com.android.server.devicestate.DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_NORMAL; -import static com.android.server.policy.FoldableDeviceStateProvider.DeviceStateConfiguration.createConfig; +import static com.android.server.policy.FoldableDeviceStateProvider.DeviceStatePredicateWrapper.createConfig; import static com.google.common.truth.Truth.assertThat; @@ -59,8 +59,10 @@ import android.os.PowerManager; import android.testing.AndroidTestingRunner; import android.view.Display; +import androidx.annotation.NonNull; + import com.android.server.devicestate.DeviceStateProvider.Listener; -import com.android.server.policy.FoldableDeviceStateProvider.DeviceStateConfiguration; +import com.android.server.policy.FoldableDeviceStateProvider.DeviceStatePredicateWrapper; import com.android.server.policy.feature.flags.FakeFeatureFlagsImpl; import com.android.server.policy.feature.flags.Flags; @@ -73,6 +75,11 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.internal.util.reflection.FieldSetter; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + /** * Unit tests for {@link FoldableDeviceStateProvider}. * <p/> @@ -81,8 +88,14 @@ import org.mockito.internal.util.reflection.FieldSetter; @RunWith(AndroidTestingRunner.class) public final class FoldableDeviceStateProviderTest { - private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = ArgumentCaptor.forClass( - DeviceState[].class); + private static final Set<Integer> EMPTY_PROPERTY_SET = new HashSet<>(); + private static final Set<Integer> THERMAL_PROPERTY_SET = new HashSet<>( + Arrays.asList(DeviceState.PROPERTY_EMULATED_ONLY, + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)); + + private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = + ArgumentCaptor.forClass(DeviceState[].class); @Captor private ArgumentCaptor<Integer> mIntegerCaptor; @Captor @@ -122,22 +135,17 @@ public final class FoldableDeviceStateProviderTest { public void create_duplicatedDeviceStateIdentifiers_throwsException() { assertThrows(IllegalArgumentException.class, () -> createProvider( - createConfig( - /* identifier= */ 0, /* name= */ "ONE", (c) -> true), - createConfig( - /* identifier= */ 0, /* name= */ "TWO", (c) -> true) + createConfig(createDeviceState(0, "ONE"), (c) -> true), + createConfig(createDeviceState(0, "TWO"), (c) -> true) )); } @Test public void create_allMatchingStatesDefaultsToTheFirstIdentifier() { createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", (c) -> true), - createConfig( - /* identifier= */ 2, /* name= */ "TWO", (c) -> true), - createConfig( - /* identifier= */ 3, /* name= */ "THREE", (c) -> true) + createConfig(createDeviceState(1, "ONE"), (c) -> true), + createConfig(createDeviceState(2, "TWO"), (c) -> true), + createConfig(createDeviceState(3, "THREE"), (c) -> true) ); Listener listener = mock(Listener.class); @@ -146,9 +154,9 @@ public final class FoldableDeviceStateProviderTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "ONE", /* flags= */ 0), - new DeviceState(2, "TWO", /* flags= */ 0), - new DeviceState(3, "THREE", /* flags= */ 0), + createDeviceState(1, "ONE", EMPTY_PROPERTY_SET), + createDeviceState(2, "TWO", EMPTY_PROPERTY_SET), + createDeviceState(3, "THREE", EMPTY_PROPERTY_SET) }; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); @@ -159,14 +167,10 @@ public final class FoldableDeviceStateProviderTest { @Test public void create_multipleMatchingStatesDefaultsToTheLowestIdentifier() { createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", (c) -> false), - createConfig( - /* identifier= */ 3, /* name= */ "THREE", (c) -> false), - createConfig( - /* identifier= */ 4, /* name= */ "FOUR", (c) -> true), - createConfig( - /* identifier= */ 2, /* name= */ "TWO", (c) -> true) + createConfig(createDeviceState(1, "ONE"), (c) -> false), + createConfig(createDeviceState(3, "THREE"), (c) -> false), + createConfig(createDeviceState(4, "FOUR"), (c) -> true), + createConfig(createDeviceState(2, "TWO"), (c) -> true) ); Listener listener = mock(Listener.class); @@ -178,9 +182,9 @@ public final class FoldableDeviceStateProviderTest { @Test public void test_hingeAngleUpdatedFirstTime_switchesToMatchingState() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "ONE", + createProvider(createConfig(createDeviceState(1, "ONE"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 2, /* name= */ "TWO", + createConfig(createDeviceState(2, "TWO"), (c) -> c.getHingeAngle() >= 90f)); Listener listener = mock(Listener.class); mProvider.setListener(listener); @@ -195,9 +199,9 @@ public final class FoldableDeviceStateProviderTest { @Test public void test_hallSensorUpdatedFirstTime_switchesToMatchingState() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "ONE", + createProvider(createConfig(createDeviceState(1, "ONE"), (c) -> !c.isHallSensorClosed()), - createConfig(/* identifier= */ 2, /* name= */ "TWO", + createConfig(createDeviceState(2, "TWO"), FoldableDeviceStateProvider::isHallSensorClosed)); Listener listener = mock(Listener.class); mProvider.setListener(listener); @@ -213,9 +217,9 @@ public final class FoldableDeviceStateProviderTest { @Test public void test_hingeAngleUpdatedSecondTime_switchesToMatchingState() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "ONE", + createProvider(createConfig(createDeviceState(1, "ONE"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 2, /* name= */ "TWO", + createConfig(createDeviceState(2, "TWO"), (c) -> c.getHingeAngle() >= 90f)); sendSensorEvent(mHingeAngleSensor, /* value= */ 30f); Listener listener = mock(Listener.class); @@ -232,9 +236,9 @@ public final class FoldableDeviceStateProviderTest { @Test public void test_hallSensorUpdatedSecondTime_switchesToMatchingState() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "ONE", + createProvider(createConfig(createDeviceState(1, "ONE"), (c) -> !c.isHallSensorClosed()), - createConfig(/* identifier= */ 2, /* name= */ "TWO", + createConfig(createDeviceState(2, "TWO"), FoldableDeviceStateProvider::isHallSensorClosed)); sendSensorEvent(mHallSensor, /* value= */ 0f); Listener listener = mock(Listener.class); @@ -252,9 +256,9 @@ public final class FoldableDeviceStateProviderTest { @Test public void test_invalidSensorValues_onStateChangedIsNotTriggered() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "ONE", + createProvider(createConfig(createDeviceState(1, "ONE"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 2, /* name= */ "TWO", + createConfig(createDeviceState(2, "TWO"), (c) -> c.getHingeAngle() >= 90f)); Listener listener = mock(Listener.class); mProvider.setListener(listener); @@ -277,23 +281,21 @@ public final class FoldableDeviceStateProviderTest { @Test public void test_nullSensorValues_noExceptionThrown() throws Exception { - createProvider(createConfig( /* identifier= */ 1, /* name= */ "ONE", - (c) -> c.getHingeAngle() < 90f)); + createProvider(createConfig(createDeviceState(1, "ONE"), + (c) -> c.getHingeAngle() < 90f)); sendInvalidSensorEvent(null); } @Test public void test_flagDisableWhenThermalStatusCritical() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "CLOSED", + createProvider(createConfig(createDeviceState(1, "CLOSED"), (c) -> c.getHingeAngle() < 5f), - createConfig(/* identifier= */ 2, /* name= */ "HALF_OPENED", + createConfig(createDeviceState(2, "HALF_OPENED"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 3, /* name= */ "OPENED", + createConfig(createDeviceState(3, "OPENED"), (c) -> c.getHingeAngle() < 180f), - createConfig(/* identifier= */ 4, /* name= */ "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE, + createConfig( + createDeviceState(4, "THERMAL_TEST", THERMAL_PROPERTY_SET), (c) -> true)); Listener listener = mock(Listener.class); mProvider.setListener(listener); @@ -301,13 +303,10 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)}, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", THERMAL_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); clearInvocations(listener); @@ -322,9 +321,9 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */)}, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); clearInvocations(listener); @@ -334,28 +333,23 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_NORMAL)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)}, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", THERMAL_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); } @Test public void test_flagDisableWhenPowerSaveEnabled() throws Exception { - createProvider(createConfig(/* identifier= */ 1, /* name= */ "CLOSED", + createProvider(createConfig(createDeviceState(1, "CLOSED"), (c) -> c.getHingeAngle() < 5f), - createConfig(/* identifier= */ 2, /* name= */ "HALF_OPENED", + createConfig(createDeviceState(2, "HALF_OPENED"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 3, /* name= */ "OPENED", + createConfig(createDeviceState(3, "OPENED"), (c) -> c.getHingeAngle() < 180f), - createConfig(/* identifier= */ 4, /* name= */ "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE, + createConfig( + createDeviceState(4, "THERMAL_TEST", THERMAL_PROPERTY_SET), (c) -> true)); mProvider.onPowerSaveModeChanged(false /* isPowerSaveModeEnabled */); Listener listener = mock(Listener.class); @@ -365,13 +359,10 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", THERMAL_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); clearInvocations(listener); @@ -386,9 +377,9 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); clearInvocations(listener); @@ -398,13 +389,10 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", THERMAL_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); } @@ -413,13 +401,11 @@ public final class FoldableDeviceStateProviderTest { // Create a configuration where state TWO could be matched only if // the previous state was 'THREE' createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", (c) -> c.getHingeAngle() < 30f), - createConfig( - /* identifier= */ 2, /* name= */ "TWO", + createConfig(createDeviceState(1, "ONE"), + (c) -> c.getHingeAngle() < 30f), + createConfig(createDeviceState(2, "TWO"), (c) -> c.getLastReportedDeviceState() == 3 && c.getHingeAngle() > 120f), - createConfig( - /* identifier= */ 3, /* name= */ "THREE", + createConfig(createDeviceState(3, "THREE"), (c) -> c.getHingeAngle() > 90f) ); sendSensorEvent(mHingeAngleSensor, /* value= */ 0f); @@ -448,8 +434,7 @@ public final class FoldableDeviceStateProviderTest { @Test public void isScreenOn_afterDisplayChangedToOn_returnsTrue() { createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", (c) -> true) + createConfig(createDeviceState(1, "ONE"), (c) -> true) ); setScreenOn(true); @@ -460,8 +445,7 @@ public final class FoldableDeviceStateProviderTest { @Test public void isScreenOn_afterDisplayChangedToOff_returnsFalse() { createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", (c) -> true) + createConfig(createDeviceState(1, "ONE"), (c) -> true) ); setScreenOn(false); @@ -472,8 +456,7 @@ public final class FoldableDeviceStateProviderTest { @Test public void isScreenOn_afterDisplayChangedToOnThenOff_returnsFalse() { createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", (c) -> true) + createConfig(createDeviceState(1, "ONE"), (c) -> true) ); setScreenOn(true); @@ -487,14 +470,14 @@ public final class FoldableDeviceStateProviderTest { when(mDisplayManager.getDisplays()).thenReturn(new Display[]{mDefaultDisplay}); when(mDefaultDisplay.getType()).thenReturn(TYPE_INTERNAL); - createProvider(createConfig(/* identifier= */ 1, /* name= */ "CLOSED", + createProvider(createConfig(createDeviceState(1, "CLOSED"), (c) -> c.getHingeAngle() < 5f), - createConfig(/* identifier= */ 2, /* name= */ "HALF_OPENED", + createConfig(createDeviceState(2, "HALF_OPENED"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 3, /* name= */ "OPENED", + createConfig(createDeviceState(3, "OPENED"), (c) -> c.getHingeAngle() < 180f), - createConfig(/* identifier= */ 4, /* name= */ "DUAL_DISPLAY", /* flags */ 0, - (c) -> false, FoldableDeviceStateProvider::hasNoConnectedExternalDisplay)); + createConfig(createDeviceState(4, "DUAL_DISPLAY"), (c) -> false, + FoldableDeviceStateProvider::hasNoConnectedExternalDisplay)); Listener listener = mock(Listener.class); mProvider.setListener(listener); @@ -502,10 +485,11 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertThat(mDeviceStateArrayCaptor.getValue()).asList().containsExactly( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "DUAL_DISPLAY", 0 /* flags */)}).inOrder(); + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "DUAL_DISPLAY", + EMPTY_PROPERTY_SET)}).inOrder(); clearInvocations(listener); @@ -520,9 +504,9 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_EXTERNAL_DISPLAY_ADDED)); assertThat(mDeviceStateArrayCaptor.getValue()).asList().containsExactly( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */)}).inOrder(); + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}).inOrder(); clearInvocations(listener); // The DUAL_DISPLAY state should be re-enabled. @@ -532,10 +516,11 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_EXTERNAL_DISPLAY_REMOVED)); assertThat(mDeviceStateArrayCaptor.getValue()).asList().containsExactly( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "DUAL_DISPLAY", 0 /* flags */)}).inOrder(); + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "DUAL_DISPLAY", + EMPTY_PROPERTY_SET)}).inOrder(); } @Test @@ -543,14 +528,14 @@ public final class FoldableDeviceStateProviderTest { when(mDisplayManager.getDisplays()).thenReturn(new Display[]{mDefaultDisplay}); when(mDefaultDisplay.getType()).thenReturn(TYPE_INTERNAL); - createProvider(createConfig(/* identifier= */ 1, /* name= */ "CLOSED", + createProvider(createConfig(createDeviceState(1, "CLOSED"), (c) -> c.getHingeAngle() < 5f), - createConfig(/* identifier= */ 2, /* name= */ "HALF_OPENED", + createConfig(createDeviceState(2, "HALF_OPENED"), (c) -> c.getHingeAngle() < 90f), - createConfig(/* identifier= */ 3, /* name= */ "OPENED", + createConfig(createDeviceState(3, "OPENED"), (c) -> c.getHingeAngle() < 180f), - createConfig(/* identifier= */ 4, /* name= */ "DUAL_DISPLAY", /* flags */ 0, - (c) -> false, FoldableDeviceStateProvider::hasNoConnectedExternalDisplay)); + createConfig(createDeviceState(4, "DUAL_DISPLAY"), + FoldableDeviceStateProvider::hasNoConnectedExternalDisplay)); Listener listener = mock(Listener.class); mProvider.setListener(listener); @@ -558,10 +543,11 @@ public final class FoldableDeviceStateProviderTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertThat(mDeviceStateArrayCaptor.getValue()).asList().containsExactly( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "DUAL_DISPLAY", 0 /* flags */)}).inOrder(); + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "DUAL_DISPLAY", + EMPTY_PROPERTY_SET)}).inOrder(); clearInvocations(listener); @@ -579,10 +565,8 @@ public final class FoldableDeviceStateProviderTest { @Test public void hasNoConnectedDisplay_afterExternalDisplayAdded_returnsFalse() { createProvider( - createConfig( - /* identifier= */ 1, /* name= */ "ONE", - /* flags= */0, (c) -> true, - FoldableDeviceStateProvider::hasNoConnectedExternalDisplay) + createConfig(createDeviceState(1, "ONE", Collections.emptySet()), + (c) -> true, FoldableDeviceStateProvider::hasNoConnectedExternalDisplay) ); addExternalDisplay(/* displayId */ 1); @@ -594,9 +578,8 @@ public final class FoldableDeviceStateProviderTest { public void testOnDisplayAddedWithNullDisplayDoesNotThrowNPE() { createProvider( createConfig( - /* identifier= */ 1, /* name= */ "ONE", - /* flags= */0, (c) -> true, - FoldableDeviceStateProvider::hasNoConnectedExternalDisplay) + createDeviceState(1, "ONE", Collections.emptySet()), + (c) -> true, FoldableDeviceStateProvider::hasNoConnectedExternalDisplay) ); when(mDisplayManager.getDisplay(1)).thenReturn(null); @@ -608,9 +591,8 @@ public final class FoldableDeviceStateProviderTest { public void hasNoConnectedDisplay_afterExternalDisplayAddedAndRemoved_returnsTrue() { createProvider( createConfig( - /* identifier= */ 1, /* name= */ "ONE", - /* flags= */0, (c) -> true, - FoldableDeviceStateProvider::hasNoConnectedExternalDisplay) + createDeviceState(1, "ONE", Collections.emptySet()), + (c) -> true, FoldableDeviceStateProvider::hasNoConnectedExternalDisplay) ); addExternalDisplay(/* displayId */ 1); @@ -657,7 +639,7 @@ public final class FoldableDeviceStateProviderTest { mProvider.onSensorChanged(event); } - private void createProvider(DeviceStateConfiguration... configurations) { + private void createProvider(DeviceStatePredicateWrapper... configurations) { mProvider = new FoldableDeviceStateProvider(mFakeFeatureFlags, mContext, mSensorManager, mHingeAngleSensor, mHallSensor, mDisplayManager, configurations); verify(mDisplayManager) @@ -665,4 +647,23 @@ public final class FoldableDeviceStateProviderTest { mDisplayListenerCaptor.capture(), nullable(Handler.class)); } + + /** + * Returns a new {@link DeviceState} object + */ + private DeviceState createDeviceState(int identifier, + @NonNull String name, + @NonNull Set<@DeviceState.DeviceStateProperties Integer> systemProperties) { + return new DeviceState(new DeviceState.Configuration.Builder(identifier, name) + .setSystemProperties(systemProperties) + .build()); + } + + /** + * Returns a new {@link DeviceState} object + */ + private DeviceState createDeviceState(int identifier, + @NonNull String name) { + return createDeviceState(identifier, name, Collections.emptySet()); + } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 9d95c5b4f649..2112dae0f311 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -76,6 +76,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.IStorageManager; @@ -1089,6 +1090,7 @@ public final class SystemServer implements Dumpable { final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); + Trace.registerWithPerfetto(); } /** diff --git a/services/permission/java/com/android/server/permission/access/AccessPersistence.kt b/services/permission/java/com/android/server/permission/access/AccessPersistence.kt index d0913d29f504..58714a8eedaa 100644 --- a/services/permission/java/com/android/server/permission/access/AccessPersistence.kt +++ b/services/permission/java/com/android/server/permission/access/AccessPersistence.kt @@ -25,9 +25,9 @@ import android.util.AtomicFile import android.util.Slog import android.util.SparseLongArray import com.android.internal.annotations.GuardedBy -import com.android.internal.os.BackgroundThread import com.android.modules.utils.BinaryXmlPullParser import com.android.modules.utils.BinaryXmlSerializer +import com.android.server.IoThread import com.android.server.permission.access.collection.* // ktlint-disable no-wildcard-imports import com.android.server.permission.access.immutable.* // ktlint-disable no-wildcard-imports import com.android.server.permission.access.util.PermissionApex @@ -47,7 +47,7 @@ class AccessPersistence(private val policy: AccessPolicy) { private val writeLock = Any() fun initialize() { - writeHandler = WriteHandler(BackgroundThread.getHandler().looper) + writeHandler = WriteHandler(IoThread.getHandler().looper) } /** diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java index bed6f928a55c..2939192d3d2e 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -16,7 +16,7 @@ package com.android.server.display; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY_GROUP; import static android.view.Display.FLAG_REAR; @@ -674,7 +674,7 @@ public class LogicalDisplayMapperTest { /* isInteractive= */true, /* isBootCompleted= */true)); assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED, - INVALID_DEVICE_STATE, + INVALID_DEVICE_STATE_IDENTIFIER, /* isOverrideActive= */false, /* isInteractive= */true, /* isBootCompleted= */true)); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java index 079bc37b6642..a2756ffc9add 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -42,6 +42,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; 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.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -1478,7 +1479,8 @@ public final class BroadcastQueueModernImplTest extends BaseBroadcastQueueTest { eq(BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST), eq(BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD), anyLong(), anyLong(), anyLong(), anyInt(), nullable(String.class), - anyString(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()), + anyString(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), + anyBoolean(), anyLong()), times(1)); } 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 7ea722be9878..7f88b0031191 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java @@ -67,7 +67,6 @@ import android.os.Handler; import android.os.IBinder; import android.os.LocaleList; import android.os.UserHandle; -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; @@ -851,26 +850,6 @@ public class AccessibilityManagerServiceTest { } @Test - @RequiresFlagsDisabled(Flags.FLAG_SCAN_PACKAGES_WITHOUT_LOCK) - // Test old behavior to validate lock detection for the old (locked access) case. - public void testPackageMonitorScanPackages_scansWhileHoldingLock() { - setupAccessibilityServiceConnection(0); - final AtomicReference<Set<Boolean>> lockState = collectLockStateWhilePackageScanning(); - when(mMockPackageManager.queryIntentServicesAsUser(any(), anyInt(), anyInt())) - .thenReturn(List.of(mMockResolveInfo)); - when(mMockSecurityPolicy.canRegisterService(any())).thenReturn(true); - - final Intent packageIntent = new Intent(Intent.ACTION_PACKAGE_ADDED); - packageIntent.setData(Uri.parse("test://package")); - packageIntent.putExtra(Intent.EXTRA_USER_HANDLE, mA11yms.getCurrentUserIdLocked()); - packageIntent.putExtra(Intent.EXTRA_REPLACING, true); - mA11yms.getPackageMonitor().doHandlePackageEvent(packageIntent); - - assertThat(lockState.get()).containsExactly(true); - } - - @Test - @RequiresFlagsEnabled(Flags.FLAG_SCAN_PACKAGES_WITHOUT_LOCK) public void testPackageMonitorScanPackages_scansWithoutHoldingLock() { setupAccessibilityServiceConnection(0); final AtomicReference<Set<Boolean>> lockState = collectLockStateWhilePackageScanning(); @@ -888,7 +867,6 @@ public class AccessibilityManagerServiceTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_SCAN_PACKAGES_WITHOUT_LOCK) public void testSwitchUserScanPackages_scansWithoutHoldingLock() { setupAccessibilityServiceConnection(0); final AtomicReference<Set<Boolean>> lockState = collectLockStateWhilePackageScanning(); diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index ea1a68abe37b..7891661f6338 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -1342,7 +1342,7 @@ public class UserControllerTest { @Override protected int broadcastIntent(Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, - String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, + String[] requiredPermissions, int appOp, Bundle bOptions, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId) { Log.i(TAG, "broadcastIntentLocked " + intent); diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index b7050771d2e4..733f0565fd83 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -16,7 +16,7 @@ package com.android.server.devicestate; -import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; import static com.android.compatibility.common.util.PollingCheck.waitFor; @@ -48,8 +48,6 @@ import com.android.compatibility.common.util.PollingCheck; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.WindowProcessController; -import junit.framework.Assert; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,6 +55,8 @@ import org.junit.runner.RunWith; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Optional; import javax.annotation.Nullable; @@ -69,21 +69,25 @@ import javax.annotation.Nullable; @Presubmit @RunWith(AndroidJUnit4.class) public final class DeviceStateManagerServiceTest { - private static final DeviceState DEFAULT_DEVICE_STATE = - new DeviceState(0, "DEFAULT", 0 /* flags */); - private static final DeviceState OTHER_DEVICE_STATE = - new DeviceState(1, "OTHER", 0 /* flags */); - private static final DeviceState - DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = - new DeviceState(2, "DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP", - DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP /* flags */); + private static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(0, "DEFAULT").build()); + private static final DeviceState OTHER_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(1, "DEFAULT").build()); + private static final DeviceState DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = + new DeviceState(new DeviceState.Configuration.Builder(2, + "DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP") + .setSystemProperties(new HashSet<>(List.of( + DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP))) + .build()); + // A device state that is not reported as being supported for the default test provider. - private static final DeviceState UNSUPPORTED_DEVICE_STATE = - new DeviceState(255, "UNSUPPORTED", 0 /* flags */); + private static final DeviceState UNSUPPORTED_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(255, "UNSUPPORTED") + .build()); - private static final int[] SUPPORTED_DEVICE_STATE_IDENTIFIERS = - new int[]{DEFAULT_DEVICE_STATE.getIdentifier(), OTHER_DEVICE_STATE.getIdentifier(), - DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP.getIdentifier()}; + private static final List<DeviceState> SUPPORTED_DEVICE_STATES = Arrays.asList( + DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, + DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); private static final int FAKE_PROCESS_ID = 100; @@ -201,9 +205,8 @@ public final class DeviceStateManagerServiceTest { @Test public void baseStateChanged_invalidState() { - assertThrows(IllegalArgumentException.class, () -> { - mProvider.setState(INVALID_DEVICE_STATE); - }); + assertThrows(IllegalArgumentException.class, + () -> mProvider.setState(INVALID_DEVICE_STATE_IDENTIFIER)); assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); @@ -224,7 +227,7 @@ public final class DeviceStateManagerServiceTest { assertEquals(mSysPropSetter.getValue(), DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName()); assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); - assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE, + assertThat(mService.getSupportedStates()).containsExactly(DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); mProvider.notifySupportedDeviceStates(new DeviceState[]{DEFAULT_DEVICE_STATE}); @@ -237,10 +240,9 @@ public final class DeviceStateManagerServiceTest { assertEquals(mSysPropSetter.getValue(), DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName()); assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); - assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE); + assertThat(mService.getSupportedStates()).containsExactly(DEFAULT_DEVICE_STATE); - assertArrayEquals(callback.getLastNotifiedInfo().supportedStates, - new int[]{DEFAULT_DEVICE_STATE.getIdentifier()}); + assertEquals(callback.getLastNotifiedInfo().supportedStates, List.of(DEFAULT_DEVICE_STATE)); } @Test @@ -257,7 +259,7 @@ public final class DeviceStateManagerServiceTest { assertEquals(mSysPropSetter.getValue(), DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName()); assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); - assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE, + assertThat(mService.getSupportedStates()).containsExactly(DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); mProvider.notifySupportedDeviceStates(new DeviceState[]{DEFAULT_DEVICE_STATE, @@ -271,7 +273,7 @@ public final class DeviceStateManagerServiceTest { assertEquals(mSysPropSetter.getValue(), DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName()); assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); - assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE, + assertThat(mService.getSupportedStates()).containsExactly(DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); // The callback wasn't notified about a change in supported states as the states have not @@ -283,9 +285,9 @@ public final class DeviceStateManagerServiceTest { public void getDeviceStateInfo() throws RemoteException { DeviceStateInfo info = mService.getBinderService().getDeviceStateInfo(); assertNotNull(info); - assertArrayEquals(info.supportedStates, SUPPORTED_DEVICE_STATE_IDENTIFIERS); - assertEquals(info.baseState, DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier()); + assertEquals(info.supportedStates, SUPPORTED_DEVICE_STATES); + assertEquals(info.baseState, DEFAULT_DEVICE_STATE); + assertEquals(info.currentState, DEFAULT_DEVICE_STATE); } @FlakyTest(bugId = 297949293) @@ -299,9 +301,9 @@ public final class DeviceStateManagerServiceTest { DeviceStateInfo info = mService.getBinderService().getDeviceStateInfo(); - assertArrayEquals(info.supportedStates, SUPPORTED_DEVICE_STATE_IDENTIFIERS); - assertEquals(info.baseState, INVALID_DEVICE_STATE); - assertEquals(info.currentState, INVALID_DEVICE_STATE); + assertEquals(info.supportedStates, SUPPORTED_DEVICE_STATES); + assertEquals(info.baseState.getIdentifier(), INVALID_DEVICE_STATE_IDENTIFIER); + assertEquals(info.currentState.getIdentifier(), INVALID_DEVICE_STATE_IDENTIFIER); } @Test @@ -310,33 +312,33 @@ public final class DeviceStateManagerServiceTest { mService.getBinderService().registerCallback(callback); mProvider.setState(OTHER_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().baseState + waitAndAssert(() -> callback.getLastNotifiedInfo().baseState.getIdentifier() == OTHER_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().currentState + waitAndAssert(() -> callback.getLastNotifiedInfo().currentState.getIdentifier() == OTHER_DEVICE_STATE.getIdentifier()); mProvider.setState(DEFAULT_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().baseState + waitAndAssert(() -> callback.getLastNotifiedInfo().baseState.getIdentifier() == DEFAULT_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().currentState + waitAndAssert(() -> callback.getLastNotifiedInfo().currentState.getIdentifier() == DEFAULT_DEVICE_STATE.getIdentifier()); mPolicy.blockConfigure(); mProvider.setState(OTHER_DEVICE_STATE.getIdentifier()); // The callback should not have been notified of the state change as the policy is still // pending callback. - waitAndAssert(() -> callback.getLastNotifiedInfo().baseState + waitAndAssert(() -> callback.getLastNotifiedInfo().baseState.getIdentifier() == DEFAULT_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().currentState + waitAndAssert(() -> callback.getLastNotifiedInfo().currentState.getIdentifier() == DEFAULT_DEVICE_STATE.getIdentifier()); mPolicy.resumeConfigure(); // Now that the policy is finished processing the callback should be notified of the state // change. - waitAndAssert(() -> callback.getLastNotifiedInfo().baseState + waitAndAssert(() -> callback.getLastNotifiedInfo().baseState.getIdentifier() == OTHER_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().currentState + waitAndAssert(() -> callback.getLastNotifiedInfo().currentState.getIdentifier() == OTHER_DEVICE_STATE.getIdentifier()); } @@ -346,10 +348,8 @@ public final class DeviceStateManagerServiceTest { mService.getBinderService().registerCallback(callback); flushHandler(); assertNotNull(callback.getLastNotifiedInfo()); - assertEquals(callback.getLastNotifiedInfo().baseState, - DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - DEFAULT_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().baseState, DEFAULT_DEVICE_STATE); + assertEquals(callback.getLastNotifiedInfo().currentState, DEFAULT_DEVICE_STATE); } @Test @@ -392,10 +392,8 @@ public final class DeviceStateManagerServiceTest { OTHER_DEVICE_STATE.getIdentifier()); assertNotNull(callback.getLastNotifiedInfo()); - assertEquals(callback.getLastNotifiedInfo().baseState, - DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - OTHER_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().baseState, DEFAULT_DEVICE_STATE); + assertEquals(callback.getLastNotifiedInfo().currentState, OTHER_DEVICE_STATE); mService.getBinderService().cancelStateRequest(); @@ -410,10 +408,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().baseState, - DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - DEFAULT_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().baseState, DEFAULT_DEVICE_STATE); + assertEquals(callback.getLastNotifiedInfo().currentState, DEFAULT_DEVICE_STATE); } @FlakyTest(bugId = 200332057) @@ -636,7 +632,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); - mProvider.notifySupportedDeviceStates(new DeviceState[]{ DEFAULT_DEVICE_STATE }); + mProvider.notifySupportedDeviceStates( + new DeviceState[]{DEFAULT_DEVICE_STATE}); flushHandler(); // Request is canceled because the state is no longer supported. @@ -672,7 +669,8 @@ public final class DeviceStateManagerServiceTest { assertThrows(IllegalArgumentException.class, () -> { final IBinder token = new Binder(); - mService.getBinderService().requestState(token, INVALID_DEVICE_STATE, 0 /* flags */); + mService.getBinderService().requestState(token, INVALID_DEVICE_STATE_IDENTIFIER, + 0 /* flags */); }); } @@ -712,10 +710,8 @@ public final class DeviceStateManagerServiceTest { OTHER_DEVICE_STATE.getIdentifier()); assertNotNull(callback.getLastNotifiedInfo()); - assertEquals(callback.getLastNotifiedInfo().baseState, - OTHER_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - OTHER_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().baseState, OTHER_DEVICE_STATE); + assertEquals(callback.getLastNotifiedInfo().currentState, OTHER_DEVICE_STATE); mService.getBinderService().cancelBaseStateOverride(); @@ -731,19 +727,19 @@ public final class DeviceStateManagerServiceTest { assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().baseState + waitAndAssert(() -> callback.getLastNotifiedInfo().baseState.getIdentifier() == DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - DEFAULT_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().currentState, DEFAULT_DEVICE_STATE); } @Test public void requestBaseStateOverride_cancelledByBaseStateUpdate() throws RemoteException { - final DeviceState testDeviceState = new DeviceState(2, "TEST", 0); + final DeviceState testDeviceState = new DeviceState(new DeviceState.Configuration.Builder(2, + "TEST").build()); TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); mService.getBinderService().registerCallback(callback); - mProvider.notifySupportedDeviceStates( - new DeviceState[]{DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, testDeviceState }); + mProvider.notifySupportedDeviceStates(new DeviceState[]{DEFAULT_DEVICE_STATE, + OTHER_DEVICE_STATE, testDeviceState}); flushHandler(); final IBinder token = new Binder(); @@ -767,10 +763,8 @@ public final class DeviceStateManagerServiceTest { OTHER_DEVICE_STATE.getIdentifier()); assertNotNull(callback.getLastNotifiedInfo()); - assertEquals(callback.getLastNotifiedInfo().baseState, - OTHER_DEVICE_STATE.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - OTHER_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().baseState, OTHER_DEVICE_STATE); + assertEquals(callback.getLastNotifiedInfo().currentState, OTHER_DEVICE_STATE); mProvider.setState(testDeviceState.getIdentifier()); @@ -786,10 +780,9 @@ public final class DeviceStateManagerServiceTest { assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), testDeviceState.getIdentifier()); - waitAndAssert(() -> callback.getLastNotifiedInfo().baseState + waitAndAssert(() -> callback.getLastNotifiedInfo().baseState.getIdentifier() == testDeviceState.getIdentifier()); - assertEquals(callback.getLastNotifiedInfo().currentState, - testDeviceState.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().currentState, testDeviceState); } @Test @@ -811,8 +804,8 @@ public final class DeviceStateManagerServiceTest { assertThrows(IllegalArgumentException.class, () -> { final IBinder token = new Binder(); - mService.getBinderService().requestBaseStateOverride(token, INVALID_DEVICE_STATE, - 0 /* flags */); + mService.getBinderService().requestBaseStateOverride(token, + INVALID_DEVICE_STATE_IDENTIFIER, 0 /* flags */); }); } @@ -826,10 +819,6 @@ public final class DeviceStateManagerServiceTest { }); } - private static void assertArrayEquals(int[] expected, int[] actual) { - Assert.assertTrue(Arrays.equals(expected, actual)); - } - /** * Common code to verify the handling of FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag. * @@ -892,7 +881,8 @@ public final class DeviceStateManagerServiceTest { * @param isOverrideState whether a state override is active. */ private void assertDeviceStateConditions( - DeviceState state, DeviceState baseState, boolean isOverrideState) { + DeviceState state, DeviceState baseState, + boolean isOverrideState) { assertEquals(mService.getCommittedState(), Optional.of(state)); assertEquals(mService.getBaseState(), Optional.of(baseState)); assertEquals(mSysPropSetter.getValue(), @@ -910,7 +900,7 @@ public final class DeviceStateManagerServiceTest { private static final class TestDeviceStatePolicy extends DeviceStatePolicy { private final DeviceStateProvider mProvider; - private int mLastDeviceStateRequestedToConfigure = INVALID_DEVICE_STATE; + private int mLastDeviceStateRequestedToConfigure = INVALID_DEVICE_STATE_IDENTIFIER; private boolean mConfigureBlocked = false; private Runnable mPendingConfigureCompleteRunnable; @@ -970,10 +960,11 @@ public final class DeviceStateManagerServiceTest { } private static final class TestDeviceStateProvider implements DeviceStateProvider { - private DeviceState[] mSupportedDeviceStates = new DeviceState[]{ - DEFAULT_DEVICE_STATE, - OTHER_DEVICE_STATE, - DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP}; + private DeviceState[] mSupportedDeviceStates = + new DeviceState[]{ + DEFAULT_DEVICE_STATE, + OTHER_DEVICE_STATE, + DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP}; @Nullable private final DeviceState mInitialState; private Listener mListener; diff --git a/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java b/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java index cfdb5869e020..637bf03c8bcc 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java @@ -49,10 +49,10 @@ import java.util.Map; @RunWith(AndroidJUnit4.class) public final class OverrideRequestControllerTest { - private static final DeviceState - TEST_DEVICE_STATE_ZERO = new DeviceState(0, "TEST_STATE", 0); - private static final DeviceState - TEST_DEVICE_STATE_ONE = new DeviceState(1, "TEST_STATE", 0); + private static final DeviceState TEST_DEVICE_STATE_ZERO = new DeviceState( + new DeviceState.Configuration.Builder(0, "TEST_STATE").build()); + private static final DeviceState TEST_DEVICE_STATE_ONE = new DeviceState( + new DeviceState.Configuration.Builder(1, "TEST_STATE").build()); private TestStatusChangeListener mStatusListener; private OverrideRequestController mController; diff --git a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java index 16909ab4511e..fad10f7a7553 100644 --- a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java @@ -60,7 +60,10 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * Unit tests for {@link DeviceStateProviderImpl}. @@ -68,10 +71,15 @@ import java.util.List; * Run with <code>atest DeviceStateProviderImplTest</code>. */ public final class DeviceStateProviderImplTest { - private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = ArgumentCaptor.forClass( - DeviceState[].class); + private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = + ArgumentCaptor.forClass(DeviceState[].class); private final ArgumentCaptor<Integer> mIntegerCaptor = ArgumentCaptor.forClass(Integer.class); private static final int MAX_HINGE_ANGLE_EXCLUSIVE = 360; + private static final Set<Integer> EMPTY_PROPERTY_SET = new HashSet<>(); + private static final Set<Integer> THERMAL_TEST_PROPERTY_SET = new HashSet<>( + Arrays.asList(DeviceState.PROPERTY_EMULATED_ONLY, + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)); private Context mContext; private SensorManager mSensorManager; @@ -160,8 +168,8 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", 0 /* flags */), - new DeviceState(2, "", 0 /* flags */) }; + createDeviceState(1, "", EMPTY_PROPERTY_SET), + createDeviceState(2, "", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); verify(listener).onStateChanged(mIntegerCaptor.capture()); @@ -169,13 +177,13 @@ public final class DeviceStateProviderImplTest { } @Test - public void create_stateWithCancelOverrideRequestFlag() { + public void create_stateWithCancelOverrideRequestProperty() { String configString = "<device-state-config>\n" + " <device-state>\n" + " <identifier>1</identifier>\n" - + " <flags>\n" - + " <flag>FLAG_CANCEL_OVERRIDE_REQUESTS</flag>\n" - + " </flags>\n" + + " <properties>\n" + + " <property>PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS</property>\n" + + " </properties>\n" + " <conditions/>\n" + " </device-state>\n" + " <device-state>\n" @@ -192,20 +200,22 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); + final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS), - new DeviceState(2, "", 0 /* flags */) }; + createDeviceState(1, "", new HashSet<>( + List.of(DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS))), + createDeviceState(2, "", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); } @Test - public void create_stateWithInvalidFlag() { + public void create_stateWithInvalidProperty() { String configString = "<device-state-config>\n" + " <device-state>\n" + " <identifier>1</identifier>\n" - + " <flags>\n" - + " <flag>INVALID_FLAG</flag>\n" - + " </flags>\n" + + " <properties>\n" + + " <property>INVALID_PROPERTY</property>\n" + + " </properties>\n" + " <conditions/>\n" + " </device-state>\n" + " <device-state>\n" @@ -223,8 +233,8 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", 0 /* flags */), - new DeviceState(2, "", 0 /* flags */) }; + createDeviceState(1, "", EMPTY_PROPERTY_SET), + createDeviceState(2, "", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); } @@ -259,8 +269,8 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", 0 /* flags */), - new DeviceState(2, "CLOSED", 0 /* flags */) }; + createDeviceState(1, "", EMPTY_PROPERTY_SET), + createDeviceState(2, "CLOSED", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); // onStateChanged() should not be called because the provider has not yet been notified of @@ -327,11 +337,13 @@ public final class DeviceStateProviderImplTest { + " <device-state>\n" + " <identifier>4</identifier>\n" + " <name>THERMAL_TEST</name>\n" - + " <flags>\n" - + " <flag>FLAG_EMULATED_ONLY</flag>\n" - + " <flag>FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL</flag>\n" - + " <flag>FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE</flag>\n" - + " </flags>\n" + + " <properties>\n" + + " <property>PROPERTY_EMULATED_ONLY</property>\n" + + " <property>PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL" + + "</property>\n" + + " <property>PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE" + + "</property>\n" + + " </properties>\n" + " </device-state>\n" + "</device-state-config>\n"; DeviceStateProviderImpl.ReadableConfig config = new TestReadableConfig(configString); @@ -352,13 +364,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); // onStateChanged() should not be called because the provider has not yet been notified of // the initial sensor state. @@ -405,7 +415,7 @@ public final class DeviceStateProviderImplTest { } @Test - public void test_flagDisableWhenThermalStatusCritical() throws Exception { + public void test_propertyDisableWhenThermalStatusCritical() throws Exception { Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE); when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor)); DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor); @@ -418,13 +428,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -439,9 +447,9 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -451,18 +459,16 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_NORMAL)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); } @Test - public void test_flagDisableWhenPowerSaveEnabled() throws Exception { + public void test_propertyDisableWhenPowerSaveEnabled() throws Exception { Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE); when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor)); DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor); @@ -475,13 +481,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -496,9 +500,9 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -508,13 +512,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); } @@ -598,13 +600,22 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */) + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET) }, mDeviceStateArrayCaptor.getValue()); // onStateChanged() should not be called because the provider could not find the sensor. verify(listener, never()).onStateChanged(mIntegerCaptor.capture()); } + private DeviceState createDeviceState(int identifier, @NonNull String name, + @NonNull Set<@DeviceState.DeviceStateProperties Integer> systemProperties) { + DeviceState.Configuration configuration = new DeviceState.Configuration.Builder(identifier, + name) + .setSystemProperties(systemProperties) + .build(); + return new DeviceState(configuration); + } + private static Sensor newSensor(String name, String type) throws Exception { Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor(); constructor.setAccessible(true); 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 03f27493c3c7..26cda65309ad 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -12008,7 +12008,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // style + self managed call - bypasses block when(mTelecomManager.isInSelfManagedCall( - r.getSbn().getPackageName(), true)).thenReturn(true); + r.getSbn().getPackageName(), UserHandle.ALL)).thenReturn(true); assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue(); @@ -12091,7 +12091,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // style + self managed call - bypasses block mService.clearNotifications(); reset(mUsageStats); - when(mTelecomManager.isInSelfManagedCall(r.getSbn().getPackageName(), true)) + when(mTelecomManager.isInSelfManagedCall(r.getSbn().getPackageName(), UserHandle.ALL)) .thenReturn(true); mService.addEnqueuedNotification(r); diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index d6ac517b7a65..8cbcc226ce73 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -2108,9 +2108,6 @@ public class VibratorManagerServiceTest { assertEquals(scale.adaptiveHapticsScale, 1f, 0); - mVibratorControlService.setVibrationParams( - VibrationParamGenerator.generateVibrationParams(vibrationScales), - mFakeVibratorController); externalVibration = new ExternalVibration(UID, PACKAGE_NAME, AUDIO_NOTIFICATION_ATTRS, mock(IExternalVibrationController.class)); @@ -2118,7 +2115,8 @@ public class VibratorManagerServiceTest { mExternalVibratorService.onExternalVibrationStop(externalVibration); assertEquals(scale.adaptiveHapticsScale, 1f, 0); - verify(mVibratorFrameworkStatsLoggerMock).logVibrationAdaptiveHapticScale(UID, 1f); + verify(mVibratorFrameworkStatsLoggerMock, times(2)) + .logVibrationAdaptiveHapticScale(UID, 1f); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 45a2ba4bfcca..daa5a5a4fccc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -3683,7 +3683,9 @@ public class ActivityRecordTests extends WindowTestsBase { assertEquals(WINDOWING_MODE_FULLSCREEN, activity.getWindowingMode()); registerTestTransitionPlayer(); - task.mTransitionController.requestTransitionIfNeeded(TRANSIT_PIP, task); + Transition tr = task.mTransitionController.requestStartTransition( + task.mTransitionController.createTransition(TRANSIT_PIP), task, null, null); + tr.collect(task); task.setWindowingMode(WINDOWING_MODE_PINNED); // Collect activity in the transition if the Task windowing mode is going to change. diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java index 99d354aa0505..b11f9b2306df 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java @@ -70,6 +70,7 @@ public class DisplayContentDeferredUpdateTests extends WindowTestsBase { @Before public void before() { + doReturn(true).when(mDisplayContent).getLastHasContent(); mockTransitionsController(/* enabled= */ true); mockRemoteDisplayChangeController(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index 32b3558ba397..da437c4d1d18 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.wm.ActivityRecord.State.PAUSED; +import static com.android.server.wm.ActivityRecord.State.STOPPING; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -164,13 +165,12 @@ public class RecentsAnimationTest extends WindowTestsBase { ActivityRecord recentsActivity = recentsStack.getTopNonFinishingActivity(); // The activity is started in background so it should be invisible and will be stopped. assertThat(recentsActivity).isNotNull(); - assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity); + assertThat(recentsActivity.getState()).isEqualTo(STOPPING); assertFalse(recentsActivity.isVisibleRequested()); // Assume it is stopped to test next use case. recentsActivity.activityStopped(null /* newIcicle */, null /* newPersistentState */, null /* description */); - mSupervisor.mStoppingActivities.remove(recentsActivity); spyOn(recentsActivity); // Start when the recents activity exists. It should ensure the configuration. @@ -178,7 +178,6 @@ public class RecentsAnimationTest extends WindowTestsBase { null /* recentsAnimationRunner */); verify(recentsActivity).ensureActivityConfiguration(eq(true) /* ignoreVisibility */); - assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index ce890f6d8751..ff7129c50459 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -70,6 +70,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static java.lang.Integer.MAX_VALUE; + import android.app.ActivityManager; import android.content.res.Configuration; import android.graphics.Color; @@ -1120,8 +1122,7 @@ public class TransitionTests extends WindowTestsBase { mDisplayContent.getDisplayRotation().setRotation(mDisplayContent.getRotation() + 1); mDisplayContent.setLastHasContent(); - mDisplayContent.requestChangeTransitionIfNeeded(1 /* any changes */, - null /* displayChange */); + mDisplayContent.requestChangeTransition(1 /* any changes */, null /* displayChange */); assertEquals(WindowContainer.SYNC_STATE_NONE, statusBar.mSyncState); assertEquals(WindowContainer.SYNC_STATE_NONE, navBar.mSyncState); assertEquals(WindowContainer.SYNC_STATE_NONE, screenDecor.mSyncState); @@ -1191,7 +1192,7 @@ public class TransitionTests extends WindowTestsBase { mDisplayContent.getDisplayRotation().setRotation(mDisplayContent.getRotation() + 1); final int anyChanges = 1; mDisplayContent.setLastHasContent(); - mDisplayContent.requestChangeTransitionIfNeeded(anyChanges, null /* displayChange */); + mDisplayContent.collectDisplayChange(transition); transition.setKnownConfigChanges(mDisplayContent, anyChanges); final AsyncRotationController asyncRotationController = mDisplayContent.getAsyncRotationController(); @@ -1254,7 +1255,7 @@ public class TransitionTests extends WindowTestsBase { // so the previous async rotation controller should still exist. mDisplayContent.getDisplayRotation().setRotation(mDisplayContent.getRotation() + 1); mDisplayContent.setLastHasContent(); - mDisplayContent.requestChangeTransitionIfNeeded(1 /* changes */, null /* displayChange */); + mDisplayContent.requestChangeTransition(1 /* changes */, null /* displayChange */); assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp()); assertNotNull(mDisplayContent.getAsyncRotationController()); @@ -1300,7 +1301,7 @@ public class TransitionTests extends WindowTestsBase { mDisplayContent.setFixedRotationLaunchingAppUnchecked(app); registerTestTransitionPlayer(); mDisplayContent.setLastHasContent(); - mDisplayContent.requestChangeTransitionIfNeeded(1 /* changes */, null /* displayChange */); + mDisplayContent.requestChangeTransition(1 /* changes */, null /* displayChange */); assertNotNull(mDisplayContent.getAsyncRotationController()); mDisplayContent.setFixedRotationLaunchingAppUnchecked(null); assertNull("Clear rotation controller if rotation is not changed", @@ -2571,6 +2572,37 @@ public class TransitionTests extends WindowTestsBase { } @Test + public void testConfigAtEndReparent() { + final TransitionController controller = mDisplayContent.mTransitionController; + Transition transit = createTestTransition(TRANSIT_CHANGE, controller); + final TestTransitionPlayer player = registerTestTransitionPlayer(); + + final Task taskOrig = createTask(mDisplayContent); + taskOrig.getConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 200, 300)); + final Task task = createTask(mDisplayContent); + task.getConfiguration().windowConfiguration.setBounds(new Rect(10, 10, 200, 300)); + final ActivityRecord activity = createActivityRecord(taskOrig); + activity.setVisibleRequested(true); + activity.setVisible(true); + + controller.moveToCollecting(transit); + transit.collect(taskOrig); + transit.collect(task); + transit.collect(activity); + transit.setConfigAtEnd(taskOrig); + activity.reparent(task, MAX_VALUE); + task.moveToFront("test"); + + controller.requestStartTransition(transit, task, null, null); + player.start(); + // config-at-end flag must propagate up to task even when reparented (since config-at-end + // only cares about after-end state). + assertTrue(player.mLastReady.getChange( + task.mRemoteToken.toWindowContainerToken()).hasFlags(FLAG_CONFIG_AT_END)); + player.finish(); + } + + @Test public void testReadyTrackerBasics() { final TransitionController controller = new TestTransitionController( mock(ActivityTaskManagerService.class)); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 048b1b290dde..ff4be5586bc1 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -2797,7 +2797,9 @@ public class TelecomManager { /** * Determines whether there are any ongoing {@link PhoneAccount#CAPABILITY_SELF_MANAGED} - * calls for a given {@code packageName} and {@code userHandle}. + * calls for a given {@code packageName} and {@code userHandle}. If UserHandle.ALL or a user + * that isn't the calling user is passed in, the caller will need to have granted the ability + * to interact across users. * * @param packageName the package name of the app to check calls for. * @param userHandle the user handle to check calls for. @@ -2816,41 +2818,7 @@ public class TelecomManager { if (service != null) { try { return service.isInSelfManagedCall(packageName, userHandle, - mContext.getOpPackageName(), false); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException isInSelfManagedCall: " + e); - e.rethrowFromSystemServer(); - return false; - } - } else { - throw new IllegalStateException("Telecom service is not present"); - } - } - - /** - * Determines whether there are any ongoing {@link PhoneAccount#CAPABILITY_SELF_MANAGED} - * calls for a given {@code packageName} amongst all users, given that detectForAllUsers is true - * and the caller has the ability to interact across users. If detectForAllUsers isn't enabled, - * the calls will be checked against the caller. - * - * @param packageName the package name of the app to check calls for. - * @param detectForAllUsers indicates if calls should be detected across all users. - * @return {@code true} if there are ongoing calls, {@code false} otherwise. - * @throws SecurityException if detectForAllUsers is true and the caller does not grant the - * ability to interact across users. - * @hide - */ - @SystemApi - @FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) - @RequiresPermission(allOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, - Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true) - public boolean isInSelfManagedCall(@NonNull String packageName, - boolean detectForAllUsers) { - ITelecomService service = getTelecomService(); - if (service != null) { - try { - return service.isInSelfManagedCall(packageName, null, - mContext.getOpPackageName(), detectForAllUsers); + mContext.getOpPackageName()); } catch (RemoteException e) { Log.e(TAG, "RemoteException isInSelfManagedCall: " + e); e.rethrowFromSystemServer(); diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 302a472b77e4..112471b2af57 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -401,7 +401,7 @@ interface ITelecomService { * @see TelecomServiceImpl#isInSelfManagedCall */ boolean isInSelfManagedCall(String packageName, in UserHandle userHandle, - String callingPackage, boolean detectForAllUsers); + String callingPackage); /** * @see TelecomServiceImpl#addCall diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 2150b5deff52..d3a50bbf1462 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -10258,6 +10258,31 @@ public class CarrierConfigManager { @FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) public static final String KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY = "cellular_service_capabilities_int_array"; + /** + * Transition delay from BT to Cellular on Wear. + * Specifies delay when transitioning away from BT. + * This minimizes the duration of the netTransitionWakelock held by ConnectivityService + * whenever the primary/default network disappears, while still allowing some amount of time + * for BT to reconnect before we enable cell. + * + * If set as -1 then value from resources will be used + * + * @hide + */ + public static final String KEY_WEAR_CONNECTIVITY_BT_TO_CELL_DELAY_MS_INT = + "proxy_connectivity_delay_cell"; + + /** + * Transition delay from BT to Cellular on Wear. + * If wifi connected it extends delay that has been started for BT to Cellular transition + * to avoid Wifi thrashing turning Cell radio and causing higher battery drain. + * + * If set as -1 then value from resources will be used + * + * @hide + */ + public static final String KEY_WEAR_CONNECTIVITY_EXTEND_BT_TO_CELL_DELAY_ON_WIFI_MS_INT = + "wifi_connectivity_extend_cell_delay"; /** The default value for every variable. */ private static final PersistableBundle sDefaults; @@ -11054,6 +11079,8 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_CARRIER_SERVICE_NAME_STRING_ARRAY, new String[0]); sDefaults.putStringArray(KEY_CARRIER_SERVICE_NUMBER_STRING_ARRAY, new String[0]); sDefaults.putIntArray(KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY, new int[]{1, 2, 3}); + sDefaults.putInt(KEY_WEAR_CONNECTIVITY_BT_TO_CELL_DELAY_MS_INT, -1); + sDefaults.putInt(KEY_WEAR_CONNECTIVITY_EXTEND_BT_TO_CELL_DELAY_ON_WIFI_MS_INT, -1); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 88acbabc0e0f..a047b97d8592 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -18852,7 +18852,7 @@ public class TelephonyManager { */ @SystemApi @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) - @RequiresPermission(android.Manifest.permission.DUMP) + @RequiresPermission(android.Manifest.permission.READ_DROPBOX_DATA) public void persistEmergencyCallDiagnosticData(@NonNull String dropboxTag, @NonNull EmergencyCallDiagnosticData data) { try { diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt index 17f91ebad771..060015bcc4b2 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt @@ -40,9 +40,10 @@ abstract class BaseTest constructor( protected val flicker: LegacyFlickerTest, protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), + protected val tapl: LauncherInstrumentation = LauncherInstrumentation() ) { - protected val tapl: LauncherInstrumentation by lazy { - LauncherInstrumentation().also { it.expectedRotationCheckEnabled = true } + init { + tapl.setExpectedRotationCheckEnabled(true) } private val logTag = this::class.java.simpleName |